C# 获取视图模型内的TreeView SelectedItem
我正在尝试获取ViewModel中选定的TreeView节点 内部XamlC# 获取视图模型内的TreeView SelectedItem,c#,wpf,xaml,mvvm,treeview,C#,Wpf,Xaml,Mvvm,Treeview,我正在尝试获取ViewModel中选定的TreeView节点 内部Xaml <Grid> <TreeView ItemsSource="{Binding TreeViewModel.TreeData}"> <TreeView.Resources> <HierarchicalDataTemplate ItemsSource="{Binding GroupTables}" DataTy
<Grid>
<TreeView ItemsSource="{Binding TreeViewModel.TreeData}">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding GroupTables}" DataType="{x:Type tbl:StaticTablesGroup}">
<Label Content="{Binding Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type tbl:GroupTable}">
<Label Content="{Binding Name}"/>
</DataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</Grid>
内部模型
public class TreeTablesViewModel : ViewModelBase
{
private TablesXML _tables;
public TreeTablesViewModel()
{
_tables = Deserialize.GuymasterXml();
}
public List<StaticTablesGroup> TreeData
{
get
{
return _tables.StaticTablesGroups;
}
set
{
_tables.StaticTablesGroups = value;
OnPropertyChanged("TreeData");
}
}
}
public类TreeTablesViewModel:ViewModelBase
{
私有表xml_表;
公共树etablesviewmodel()
{
_tables=反序列化.GuymasterXml();
}
公共列表树数据
{
得到
{
返回_tables.statictablegroups;
}
设置
{
_tables.statictablegroups=值;
不动产变更(“TreeData”);
}
}
}
最后是数据类
[XmlRoot("Tables")]
public class TablesXML
{
public TablesXML()
{
StaticTablesGroups = new List<StaticTablesGroup>();
}
[XmlArray("StaticGroups")]
[XmlArrayItem("StaticGroup", typeof(StaticTablesGroup))]
public List<StaticTablesGroup> StaticTablesGroups { get; set; }
}
public class StaticTablesGroup
{
public StaticTablesGroup()
{
GroupTables = new List<GroupTable>();
}
[XmlAttribute("Name")]
public string Name { get; set; }
//[XmlArray("StaticGroup")]
[XmlElement("Table", typeof(GroupTable))]
public List<GroupTable> GroupTables { get; set; }
}
public class GroupTable
{
[XmlElement("TableName")]
public string Name { get; set; }
[XmlElement("TableTag")]
public string Tag { get; set; }
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected != value)
{
_isSelected = value;
}
}
}
}
[XmlRoot(“表”)]
公共类表XML
{
公共表XML()
{
StaticTablesGroups=新列表();
}
[XmlArray(“静态组”)]
[XmlArrayItem(“StaticGroup”,typeof(statictablegroup))]
公共列表组{get;set;}
}
公共类组
{
公共表组()
{
GroupTables=新列表();
}
[XmlAttribute(“名称”)]
公共字符串名称{get;set;}
//[XmlArray(“StaticGroup”)]
[XmlElement(“表格”,类型(GroupTable))]
公共列表组表{get;set;}
}
公共类分组表
{
[XmlElement(“表名”)]
公共字符串名称{get;set;}
[XmlElement(“TableTag”)]
公共字符串标记{get;set;}
私立学校当选;
公选学校
{
获取{return}isSelected;}
设置
{
如果(_isSelected!=值)
{
_isSelected=值;
}
}
}
}
选择Treeview节点后,将在GroupTable或StaticTablesGroup中引发IsSelected。
如何在TreeTablesViewModel中获取所选节点
谢谢获取TreeViewItem(我认为这是您的意思)的最简单方法是从树的选择处理程序中的项目容器生成器获取它
private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
TreeView tv = e.Source as TreeView;
TreeViewItem tvi = tv.ItemContainerGenerator.ContainerFromItem(e.NewValue) as TreeViewItem;
}
private void treeView\u SelectedItemChanged(对象发送方,RoutedPropertyChangedEventArgs e)
{
TreeView tv=e.来源为TreeView;
TreeViewItem tvi=tv.ItemContainerGenerator.ContainerFromItem(e.NewValue)作为TreeViewItem;
}
XAML
<TreeView ItemsSource="{Binding TreeViewModel.TreeData}" SelectedItemChanged="treeView_SelectedItemChanged" >
从这里我想您可以进入视图模型。您不应该试图在视图模型内操纵视图对象(TreeView、TreeView、TreeNode等)。视图模型必须仅操作业务/poco对象 如果要检索与所选可视对象(TreeViewItem或node)对应的基础业务对象,可以使用如下行为:
public class TreeviewSelectedItemTracker
{
public static TreeTablesViewModel GetSelectedItemHolder(DependencyObject obj)
{
return (TreeTablesViewModel)obj.GetValue(SelectedItemHolderProperty);
}
public static void SetSelectedItemHolder(DependencyObject obj, TreeTablesViewModel value)
{
obj.SetValue(SelectedItemHolderProperty, value);
}
public static readonly DependencyProperty SelectedItemHolderProperty =
DependencyProperty.RegisterAttached("SelectedItemHolder", typeof(TreeTablesViewModel), typeof(TreeviewSelectedItemTracker), new PropertyMetadata(null, OnSelectedChanged));
private static void OnSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TreeView tv = (TreeView)d;
tv.Loaded += Tv_Loaded;
}
private static void Tv_Loaded(object sender, RoutedEventArgs e)
{
TreeView tv = (TreeView)sender;
tv.Loaded -= Tv_Loaded;
tv.Unloaded += Tv_Unloaded;
tv.SelectedItemChanged += Tv_SelectedItemChanged;
}
private static void Tv_Unloaded(object sender, RoutedEventArgs e)
{
TreeView tv = (TreeView)sender;
tv.Unloaded -= Tv_Unloaded;
tv.SelectedItemChanged -= Tv_SelectedItemChanged;
}
private static void Tv_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
TreeView tv = (TreeView)sender;
var cotr = GetSelectedItemHolder(tv);
cotr.SelectedItem = tv.SelectedItem;
}
}
我尝试不使用MVVM模式来添加代码。谢谢您的回复。我将Selecteditem属性添加到TreeTablesViewModel:private object\u Selecteditem;公共对象SelectedItem{get{return{U SelectedItem;}set{U SelectedItem=value;OnPropertyChanged(“SelectedItem”);}}但是,viewModel中的SelectedItem永远不会执行。我做错了什么。在XAML中:是否尝试在行为中的SelectedItemChanged处理程序中放置断点,以查看事件是否引发?Tv_SelectedItemChanged事件从未引发。这意味着对“SelectedItemHolder”属性的绑定未绑定到正确的对象。绑定不能指向SelectEditeProperty本身,而是指向视图模型:vm:TreeviewSelectedItemTracker.SelectedItemHolder=“{binding TreeViewModel}”
<TreeView ItemsSource="{Binding TreeViewModel.TreeData}" local:TreeviewSelectedItemTracker.SelectedItemHolder="{Binding}"/>