Frage

Ich möchte ein Drag & Drop, um zu überprüfen Betrieb erlaubt ist. Ein gültiges Element kann aus einem anderen unseren „Kontrollen“, kommt oder intern innerhalb der benutzerdefinierten treeview. Derzeit wird diese habe ich:

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;
}

Ich habe alle Prüfcodes dieser Methode bewegt zu versuchen, die Dinge zu verbessern, aber das ist für mich immer noch schrecklich!

So viel Logik und so viel davon, Dinge zu tun, dass ich das treeview selbst tun würde erwarten würde (zB. „TargetExistsInNode“ überprüft, ob das gezogene Knoten zu einem seiner Kinder gezogen wird).

Was ist der beste Weg, Eingabe in eine Steuerung zu validieren?

War es hilfreich?

Lösung

Ich verwende die TreeNode.Tag Eigenschaft kleine „Controller“ Objekte zu speichern, die die Logik macht. Z.

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;
  }
}

Dann ist mein Candrop wäre so etwas wie:

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;
}

Jetzt für jede Klasse von Objekten, die ich zu dem Baum hinzufügen Ich kann das Verhalten spezialisiert, indem Sie die TreeNodeController im Tag-Objekt zu setzen.

Andere Tipps

Beantwortung nicht streng Ihre Frage, aber ich habe einen Fehler im Code entdeckt. DragDropEffects hat die Flags-Attribut gesetzt, so könnten Sie e.Effect seine eine bitweise Kombination von Kopier- und Bewegung zu bekommen. In diesem Fall würde der Code falsch false zurück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top