Запуск события TreeView AfterSelect несколько раз

#c# #.net #winforms #treeview

#c# #.net #winforms #просмотр дерева

Вопрос:

У меня есть элемент управления TreeView. Допустим, у меня в нем 5 узлов. При выборе узла я заполняю ListView всеми каталогами под этим SelectedNode. Затем я нажимаю кнопку, которая изменяет элементы ListView.

Итак, когда я снова выбираю узел в TreeView (тот же, который я выбрал ранее), событие AfterSelect не запускается. И из-за этого мой ListView не обновляется.

Есть идеи, ребята / девчонки?

Комментарии:

1. Ожидать, что пользователь обнаружит, что нажатие на узел, который уже выбран, будет иметь эффект, — это принятие желаемого за действительное. Добавьте кнопку обновления и реализуйте нажатие клавиши F5.

Ответ №1:

Обходной путь заключается в переключении выбранного узла…

     treeView.NodeMouseClick  = delegate(object sender, TreeNodeMouseClickEventArgs e) {
        TreeNode selected = e.Node;

        // If node already selected - unselect, then reselect
        if (selected == treeView.SelectedNode) {
            treeView.SelectedNode = null;
            treeView.SelectedNode = selected;
        }
    };
  

Ответ №2:

Это невозможно. AfterSelect Событие не будет вызвано снова, потому что узел, который был выбран, уже выбран. Выбор не меняется, поэтому событие не будет вызвано.

Как указывает Ханс в комментарии к исходному вопросу, весьма вероятно, что плохой дизайн пользовательского интерфейса ожидает, что пользователь поймет, что повторный щелчок по уже выбранному узлу будет иметь какой-то эффект. Лучшим решением является добавление функции «Обновить» в ваше приложение. Обычно это сопоставляется с F5 клавишей и / или сочетанием клавиш Ctrl R.

Если вам абсолютно необходимо запустить какое-либо действие при повторном выборе узла, вам нужно будет обработать его на более низком уровне, чем AfterSelect событие. И это означает, что нужно выяснить, на какой узел пользователь нажал вручную. Для этого обработайте MouseDown событие и используйте HitTest метод для определения узла в том месте, на которое нажал пользователь. Это некрасиво, и я не рекомендую это, но это позволит выполнить работу.

 private void myTreeView_MouseDown(object sender, MouseEventArgs e)
{
    TreeViewHitTestInfo info = myTreeView.HitTest(e.X, e.Y);

    // Ensure that the user actually clicked on a node (there are lots of areas
    // over which they could potentially click that do not contain a node)
    if ((info.Node != null) amp;amp; (info.Node == myTreeView.SelectedNode))
    {
        // The user clicked on the currently-selected node,
        // so refresh the TreeView
        // . . . 
    }
}
  

Комментарии:

1. Спасибо, этот код был полезен для меня. Не могли бы вы предоставить код для той же ситуации, но когда пользователь перемещается по пользовательскому интерфейсу с помощью клавиши TAB?

Ответ №3:

Это не срабатывает, потому что элемент уже выбран. Вместо этого обработайте MouseDown или PreviewMouseDown .

Комментарии:

1. Я знаю. Разве нет другого способа, я мог бы сделать это только в событии AfterSelect?

Ответ №4:

Вы можете использовать событие MouseClick вместо события AfterSelect:

 Sub treeView1_NodeMouseClick(ByVal sender As Object, ByVal e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseClick

    ' textBox1.Text = e.Node.Text
    If Not e.Node.Tag Is Nothing Then
        Dim frm As Form = DirectCast(e.Node.Tag, Form)
        frm.ShowDialog()
        ''frm.Dispose()

    End If

End Sub
  

Ответ №5:

@Cody Gray Даже это очень общий пост, просто нравится публиковать и отвечать. Я думаю, что если вы свернете и развернете treeview одновременно с выбором узла, это сработает. коды, приведенные ниже

 MyTreeview.CollapseAll()
MyTreeview.ExpandAll()
  

Комментарии:

1. Помимо хакерской природы этого подхода, это приводит к ужасному UX на нескольких уровнях. Во-первых, неизбежное мерцание / вспышка при быстром изменении пользовательского интерфейса. Во-вторых, он теряет пользовательское состояние. Как я оставляю TreeView развернутым / свернутым, это мое решение; приложение должно сохранять это, а не бессмысленно выбрасывать.