Chciałbym wybrać węzeł WPF TreeView po kliknięciu prawym przyciskiem myszy, tuż przed wyświetleniem menu ContextMenu.
W przypadku WinForms mógłbym użyć kodu takiego jak ten węzeł Znajdź kliknięty w menu kontekstowym , jakie są alternatywy WPF?
wpf
treeview
contextmenu
alex2k8
źródło
źródło
if (treeViewItem == null) treeView.SelectedIndex = -1
lubtreeView.SelectedItem = null
. Uważam, że jedno i drugie powinno działać.Jeśli potrzebujesz rozwiązania obsługującego tylko XAML, możesz użyć funkcji Blend Interactivity.
Załóżmy, że
TreeView
dane is są powiązane z hierarchiczną kolekcją modeli widoków posiadającychBoolean
właściwośćIsSelected
iString
właściwość,Name
a także kolekcję elementów podrzędnych o nazwieChildren
.Istnieją dwie interesujące części:
TreeViewItem.IsSelected
Nieruchomość jest związana zIsSelected
nieruchomości na widoku model. UstawienieIsSelected
właściwości w modelu widoku na true spowoduje wybranie odpowiedniego węzła w drzewie.Po
PreviewMouseRightButtonDown
uruchomieniu na wizualnej części węzła (w tym przykładzie aTextBlock
)IsSelected
właściwość modelu widoku jest ustawiona na wartość true. Wracając do 1. widać, że odpowiedni węzeł, który został kliknięty w drzewie, staje się węzłem wybranym.Jednym ze sposobów uzyskania interaktywności mieszania w projekcie jest użycie pakietu NuGet Unofficial.Blend.Interactivity .
źródło
i
iei
przestrzeni nazw i w jakich zestawach można je znaleźć. Zakładam:xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
ixmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
, które znajdują się odpowiednio w zestawach System.Windows.Interactivity i Microsoft.Expression.Interactions.ChangePropertyAction
próbuje ustawićIsSelected
właściwość powiązanego obiektu danych, który nie jest częścią interfejsu użytkownika, więc nie maIsSelected
właściwości. czy robię coś źle?IsSelected
właściwość określoną w drugim akapicie mojej odpowiedzi: Załóżmy, żeTreeView
dane są powiązane z hierarchicznym zbiorem modeli widoku posiadających właściwość logicznąIsSelected
... (moje podkreślenie).Korzystanie z "item.Focus ();" wydaje się, że nie działa w 100%, używając "item.IsSelected = true;" robi.
źródło
W języku XAML dodaj program obsługi PreviewMouseRightButtonDown w języku XAML: In XAML, add a PreviewMouseRightButtonDown handler in XAML:
Następnie obsłuż zdarzenie w następujący sposób:
źródło
Korzystając z oryginalnego pomysłu z alex2k8, poprawnie obsługując elementy niewizualne z Wieser Software Ltd, XAML od Stefana, IsSelected z Erlend i mój wkład w stworzenie statycznej metody Generic:
XAML:
Kod C # za:
Edycja: poprzedni kod zawsze działał dobrze w tym scenariuszu, ale w innym scenariuszu VisualTreeHelper.GetParent zwrócił wartość null, gdy LogicalTreeHelper zwrócił wartość, więc naprawiliśmy to.
źródło
Prawie dobrze , ale musisz uważać na elementy niewidoczne w drzewie (jak
Run
na przykład a).źródło
Myślę, że zarejestrowanie programu obsługi klas powinno załatwić sprawę. Po prostu zarejestruj procedurę obsługi zdarzeń kierowanych w obiekcie PreviewMouseRightButtonDownEvent TreeViewItem w pliku kodu app.xaml.cs w następujący sposób:
źródło
Innym sposobem rozwiązania tego problemu za pomocą MVVM jest polecenie wiązania prawym przyciskiem myszy z modelem widoku. Możesz tam również określić inną logikę
source.IsSelected = true
. To używa tylkoxmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
zSystem.Windows.Interactivity
.XAML do wyświetlenia:
Zobacz model:
źródło
Miałem problem z wyborem dzieci za pomocą metody HierarchicalDataTemplate. Gdybym wybrał dziecko węzła, w jakiś sposób wybrałoby głównego rodzica tego dziecka. Dowiedziałem się, że zdarzenie MouseRightButtonDown będzie wywoływane na każdym poziomie, na jakim było dziecko. Na przykład, jeśli masz takie drzewo:
Pozycja 1
- Dziecko 1
- Dziecko 2
- Podelement1
- Podelement2
Gdybym wybrał Subitem2, zdarzenie uruchomiłoby się trzy razy i zostałby wybrany element 1. Rozwiązałem to za pomocą wywołania logicznego i asynchronicznego.
Wydaje się trochę lepki, ale zasadniczo ustawiam wartość logiczną na true przy pierwszym przejściu i resetuję ją w innym wątku w ciągu kilku sekund (w tym przypadku 3). Oznacza to, że następne przejście przez miejsce, w którym spróbuje przejść w górę, zostanie pominięte, pozostawiając wybrany właściwy węzeł. Jak dotąd wydaje się, że działa :-)
źródło
MouseButtonEventArgs.Handled
dotrue
. Ponieważ dziecko jest pierwszym wezwaniem. Ustawienie tej właściwości na true spowoduje wyłączenie innych wywołań do rodzica.Możesz go wybrać za pomocą zdarzenia po naciśnięciu myszy. Spowoduje to wybranie przed uruchomieniem menu kontekstowego.
źródło
Jeśli chcesz pozostać w ramach wzorca MVVM, możesz wykonać następujące czynności:
Widok:
Kod za:
ViewModel:
Teraz możesz albo zareagować na zmianę właściwości ClickedTreeElement, albo możesz użyć polecenia, które wewnętrznie działa z ClickedTreeElement.
Rozszerzony widok:
źródło