繁体   English   中英

当TreeViewItem选择更改时,WPF MVVM更新文本编辑器

[英]WPF MVVM Update text editor when TreeViewItem selection changes

我有一个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;
}

当用户从treeView中选择DirectoryItem时,我要从该项目中获取Fullpath,从文件中读取所有文本,然后将其加载到文本编辑器中。

我的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属性相关联的命令,该属性将Fullpath传递给ViewModel,但是我无法使代码正常工作。 我将如何实施呢?

这是我无法工作的结果,出现“属性触发器无法附加到Style类型的元素”错误:

<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>

谢谢。

您不能在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<DirectoryItem>中每个项目的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<DirectoryItem> ,则可能还需要处理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);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM