问题描述
||
所以我在C#Windows窗体应用程序中有一个TreeView。我需要对某些节点进行“锁定”,以便基于参数无法对其进行检查(或取消检查)。
我现在正在做的是这样的:
private void tv_local_BeforeCheck(object sender,TreeViewCancelEventArgs e) {
TNode node = (TNode)e.Node;
//if a part node,cancel the action.
if (node.Type == \"Part\") {
e.Cancel = true;
}
//if a locked node,cancel the action
if (node.Locked == true) {
e.Cancel = true;
}
}
只需单击复选框,该代码就可以很好地工作,但是如果用户双击复选框,它仍然会选中/取消选中。
我曾尝试过使用nodeMouseDoubleClick事件,但这并没有真正的帮助,因为我无法取消该事件...
有什么想法可以取消节点上的双击事件吗?...或其他任何方法?
谢谢
解决方法
我认为这是TreeView中的错误(http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/9d717ce0-ec6b-4758-a357-6bb55591f956/)。您需要对树视图进行子类化并禁用双击消息才能对其进行修复。像这样:
public class NoClickTree : TreeView
{
protected override void WndProc(ref Message m)
{
// Suppress WM_LBUTTONDBLCLK
if (m.Msg == 0x203) { m.Result = IntPtr.Zero; }
else base.WndProc(ref m);
}
};
当然,如果执行此操作,您将无法再在树视图中使用双击隐喻进行其他操作(例如,双击节点以启动属性页等)。
,如果要双击以实际切换复选框,请尝试:
protected override void WndProc(ref Message m)
{
// Filter WM_LBUTTONDBLCLK when we\'re showing check boxes
if (m.Msg == 0x203 && CheckBoxes)
{
// See if we\'re over the checkbox. If so then we\'ll handle the toggling of it ourselves.
int x = m.LParam.ToInt32() & 0xffff;
int y = (m.LParam.ToInt32() >> 16) & 0xffff;
TreeViewHitTestInfo hitTestInfo = HitTest(x,y);
if (hitTestInfo.Node != null && hitTestInfo.Location == TreeViewHitTestLocations.StateImage)
{
OnBeforeCheck(new TreeViewCancelEventArgs(hitTestInfo.Node,false,TreeViewAction.ByMouse));
hitTestInfo.Node.Checked = !hitTestInfo.Node.Checked;
OnAfterCheck(new TreeViewEventArgs(hitTestInfo.Node,TreeViewAction.ByMouse));
m.Result = IntPtr.Zero;
return;
}
}
base.WndProc(ref m);
}
,我使用以下代码对其进行管理,从而防止检查根节点:
private void MyTreeView_MouseUp(object sender,MouseEventArgs e)
{
// HACK: avoid to check root nodes (mr)
var node = ((TreeView)sender).GetNodeAt(new Point(e.X,e.Y));
if (node != null && node.Parent == null)
BeginInvoke(new MouseEventHandler(TreeView_MouseUpAsync),sender,e);
}
private void TreeView_MouseUpAsync(object sender,MouseEventArgs e)
{
if (IsDisposed)
return;
var node = ((TreeView)sender).GetNodeAt(new Point(e.X,e.Y));
node.Checked = false;
}
,尝试扩展TreeNode类,并添加一个布尔属性,该属性维护正确的checkedState。这样,当有人双击某个节点时,可以将节点的选中状态重置回存储在属性中的值。可能会有更优雅的解决方案,但这是我能想到的最好的解决方案。