Я хотел бы выбрать узел WPF TreeView правой кнопкой мыши, прямо перед отображением ContextMenu.
Для WinForms я мог бы использовать такой код, как этот узел поиска, который был нажат в контекстном меню , каковы альтернативы WPF?
wpf
treeview
contextmenu
alex2k8
источник
источник
if (treeViewItem == null) treeView.SelectedIndex = -1
илиtreeView.SelectedItem = null
. Я считаю, что оба варианта должны работать.Если вам нужно решение только на XAML, вы можете использовать Blend Interactivity.
Предположим, что
TreeView
это данные, связанные с иерархической коллекцией моделей представления, имеющейBoolean
свойствоIsSelected
иString
свойство,Name
а также с коллекцией названных дочерних элементовChildren
.Есть две интересные части:
TreeViewItem.IsSelected
Свойство привязан кIsSelected
собственности на вид-модели. Установка дляIsSelected
свойства модели представления значения true выберет соответствующий узел в дереве.Когда
PreviewMouseRightButtonDown
срабатывает визуальная часть узла (в этом примере aTextBlock
),IsSelected
свойство модели представления устанавливается в значение true. Вернувшись к 1., вы увидите, что соответствующий узел, на котором щелкнули в дереве, становится выбранным узлом.Один из способов добиться интерактивности Blend в вашем проекте - использовать пакет NuGet Unofficial.Blend.Interactivity .
источник
i
иei
отображение пространства имен решимости , хотя и какие узлы они могут быть найдены в Я предполагаю , что :.xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Иxmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
, которые находятся в System.Windows.Interactivity и Microsoft.Expression.Interactions узлов соответственно.ChangePropertyAction
он пытается установитьIsSelected
свойство связанного объекта данных, который не является частью пользовательского интерфейса, поэтому у него нетIsSelected
свойства. Я делаю что-то неправильно?IsSelected
свойство, как указано во втором абзаце моего ответа: Предположим, чтоTreeView
это данные привязаны к иерархической коллекции моделей представления, имеющих логическое свойствоIsSelected
... (курсив мой).Использование «item.Focus ();» похоже, не работает на 100%, используя "item.IsSelected = true;" делает.
источник
В XAML добавьте обработчик PreviewMouseRightButtonDown в XAML:
Затем обработайте событие следующим образом:
источник
Используя оригинальную идею от alex2k8, правильно обрабатывая невизуальные элементы от Wieser Software Ltd, XAML от Стефана, IsSelected от Эрленда и мой вклад в создание статического метода Generic:
XAML:
Код C # позади:
Изменить: предыдущий код всегда работал нормально для этого сценария, но в другом сценарии VisualTreeHelper.GetParent возвращал значение null, когда LogicalTreeHelper возвращал значение, поэтому это исправлено.
источник
Почти верно , но вам нужно остерегаться невизуальных элементов в дереве (например, a
Run
).источник
Я думаю, что регистрация обработчика класса должна помочь. Просто зарегистрируйте перенаправленный обработчик событий в PreviewMouseRightButtonDownEvent TreeViewItem в файле кода app.xaml.cs следующим образом:
источник
Другой способ решить эту проблему с помощью MVVM - это привязать команду для щелчка правой кнопкой мыши к вашей модели представления. Там вы можете указать другую логику, а также
source.IsSelected = true
. Используется толькоxmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
изSystem.Windows.Interactivity
.XAML для просмотра:
Посмотреть модель:
источник
У меня возникла проблема с выбором детей с помощью метода HierarchicalDataTemplate. Если бы я выбрал дочерний элемент узла, он каким-то образом выбрал бы корневого родителя этого дочернего элемента. Я обнаружил, что событие MouseRightButtonDown будет вызываться для каждого уровня, на котором находится ребенок. Например, если у вас есть такое дерево:
Элемент 1
- Ребенок 1
- Ребенок 2
- Подпункт1
- Подпункт2
Если бы я выбрал Subitem2, событие сработало бы три раза, и был бы выбран элемент 1. Я решил это с помощью логического и асинхронного вызова.
Это кажется немного громоздким, но в основном я устанавливаю логическое значение true при первом проходе и сбрасываю его в другом потоке через несколько секунд (в данном случае 3). Это означает, что следующие проходы, через которые он попытается продвинуться вверх по дереву, будут пропущены, и вы выберете правильный узел. Вроде пока работает :-)
источник
MouseButtonEventArgs.Handled
кtrue
. Так как ребенок будет вызван первым. Установка для этого свойства значения true отключит другие вызовы родительского объекта.Вы можете выбрать его, нажав кнопку мыши. Это вызовет выбор до того, как появится контекстное меню.
источник
Если вы хотите оставаться в рамках шаблона MVVM, вы можете сделать следующее:
Посмотреть:
Код позади:
ViewModel:
Теперь вы можете либо отреагировать на изменение свойства ClickedTreeElement, либо использовать команду, которая внутренне работает с ClickedTreeElement.
Расширенный вид:
источник