【问题标题】:WPF MVVM Update text editor when TreeViewItem selection changes当 TreeViewItem 选择更改时 WPF MVVM 更新文本编辑器
【发布时间】:2017-06-27 13:36:17
【问题描述】:

我有一个这样定义的 DirectoryItems TreeView:

public class DirectoryItem : INotifyPropertyChanged
{
    public String DisplayName { get; set; }
    public String Fullpath { get; set; }
    public ObservableCollection<DirectoryItem> Children { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
}

当用户从树视图中选择一个 DirectoryItem 时,我想从该项目中获取完整路径,从文件中读取所有文本,并将其加载到文本编辑器中。

我的 ViewModel 有一个文本编辑器绑定到的 DisplayText 属性:

internal class MainWindowViewModel : IMainWindowViewModel
{
    private ObservableCollection<DirectoryItem> DirectoryItems { get; set; }

    public string DisplayText { get; set; }
    //this needs to be implemented to take a filepath and read from it
}

我认为应该有一个调用的命令与 TreeViewItem 的 IsSelected 属性相关联,该属性将完整路径传递给 ViewModel,但我无法使代码正常工作。我将如何实现这一点?

这是我无法工作的内容,我收到“属性触发器无法附加到样式类型的元素”错误:

<Style TargetType="{x:Type TreeViewItem}">
    <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectedItemChanged">
                    <i:InvokeCommandAction Command="{Binding DisplayText}" CommandParameter="{Binding ElementName=treeView, Path=SelectedItem}"/>
                </i:EventTrigger>
    </i:Interaction.Triggers>
</Style>

谢谢。

【问题讨论】:

    标签: c# wpf mvvm treeview


    【解决方案1】:

    您不能在 Style 中添加交互触发器。

    您可以做的是将IsSelected 属性添加到您的DirectoryItem 类并将TreeViewItemIsSelected 属性绑定到这个:

    <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="IsSelected" Value="{Binding IsSelected}" />
    </Style>
    

    public class DirectoryItem : INotifyPropertyChanged
    {
        public String DisplayName { get; set; }
        public String Fullpath { get; set; }
        public ObservableCollection<DirectoryItem> Children { get; set; }
    
        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set { _isSelected = value; NotifyPropertyChanged(); }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    确保在 IsSelected 设置为新值时实际提升 PropertyChanged 属性。

    然后,视图模型可以连接到 ObservableCollection&lt;DirectoryItem&gt; 中每个项目的 PropertyChanged 事件,并在选择项目时执行某些操作:

    internal class MainWindowViewModel : IMainWindowViewModel
    {
        public MainWindowViewModel()
        {
            //add the items...
            DirectoryItems.Add(new DirectoryItem() { DisplayName = "test", Children = new ObservableCollection<DirectoryItem>() { new DirectoryItem() { DisplayName = "child" } } });
    
            foreach(var item in DirectoryItems)
            {
                item.PropertyChanged += Item_PropertyChanged;
            }
        }
    
        private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if(e.PropertyName == "IsSelected")
            {
                DirectoryItem selectedItem = sender as DirectoryItem;
                //set the DisplayText property
            }
        }
    
        public ObservableCollection<DirectoryItem> DirectoryItems { get; set; } = new ObservableCollection<DirectoryItem>();
    
        public string DisplayText { get; set; }
    }
    

    如果您要向ObservableCollection&lt;DirectoryItem&gt; 动态添加项目,您可能还希望处理CollectionChanged 事件以将事件处理程序连接到任何新对象:

    private void DirectoryItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (object item in e.NewItems)
            {
                (item as INotifyPropertyChanged).PropertyChanged
                    += new PropertyChangedEventHandler(Item_PropertyChanged);
            }
        }
    
        if (e.OldItems != null)
        {
            foreach (object item in e.OldItems)
            {
                (item as INotifyPropertyChanged).PropertyChanged
                    -= new PropertyChangedEventHandler(Item_PropertyChanged);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-29
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      相关资源
      最近更新 更多