#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 развернутым / свернутым, это мое решение; приложение должно сохранять это, а не бессмысленно выбрасывать.