[英]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
类,并将TreeViewItem
的IsSelected
属性绑定到此对象:
<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.