• c#:winform从一个toolstriptool上拖动一个图标到一个自定义usercontrol内。


    效果:

    在一个winform工程中,添加一个ToolStrip然后给它添加一个ToolStripButton(tsbStart,它就是红色框圈选的图标)

    this.toolStripTools = new System.Windows.Forms.ToolStrip();
    this.tsbStart = new System.Windows.Forms.ToolStripButton();

    ,当点击tsbStart并拖动到工作区(图中下边空白区,它是一个panel,panel动态添加了一个usercontrol),拖动进入工作区(usercontrol)时触发事件WorkPlace_DragEnter(object sender, DragEventArgs e),把鼠标e.Effect = DragDropEffects.Copy;。结束拖动时,在工作区(usercontroll)范围内监控到WorkPlace_DragDrop(object sender, DragEventArgs e)时,在工作区动态添加一个控件,完成拖动效果。

    实现代码:

    main窗体代码:

         public Main()
            {
                InitializeComponent();
            }
    
            private void Main_Load(object sender, EventArgs e)
            {
                if (this.wpClient != null)
                    wpClient.CloseFlow();
    
                // 重新加载窗体时,清空窗体中的控件。
                this.plClient.Controls.Clear();
    
                wpClient = new WorkPlace("1", UserId, UserName);
                wpClient.WorkFlowCaption = "Hello WorkFlow Designer...";
                wpClient.CanEdit = true;
                wpClient.State = "修改";
    
                // 添加wpClient对象到plClient控件区域内。
                this.plClient.Controls.Add(this.wpClient);
    
                // Main窗體的工具欄圖標生效為可用狀態。
                this.toolStripTools.Enabled = true;
            }
    
            private void tsbStart_MouseDown(object sender, MouseEventArgs e)
            {
                //左键的话,标志位为true(表示拖拽开始)
                if ((e.Button == System.Windows.Forms.MouseButtons.Left))
                {
                    //形成拖拽效果,移动+拷贝的组合效果
                    Button button = new Button();
                    button.SetBounds(0, 0, 100, 20);
                    button.Text = "button ";
                    button.DoDragDrop(button, (DragDropEffects.Copy | DragDropEffects.Move)); //形成拖拽效果,移动+拷贝的组合效果
                }
            }

    workspace自定义控件代码:

            public WorkPlace()
            {
                InitializeComponent();
                // 如果允許結構拖動事件必須設置為true,否則無法結束拖動事件。
                // 自定義控件自身支持接受拖拽来的控件
                this.AllowDrop = true;
                this.DragEnter += new DragEventHandler(WorkPlace_DragEnter);
                this.DragDrop += new DragEventHandler(WorkPlace_DragDrop);
            }
            
            public WorkPlace(string workFlowId, string userId, string userName)
                : this()
            {
                this.WorkFlowId = workFlowId;
                this.UserId = userId;
                this.UserName = userName;
            }
    
            /// <summary>
            /// 關閉窗體,關閉窗體時需要判定是否當前工作內容已經保存,否則提示確認信息。
            /// </summary>
            public void CloseFlow()
            {
    
            }
            
            void WorkPlace_DragEnter(object sender, DragEventArgs e)
            {
                //当Button被拖拽到WinForm上时候,鼠标效果出现
                if ((e.Data.GetDataPresent(typeof(Button))))
                {
                    e.Effect = DragDropEffects.Copy;
                }
            }
    
            int count = 0;
            void WorkPlace_DragDrop(object sender, DragEventArgs e)
            {
                if ((e.Data.GetDataPresent(typeof(Button))))
                {
                    //拖放完毕之后,自动生成新控件
                    Button btn = new Button();
                    btn.SetBounds(e.X, e.Y, 100, 50);
                    btn.Location = this.PointToClient(new Point(e.X, e.Y));
                    //用这个方法计算出客户端容器界面的X,Y坐标。否则直接使用X,Y是屏幕坐标
                    this.Controls.Add(btn);
                    btn.Text = "按钮" + count.ToString();
                    count = count + 1;
                }
            }

    注意事项:

    1)workplace自定义控件内部必须把属性AllowDrop设置true,否则不触发DragDown,DargDrop事件。

        this.AllowDrop = true;

    2)如何在事件中把传递的值给转义出来:如果采用强制转化,发现转化结果为null

           Button bt = (Button)e.Data; // 转化结果为null

    3)正确的转化结果:

            void WorkPlace_DragDrop(object sender, DragEventArgs e)
            {
                if ((e.Data.GetDataPresent(typeof(Button))))
                {
                    FieldInfo info, info2, info3;
                    object obj, obj2, obj3;
                    info = e.Data.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);
                    obj = info.GetValue(e.Data);
    
                    info2 = obj.GetType().GetField("data", BindingFlags.NonPublic | BindingFlags.Instance);
                    obj2 = info2.GetValue(obj);
    
                    System.Collections.Hashtable dataItems = (obj2 as System.Collections.Hashtable);
                    foreach (var dataItem in dataItems)
                    {
                        System.Collections.DictionaryEntry dictEntry = (System.Collections.DictionaryEntry)dataItem;
                        object key = dictEntry.Key;
                        object value = dictEntry.Value;
    
                        info3 = value.GetType().GetField("data", BindingFlags.Public | BindingFlags.Instance);
                        obj3 = info3.GetValue(value);
    
                        Button btnInstance = obj3 as Button; // 此处转化成功,成功获取到传递进来的button实例。
                    }
    
                    // 旧代码。。。。
                }
            }
  • 相关阅读:
    一例智能网卡(mellanox)的网卡故障分析
    jbd2的死锁分析
    一个dcache的性能问题分析
    systemd之导致内核 crash
    开源堡垒机teleport测试
    WSL2添加网络代理,通过宿主机代理出国.
    MongoDB数据库备份操作
    保姆级Mongodb部署教程
    Linux-XZ压缩命令
    eclipse运行Java代码报错:NoClassDefFoundError: javax/xml/bind/*
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/8934242.html
Copyright © 2020-2023  润新知