2008-09-18 45 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