[英]Best way to validate drag/drop operations for a TreeView in C#
我想验证是否允许拖放操作。 有效项可以来自我们的另一个“控件”,也可以来自内部自定义树视图。 目前我有这个:
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”检查被拖动的节点是否被拖动到其子节点之一)。
验证控件输入的最佳方法是什么?
我使用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;
}
现在,对于我添加到树中的每类对象,我可以通过选择要放置在Tag对象中的TreeNodeController来专门化行为。
没有严格回答您的问题,但是我发现您的代码中存在错误。 DragDropEffects
设置了flags属性,因此您可以将e.Effect
作为复制和移动的按位组合。 在这种情况下,您的代码将错误地返回false。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.