C #: Как избежать проверки TreeNode на событие двойного щелчка - PullRequest
14 голосов
/ 26 мая 2011

Так что у меня есть TreeView в приложении формы C # windows.Мне нужно, чтобы некоторые узлы были «заблокированы», чтобы их нельзя было проверять (или не проверять) на основе параметра.

Что я сейчас делаю, так это:

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, но это не очень помогает, так как я не могу отменить событие ...

Есть ли какие-нибудь идеи, как отменить событие двойного щелчка наузел? ... или что-нибудь еще?Спасибо

Ответы [ 4 ]

23 голосов
/ 26 мая 2011

Это ошибка в 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);
        }              
    };

Конечно, если вы сделаете это, вы больше не сможете использовать метафору двойного щелчка в древовидном представлении для других целей (например, двойного щелчка на узле для запуска страницы свойств или чего-то подобного).

4 голосов
/ 09 апреля 2013

Если вы хотите, чтобы ваш двойной щелчок фактически переключал флажок, тогда попробуйте:

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);
}
1 голос
/ 28 февраля 2012

Мне удалось это с помощью следующего кода, который предотвращает проверку корневых узлов:

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;
}
0 голосов
/ 26 мая 2011

Попробуйте расширить класс TreeNode и добавьте логическое свойство, которое поддерживает надлежащий selectedState.Таким образом, когда кто-то дважды щелкает узел, вы можете сбросить проверенное состояние узла обратно на значение, сохраненное в свойстве.Возможно, есть более элегантное решение, но это лучшее, что я могу придумать.

...