无法将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是这里的类的层次结构),以便我可以稍后处理该元素。
不确定是什么错误。请帮帮我。

谢谢王妃

无法将TreeViewItem的IsSelected属性绑定到ViewModel

您的代码有许多问题。使用这样的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的问题,这里的堆栈溢出有关数据绑定的更多信息。