无法将TreeViewItem的IsSelected属性绑定到ViewModel
本文关键字:属性 绑定 ViewModel IsSelected TreeViewItem | 更新日期: 2023-09-27 17:51:13
在这里找到了很多答案,但没有一个适合我。这是我的XAML
<UserControl x:Class="Helper.View.TreeViewUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:this="clr-namespace:Helper.Model"
xmlns:vm="clr-namespace:Helper.ViewModel"
DataContext="{DynamicResource TreeNodeViewModel}">
<UserControl.Resources>
<vm:TreeNodeViewModel x:Key="TreeNodeViewModel"/>
</UserControl.Resources>
<Grid>
<TreeView ItemsSource="{Binding CodeBookEnties}" >
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding DocSetCollection}" DataType="{x:Type this:CodeBookEntity}">
<Label Content="{Binding CodeBookName}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding FieldCollection}" DataType="{x:Type this:DocumentEntity}">
<Label Content="{Binding DocSetName}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type this:FieldEntity}">
<Label Content="{Binding FieldName}"/>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</UserControl>
我的viewmodel类是这样的
namespace Helper.ViewModel
{
public class TreeNodeViewModel : ViewModelBase
{
private ObservableCollection<DocumentEntity> children;
private CodeBookEntity _codeBookEntity;
private ObservableCollection<CodeBookEntity> codeBookEntities;
//TreeNodeViewModel _parent = null;
bool _isExpanded = false;
bool _isSelected = false;
public TreeNodeViewModel()
{
Mediator.Instance.Register(
//Callback delegate, when message is seen
(Object o) =>
{
ParentNode = (CodeBookEntity)o;
}, ViewModelMessages.CodeBookCreated);
}
public override string ToString() {
return _codeBookEntity.CodeBookName;
}
public ObservableCollection<DocumentEntity> Children
{
get { return CodeBookEnties[0].DocSetCollection; }
set {
CodeBookEnties[0].DocSetCollection = value;
//OnPropertyChanged("CodeBookEnties");
}
}
public CodeBookEntity ParentNode
{
get { return _codeBookEntity; }
set {
_codeBookEntity = value;
if (CodeBookEnties == null)
{
CodeBookEnties = new ObservableCollection<CodeBookEntity>();
}
CodeBookEnties.Add(_codeBookEntity);
OnPropertyChanged("ParentNode");
}
}
public string Name {
get { return _codeBookEntity.CodeBookName; }
}
public string Description
{ get { return _codeBookEntity.CodeBookDescription; } }
#region Presentation Members
#region IsExpanded
/// <summary>
/// Gets/sets whether the TreeViewItem
/// </summary>
public bool IsExpanded
{
get { return _isExpanded; }
set
{
if (value != _isExpanded)
{
_isExpanded = value;
this.OnPropertyChanged("IsExpanded");
}
// Expand all the way up to the root.
//if (_isExpanded && _parent != null)
// _parent.IsExpanded = true;
}
}
#endregion // IsExpanded
#region IsSelected
/// <summary>
/// Gets/sets whether the TreeViewItem
/// associated with this object is selected.
/// </summary>
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value != _isSelected)
{
_isSelected = value;
this.OnPropertyChanged("IsSelected");
}
}
}
#endregion // IsSelected
#region NameContainsText
public bool NameContainsText(string text)
{
if (String.IsNullOrEmpty(text) || String.IsNullOrEmpty(this.Name))
return false;
return this.Name.IndexOf(text, StringComparison.InvariantCultureIgnoreCase) > -1;
}
#endregion // NameContainsText
#endregion // Presentation Members
public bool IsLeaf {
get { return !Children.Any(); }
}
public ObservableCollection<CodeBookEntity> CodeBookEnties
{
get
{
return codeBookEntities;
}
set
{
if (codeBookEntities == null)
{
codeBookEntities = new ObservableCollection<CodeBookEntity>();
}
codeBookEntities = value;
OnPropertyChanged("CodeBookEnties");
}
}
}
}
我在mainwindow
中使用了这个usercontrol
。每当任何代码本添加到那里时,我将通过中介类将该信息发送到此treeviewmodel
。在此基础上,它将更新其数据。能够添加节点多达3个级别没有任何问题。
当我调试时,选择treeview
中的任何项目,treeviewitem
变得粗体,但IsSelected
属性没有被击中。每当我选择一个元素时,我必须根据它的选择获得它的类(CodeBook, Document, Field是这里的类的层次结构),以便我可以稍后处理该元素。
不确定是什么错误。请帮帮我。
谢谢王妃
您的代码有许多问题。使用这样的Binding
将导致错误,因为您正在寻找对象中的IsSelected
属性,该属性被设置为DataContext
,用于TreeViewItem
和而不是视图模型中的:
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
如果你真的想要数据绑定到TreeViewItem.IsSelected
属性到你的视图模型,那么你可以尝试使用RelativeSource Binding
代替:
<Setter Property="IsSelected" Value="{Binding DataContext.IsSelected, RelativeSource={
RelativeSource AncestorType={x:Type YourPrefix:YourView}}, Mode=TwoWay}" />
注意,这将在对象中搜索一个名为IsSelected
的属性,该属性是数据绑定到view/UserControl DataContext
属性的…我假设那是你的视图模型。我不能确认这是否会实际上工作。输入你的下一个问题
TreeViewItem.IsSelected
属性通常是数据绑定到数据对象的属性,该属性是数据绑定到TreeViewItem
的。除了任何其他原因,这样做通常是因为TreeView
可以有许多被选中的TreeViewItem
,并且视图模型中的一个属性不能引用它们。请参阅使用MVVM和WPF MVVM获取选定TreeViewItem的问题,这里的堆栈溢出有关数据绑定的更多信息。