Wpf 如何知道使用mvvm单击了哪个treeview项
我有一个WPF MVVM应用程序,它有一个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"
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