2008-09-18 84 views
2

我想验证拖放操作是否允许执行&。有效的项目可以来自我们的另一个“控件”,也可以来自自定义树视图中的内部项目。目前,我有这样的:验证C#中TreeView的拖/放操作的最佳方法

bool CanDrop(DragEventArgs e) 
{ 
    bool allow = false; 
    Point point = tree.PointToClient(new Point(e.X, e.Y)); 
    TreeNode target = tree.GetNodeAt(point); 
    if (target != null) 
    { 
     if (CanWrite(target)) //user permissions 
     { 
      if (e.Data.GetData(typeof(DataInfoObject)) != null) //from internal application 
      { 
       DataInfoObject info = (DataInfoObject)e.Data.GetData(typeof(DataInfoObject)); 
       DragDataCollection data = info.GetData(typeof(DragDataCollection)) as DragDataCollection; 
       if (data != null) 
       { 
        allow = true; 
       } 
      } 
      else if (tree.SelectedNode.Tag.GetType() != typeof(TreeRow)) //node belongs to this & not a root node 
      { 
       if (TargetExistsInNode(tree.SelectedNode, target) == false) 
       { 
        if (e.Effect == DragDropEffects.Copy) 
        { 
         allow = true; 
        } 
        else if (e.Effect == DragDropEffects.Move) 
        { 
         allow = true; 
        } 
       } 
      } 
     } 
    } 
    return allow; 
} 

我已经感动了所有的检查代码,以这种方法来尝试改善的事情,但对我来说这仍然是可怕的!

这么多的逻辑,以及它做的事情,我希望树视图本身会做(例如“TargetExistsInNode”检查拖动节点是否被拖拽到它的一个孩子)。

验证控件输入的最佳方法是什么?

回答

3

我使用TreeNode.Tag属性来存储构成逻辑的小型“控制器”对象。例如:

class TreeNodeController { 
    Entity data; 

    virtual bool IsReadOnly { get; } 
    virtual bool CanDrop(TreeNodeController source, DragDropEffects effect); 
    virtual bool CanDrop(DataInfoObject info, DragDropEffects effect); 
    virtual bool CanRename(); 
} 

class ParentNodeController : TreeNodeController { 
    override bool IsReadOnly { get { return data.IsReadOnly; } } 
    override bool CanDrop(TreeNodeController source, DragDropEffect effect) { 
    return !IsReadOnly && !data.IsChildOf(source.data) && effect == DragDropEffect.Move; 
    } 
    virtual bool CanDrop(DataInfoObject info, DragDropEffects effect) { 
    return info.DragDataCollection != null; 
    } 
    override bool CanRename() { 
    return !data.IsReadOnly && data.HasName; 
    } 
} 

class LeafNodeController : TreeNodeController { 
    override bool CanDrop(TreeNodeController source, DragDropEffect effect) { 
    return false; 
    } 
} 

然后我CanDrop会是这样的:

bool CanDrop(DragDropEventArgs args) { 
    Point point = tree.PointToClient(new Point(e.X, e.Y)); 
    TreeNode target = tree.GetNodeAt(point); 
    TreeNodeController targetController = target.Tag as TreeNodeController; 

    DataInfoObject info = args.GetData(typeof(DataInfoObject)) as DataInfoObject; 
    TreeNodeController sourceController = args.GetData(typeof(TreeNodeController)) as TreeNodeController; 

    if (info != null) return targetController.CanDrop(info, e.Effect); 
    if (sourceController != null) return targetController.CanDrop(sourceController, e.Effect); 
    return false; 
} 

现在,每一个类,我添加到树的对象,我可以通过选择专门的行为放在标签,该标签TreeNodeController目的。

1

不严格回答你的问题,但我发现你的代码中存在一个错误。 DragDropEffects设置了标志属性,因此您可以将e.Effect设置为复制和移动的按位组合。在这种情况下,您的代码将错误地返回false。

+0

你说得对。谢谢! – 2008-09-25 07:44:45