Wpf 如何知道使用mvvm单击了哪个treeview项

Wpf 如何知道使用mvvm单击了哪个treeview项,wpf,mvvm,Wpf,Mvvm,我有一个WPF MVVM应用程序,它有一个TreeView,所有静态项都保存在XAML页面中。如何在视图模型中知道单击了哪个菜单项,以便相应地显示相应的页面 <TreeView Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="MyTreeViewMenu" VerticalAlignment="Stretch" Width="Auto" Opacity="1"

我有一个WPF MVVM应用程序,它有一个
TreeView
,所有静态项都保存在XAML页面中。如何在视图模型中知道单击了哪个菜单项,以便相应地显示相应的页面

    <TreeView Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="MyTreeViewMenu" 
                      VerticalAlignment="Stretch" Width="Auto" Opacity="1" 
                     BorderThickness="1" BorderBrush="Black" Grid.Row="2">

        <TreeViewItem Header="Country" Width="Auto" HorizontalAlignment="Stretch" 
                      ></TreeViewItem>

        <TreeViewItem Header="View Details" Width="Auto" HorizontalAlignment="Stretch" IsEnabled="False">
                <TreeViewItem Header="User" />
                <TreeViewItem Header="Group" />
                <TreeViewItem Header="User Group" />
            </TreeViewItem>
    </TreeView>

我想,在您的情况下,该事件将与
单击具有相同的效果。要确定选择了哪个
treevieItem
,应添加事件
触发器

<TreeView Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="MyTreeViewMenu" 
                      VerticalAlignment="Stretch" Width="Auto" Opacity="1" 
                     BorderThickness="1" BorderBrush="Black" Grid.Row="2">

        <TreeViewItem Header="Country" Width="Auto" HorizontalAlignment="Stretch"></TreeViewItem>    
        <TreeViewItem Header="View Details" Width="Auto" HorizontalAlignment="Stretch" IsEnabled="False">
                <TreeViewItem Header="User" />
                <TreeViewItem Header="Group" />
                <TreeViewItem Header="User Group" />
            </TreeViewItem>
               <i:Interaction.Triggers>
                  <i:EventTrigger EventName="SelectedItemChanged">
                      <i:InvokeCommandAction 
                         Command="{Binding selectItemCommand}"
                         CommandParameter="{Binding SelectedItem, ElementName=MyTreeViewMenu}"/>
                  </i:EventTrigger>
              </i:Interaction.Triggers>
</TreeView>
我想,在您的情况下,该事件将与单击
具有相同的效果。要确定选择了哪个
treevieItem
,应添加事件
触发器

<TreeView Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="MyTreeViewMenu" 
                      VerticalAlignment="Stretch" Width="Auto" Opacity="1" 
                     BorderThickness="1" BorderBrush="Black" Grid.Row="2">

        <TreeViewItem Header="Country" Width="Auto" HorizontalAlignment="Stretch"></TreeViewItem>    
        <TreeViewItem Header="View Details" Width="Auto" HorizontalAlignment="Stretch" IsEnabled="False">
                <TreeViewItem Header="User" />
                <TreeViewItem Header="Group" />
                <TreeViewItem Header="User Group" />
            </TreeViewItem>
               <i:Interaction.Triggers>
                  <i:EventTrigger EventName="SelectedItemChanged">
                      <i:InvokeCommandAction 
                         Command="{Binding selectItemCommand}"
                         CommandParameter="{Binding SelectedItem, ElementName=MyTreeViewMenu}"/>
                  </i:EventTrigger>
              </i:Interaction.Triggers>
</TreeView>
看看MSDN上的页面

您可以直接绑定到
TreeView。选择editem
属性:

<TreeView ItemsSource="{Binding Items}" SelectedItem="{Binding Item, Mode=OneWay}" />
<TreeView ItemsSource="Items" HorizontalAlignment="Stretch" ... Name="MyTreeViewMenu">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>
我刚刚在StackOverflow上的帖子中找到了一个更完整的答案

或者,还有另一种方法。。。您还可以使用
TreeView.SelectedValue
TreeView.SelectedValuePath
属性。基本思想是将
TreeView.SelectedValuePath
属性设置为数据对象上的属性名称。当选择一个项目时,
TreeView.SelectedValue
属性将被设置为所选数据项目的该属性的值。有关此方法的更多信息,请访问MSDN页面。如果您有一个唯一可识别的属性,比如某种标识符,那么这种方法通常效果最好。此代码示例来自MSDN:

<TreeView ItemsSource="{Binding Source={StaticResource myEmployeeData}, 
XPath=EmployeeInfo}" Name="myTreeView" SelectedValuePath="EmployeeNumber" />

<TextBlock Margin="10">SelectedValuePath: </TextBlock>
<TextBlock Margin="10,0,0,0" Text="{Binding ElementName=myTreeView, 
Path=SelectedValuePath}" Foreground="Blue"/>

<TextBlock Margin="10">SelectedValue: </TextBlock>
<TextBlock Margin="10,0,0,0" Text="{Binding ElementName=myTreeView, 
Path=SelectedValue}" Foreground="Blue"/>

SelectedValuePath:
SelectedValue:
查看MSDN上的页面

您可以直接绑定到
TreeView。选择editem
属性:

<TreeView ItemsSource="{Binding Items}" SelectedItem="{Binding Item, Mode=OneWay}" />
<TreeView ItemsSource="Items" HorizontalAlignment="Stretch" ... Name="MyTreeViewMenu">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>
我刚刚在StackOverflow上的帖子中找到了一个更完整的答案

或者,还有另一种方法。。。您还可以使用
TreeView.SelectedValue
TreeView.SelectedValuePath
属性。基本思想是将
TreeView.SelectedValuePath
属性设置为数据对象上的属性名称。当选择一个项目时,
TreeView.SelectedValue
属性将被设置为所选数据项目的该属性的值。有关此方法的更多信息,请访问MSDN页面。如果您有一个唯一可识别的属性,比如某种标识符,那么这种方法通常效果最好。此代码示例来自MSDN:

<TreeView ItemsSource="{Binding Source={StaticResource myEmployeeData}, 
XPath=EmployeeInfo}" Name="myTreeView" SelectedValuePath="EmployeeNumber" />

<TextBlock Margin="10">SelectedValuePath: </TextBlock>
<TextBlock Margin="10,0,0,0" Text="{Binding ElementName=myTreeView, 
Path=SelectedValuePath}" Foreground="Blue"/>

<TextBlock Margin="10">SelectedValue: </TextBlock>
<TextBlock Margin="10,0,0,0" Text="{Binding ElementName=myTreeView, 
Path=SelectedValue}" Foreground="Blue"/>

SelectedValuePath:
SelectedValue:

除了绑定到TreeView.SelectedItem属性外:

<TreeView ItemsSource="{Binding Items}" SelectedItem="{Binding Item, Mode=OneWay}" />
<TreeView ItemsSource="Items" HorizontalAlignment="Stretch" ... Name="MyTreeViewMenu">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>
当使用MVVM时,它帮助我不再考虑UI中的事件,而是开始考虑UI中的状态

可以将ViewModel绑定到视图的属性。因此,通常我会尝试将SelectedItem绑定到ViewModel上的属性,以便ViewModel知道选择了什么


以同样的方式,您可以向显示的ViewModel项目添加一个名为Selected的属性,并将该属性绑定到视图中的复选框。通过这种方式,您可以在ViewModel中启用多项选择并轻松访问所选项目。

除了绑定到TreeView.SelectedItem属性外:

<TreeView ItemsSource="{Binding Items}" SelectedItem="{Binding Item, Mode=OneWay}" />
<TreeView ItemsSource="Items" HorizontalAlignment="Stretch" ... Name="MyTreeViewMenu">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>
当使用MVVM时,它帮助我不再考虑UI中的事件,而是开始考虑UI中的状态

可以将ViewModel绑定到视图的属性。因此,通常我会尝试将SelectedItem绑定到ViewModel上的属性,以便ViewModel知道选择了什么


以同样的方式,您可以向显示的ViewModel项目添加一个名为Selected的属性,并将该属性绑定到视图中的复选框。这样,您可以在ViewModel中启用多个选择并轻松访问所选项目。

为完整起见,以下是附加的属性和TreeView子类选项:

附加属性选项

public静态类TreeViewSelectedItemHelper
{
公共静态只读从属属性BindableSelectedProperty
=DependencyProperty.RegisterAttached(
“BindableSelectedItem”,
类型(对象),
类型(TreeViewSelectedItemHelper),
新的FrameworkPropertyMetadata(错误,
OnSelectedItemProperty(已更改)
{
BindsTwoWayByDefault=true
});
公共静态对象GetBindableSelectedItem(TreeView TreeView)
{
返回treeView.GetValue(BindableSelectedItemProperty);
}
公共静态无效SetBinTableSelectedItem(
树视图树视图,
对象selectedItem)
{
设置值(BindableSelectEditeProperty,selectedItem);
}
SelectedItemProperty上的私有静态无效已更改(
DependencyObject发送方,
DependencyPropertyChangedEventArgs(参数)
{
var treeView=发送方作为treeView;
if(treeView==null)返回;
SetBindableSelectedItem(树视图,参数NewValue);
treeView.SelectedItemChanged-=HandleSelectedItemChanged;
treeView.SelectedItemChanged+=HandleSelectedItemChanged;
if(args.OldValue!=args.NewValue)
SetSelected(树视图,参数NewValue);
}
选择的专用静态无效设置(ItemsControl TreeItem,
对象项(待选择)
{
foreach(TreeViewItems.Items中的变量项)
{
var生成器=treeViewItem.ItemContainerGenerator;
var child=(TreeViewItem)generator.ContainerFromItem(item);
如果(child==null)继续;
child.IsSelected=(item==itemToSelect);
如果(child.HasItems)已选择(child,itemToSelect);
}
}
私有静态无效HandleSelectedItemChanged(
对象发送器,
RoutedPropertyChangedEventArgs(参数)
{
如果(args.NewValue为TreeViewItem)返回;
var treeView=se