Laden...

SelectedItem bei TreeView mithilfe von Bindings auslesen

Erstellt von adm1n vor 9 Jahren Letzter Beitrag vor 9 Jahren 4.658 Views
A
adm1n Themenstarter:in
51 Beiträge seit 2014
vor 9 Jahren
SelectedItem bei TreeView mithilfe von Bindings auslesen

Hallo Forum,

ich lese und lese (Gewusst-wie-Themen zur Datenbindung und Übersicht über Datenbindung) nun schon seit Stunden und komme zu keiner Lösung. Ich hoffe ihr könnt mir helfen.

Folgendes Problem:

Ich habe einen TreeView, der in meiner GUI als Navigation dient:

            <TreeView x:Name="TreeViewNavigation" Grid.Column="0" Grid.Row="2" Grid.RowSpan="2" SelectedItemChanged="TreeViewNavigation_SelectedItemChanged">
                <TreeViewItem>
                    <TreeViewItem.Header>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="Resources/Bild1.png"></Image>
                            <Label Content="Label1"></Label>
                        </StackPanel>
                    </TreeViewItem.Header>
                </TreeViewItem>
                <TreeViewItem>
                    <TreeViewItem.Header>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="Resources/Bild2.png"></Image>
                            <Label Content="Label2"></Label>
                        </StackPanel>
                    </TreeViewItem.Header>
                </TreeViewItem>
            </TreeView>

Nun möchte ich auslesen, welches Item vom Benutzer ausgewählt wurde. Also immer das, was im Label bei Content steht (hier z.B. Label1 oder Label2). Über die in den MSDN-Arikel beschriebene Bindings habe ich das bisher nicht hinbekommen. Mithilfe von XPath bin ich auch zu keiner Lösung gekommen.

Würde mich über eure Hilfe freuen. Danke im Voraus!

Die Grenzen meiner Sprache bedeuten die Grenzen meiner Welt - Tractatus 5.6, Ludwig Wittgenstein

692 Beiträge seit 2008
vor 9 Jahren

Hallo adm1n,

leider geht das nicht ganz so einfach wie in Forms. Jedes TreeViewItem hat ein Property IsSelected und über dies kannst Du raus finden welches bzw. welche Items selektiert sind. Beim DataGrid muss man es z.B. genau so machen.


<TreeView ItemsSource="{Binding Nodes}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

Hier ist z.B. ein Artikel: wpf-mvvm-treeview-selecteditem

Schöne Grüße
Quaneu

A
adm1n Themenstarter:in
51 Beiträge seit 2014
vor 9 Jahren

Perfekt! Vielen Dank für deine Antwort!

Noch eine weitere Frage:
Welche Möglichkeit wählt man, wenn man den TreeView als Navigation will und je nach selektiertem Item den Inhalt in der Oberfläche ändern will?

Habe das nun vorerst so gelöst:
Wird ein Event (SelectedItemChanged) im TreeView ausgelöst, prüfe ich, welches TreeViewItem selektiert ist. Anschließend binde ich dann je nach Auswahl in einem Frame die jeweilige Page ein.

Also vom Prinzip:


         private void TreeViewNav_SelItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
             Frame frame = new Frame();

             // via .IsSelected das angewählte TreeViewItem ermitteln 
             selectedTreeViewItem = ....

             switch (selectedTreeViewItem ) 
            {
                case "page1":
                    Page1 p = new Page1();
                    frame.Content = p;
                    break;        
                case "page2":
                    Page2 p = new Page2();
                    frame.Content = p;
                    break;   
                default:
                    break;
            }

            // den Frame in den TabControl laden
            TabControlTab.Content = frame;

        }

Da gibt's doch bestimmt elegantere/bessere Lösungen, oder?

Die Grenzen meiner Sprache bedeuten die Grenzen meiner Welt - Tractatus 5.6, Ludwig Wittgenstein

692 Beiträge seit 2008
vor 9 Jahren

Also mir Fallen auf die schnelle zwei Möglichkeiten ein:1. Du löst es über IsSelected und dein Model reagiert drauf und setzt dementsprechend ein Property auf das die GUI "schaut" und reagiert dementsprechend.
2. Du benutzt ein ContentPresenter und bindest Dich an den TreeView (SelectedItem hier geht es 😃). Hier kannst Du dann über DataTemplates oder über ein Converter die Daten in der gewünschten Form anzeigen

16.832 Beiträge seit 2008
vor 9 Jahren

Da wir uns ja im WPF Umfeld befinden, sollten wir auch Dinge wie MVVM in Betracht ziehen.
Da spielen auch Routes und Commands eine Rolle, mit der man "normalerweise" solch in Menü in WPF umsetzt.

692 Beiträge seit 2008
vor 9 Jahren

@Abt:
Beide Wege benutzten Bindings und sind doch daher bestens geeignet für MVVM. Oder?

16.832 Beiträge seit 2008
vor 9 Jahren

Trotzdem verwendet man _eigentlich _ Commands, zB RelayCommands in WPF um einen Workflow abzubilden; keine Bindings.

P
660 Beiträge seit 2008
vor 9 Jahren

hallo,

wenn du wissen möchtest welches TreeViewItem selektiert ist, dann kannst du auch von der TreeView
ableiten und eine DependencyProperty bereitstellen, die das Binding ermöglicht. Der Mode des
Bindings sollte dann auf OneWayToSource eingestellt sein.


	public class TreeViewExtended : TreeView
	{
		public new static readonly DependencyProperty SelectedItemProperty =
			DependencyProperty.Register("SelectedItem", typeof(object), typeof(TreeViewExtended), new PropertyMetadata(default(TreeViewItem)));

		public new object SelectedItem
		{
			get { return GetValue(SelectedItemProperty); }
			set { SetValue( SelectedItemProperty, value ); }
		}
		
		protected override void OnSelectedItemChanged( RoutedPropertyChangedEventArgs<object> e )
		{
			this.SelectedItem = e.NewValue;
		}
	}

MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden! *"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht." *"Ignorance simplifies ANY problem." *"Stoppt die Piraterie der Musikindustrie"