【问题标题】:TreeView fires DragEnter, DragOver and DragLeave events, but won't fire DragDropTreeView 触发 DragEnter、DragOver 和 DragLeave 事件,但不会触发 DragDrop
【发布时间】:2011-02-22 14:09:06
【问题描述】:

万岁!

我很难弄清楚为什么我的树视图(或任何其他组件,甚至是表单本身)不会触发 DragDrop 事件。

我的表格是这样设置的:
一个Form,里面有一个Panel
Panel有一个TreeView,而这个TreeView(MyTree)有如下代码:

MyTree.AllowDrop = true;
MyTree.DragDrop += new System.Windows.Forms.DragEventHandler(onDragDrop);
MyTree.DragEnter += new System.Windows.Forms.DragEventHandler(onDragEnter);
MyTree.DragLeave += new System.EventHandler(onDragLeave);
MyTree.DragOver += new System.Windows.Forms.DragEventHandler(onDragOver);

处理程序如下所示:

private void onDragEnter(object sender, DragEventArgs e)
{
    Console.WriteLine(" === DragEnter === ");
}

private void onDragLeave(object sender, EventArgs e)
{
    Console.WriteLine(" === DragLeave === ");
}

private void onDragOver(object sender, DragEventArgs e)
{
    Console.WriteLine(" === DragOver === ");
}

private void onDragDrop(object sender, DragEventArgs e)
{
    Console.WriteLine(" === DragDrop === ");
}

当我测试我的应用程序时,拖动 *.txt 文件(或任何东西)输出类似于:

=== DragEnter ===
=== DragOver ===
=== DragOver ===
...
=== DragOver ===
=== DragLeave ===

最后一行 ( === DragLeave === ) 并不意味着是一个离开事件。
事实上,当我在 TreeView 上释放鼠标按钮时,就会打印出这一行。

我做错了什么?

【问题讨论】:

    标签: c# .net drag-and-drop


    【解决方案1】:

    这是我用于将文件拖放到树视图的方法:

    public class DragDropManager
    {
        private UserControl _parent;
    
        private AddFilesEventHandler OnAddFiles;   
    
        public DragDropManager()
        {
        }
    
        public UserControl Parent
        {
            set
            {
                _parent = value;    
    
                if ( ! ( _parent is IDropFileTarget ) )
                {
                    throw new Exception("DragDropManager: Parent usercontrol does not implement IDropFileTarget interface");
                }
    
                OnAddFiles = new AddFilesEventHandler(((IDropFileTarget)_parent).AddFiles);
                _parent.AllowDrop = true;
                _parent.DragEnter += new System.Windows.Forms.DragEventHandler(this.OnDragEnter);
                _parent.DragDrop += new System.Windows.Forms.DragEventHandler(this.OnDragDrop);
            }
        }
    
        /// <summary>
        /// Handle parent form DragEnter event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDragEnter(object sender, System.Windows.Forms.DragEventArgs e)
        {
            string[] formats = e.Data.GetFormats(true);
    
            //e.Effect = DragDropEffects.All;
    
            for (int formatIndex = 0; formatIndex < formats.Length; formatIndex++)
            {
                switch (formats[formatIndex])
                {
                    case Consts.DragDropFormats.FileDrop:
                        e.Effect = DragDropEffects.Copy;
                        break;
                    case Consts.DragDropFormats.Text:
                        e.Effect = DragDropEffects.Move;
                        break;
                    case Consts.DragDropFormats.UniformResourceLocator:
                        e.Effect = DragDropEffects.Link;
                        break;
                }
            }
        }
    
        /// <summary>
        /// Handle parent form DragDrop event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDragDrop(object sender, System.Windows.Forms.DragEventArgs e)
        {
            try
            {
                string[] formats = e.Data.GetFormats(true);
                string[] values = new string[1];
                string url = string.Empty;
    
                for (int formatIndex = 0; formatIndex < formats.Length; formatIndex++)
                {
                    switch (formats[formatIndex])
                    {
                        case Consts.DragDropFormats.FileDrop:
                            Array itemList = (Array)e.Data.GetData(Consts.DragDropFormats.FileDrop);
    
                            if (itemList != null)
                            {
                                _parent.BeginInvoke(OnAddFiles, new Object[] { itemList });
                                _parent.Focus();
                            }
                            break;
                        case Consts.DragDropFormats.Text:
                        case Consts.DragDropFormats.UniformResourceLocator:
                            values[0] = e.Data.GetData(Consts.DragDropFormats.Text).ToString();
                            _parent.BeginInvoke(OnAddFiles, new Object[] { values });
                            _parent.Focus();
                            break;
                        default:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Error in DragDropManager.OnDragDrop function: " + ex.Message);
            }
        }
    
    }
    

    你可以按如下方式使用它:

    DragDropManager dragDropManager = new DragDropManager();
    dragDropManager.Parent = this;
    

    并且需要在 UserControl 上实现这个

    public interface IDropFileTarget
    {
        void AddFiles(Array Files);
    }
    

    【讨论】:

      【解决方案2】:

      您需要将DragOver 中的e.Effect 设置为None 以外的其他值,以告诉系统您愿意被丢弃。

      【讨论】:

      • 谢谢你,@SLaks。在 DragEnter 或 DragOver 上更改 e.Effect 就像一个魅力。
      【解决方案3】:

      您需要确保拖动的项目中确实有一些数据。获取当前使用的字符串数组

      e.Data.GetFormats()
      

      使用字符串数组 'fmt' 的每个元素作为 GetData 的参数

      e.Data.GetData(fmt)
      

      如果它们都为空,它不会触发 DragDrop 事件,并且任何设置 e.Effect 都不会改变它。如果您确定这是原因,您可以更具体地搜索根本原因。 (在我的例子中是 Internet Explorer)

      【讨论】:

        猜你喜欢
        • 2011-02-07
        • 2023-03-16
        • 1970-01-01
        • 2020-06-19
        • 2010-10-08
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多