gpt4 book ai didi

c# - TreeView 的 PropertyChanged 始终为 null

转载 作者:太空宇宙 更新时间:2023-11-03 15:39:19 24 4
gpt4 key购买 nike

我在 WPF 项目的 TreeView 中实现搜索功能时遇到问题。

我用了this guide使用 ViewModel 创建 TreeView。我使用了 TextSeachDemo 并以适合我的应用程序的方式编辑了控件。 (添加了正确的类、更多层等)

一切正常,我得到了一个包含正确子项和父项的结构,并且搜索功能也有效,因为它找到了正确的条目。

现在的问题是:当我尝试从代码中设置“IsExpanded”属性时,没有任何反应。调试显示 RaiseProperty Changed 方法中的 PropertyChanged 事件始终为 null。

在 Josh Smith 提供的测试项目中,一切似乎都运行良好。我能看出的唯一显着区别是他在代码中设置了数据上下文,而我在 XAML 中设置了数据上下文:

来自 Josh Smith 的代码:

 public TextSearchDemoControl()
{
InitializeComponent();

// Get raw family tree data from a database.
Person rootPerson = Database.GetFamilyTree();

// Create UI-friendly wrappers around the
// raw data objects (i.e. the view-model).
_familyTree = new FamilyTreeViewModel(rootPerson);

// Let the UI bind to the view-model.
base.DataContext = _familyTree;
}

来自 MainViewModel 的构造函数(处理整个窗口的 ViewModel)

List<FactoryItem> rootItems = _machineService.GetFactoryItems();
FactoryTree = new FactoryTreeViewModel(rootItems);

因为 FactoryTree 是一个公共(public) Observable 属性,我也绑定(bind)了 TreeView 的 DataContext(而不是在上面的代码中):

   <TreeView DataContext="{Binding FactoryTree}" ItemsSource="{Binding FirstGeneration}">

顺便说一句,当我通过 GUI 打开一个项目时,我属性上的断点会触发并引发一个事件。

有什么想法吗?

最佳答案

此解决方案以对 mvvm 更友好的方式解决了该问题。UserControl 包含一个 TreeView。它使用 YourViewModel 类型作为数据上下文。 View 模型包含 YourDomainType 的集合,它本身有一个相同类型的子集合 ChildElements

在 xaml 中,数据绑定(bind)到 View 模型的 ElementInViewModel 集合。此外还有一个 HierarchicalDataTemplate(适用于 TreeView )。

YourDomainType 类型包含属性 IsExpandedIsSelected,它们绑定(bind)到 TreeViewItem 的相应属性样式。如果您在 View 模型中设置这些属性, TreeView 应按预期使用react(选择或展开相应的 TreeViewItem)。

我知道 IsExpandedIsSelected 不属于 DTO 对象。YourDomainType 可能更像是一种用于显示数据的类型,但它也可以包装存储在其中的 DTO 对象。

<UserControl>

<UserControl.DataContext>
<YourViewModel/>
</UserControl.DataContext>

<UserControl.Resources>
<CollectionViewSource Source="{Binding Path=ElementsInViewModel}" x:Key="Cvs">
</CollectionViewSource>

<HierarchicalDataTemplate DataType="{x:Type DomainModel:YourDomainType}"
ItemsSource="{Binding Path=ChildElements}">
<TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>

<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</Setter>
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</Setter>
</Style>

</UserControl.Resources>


<DockPanel>
<TreeView ItemsSource="{Binding Source={StaticResource Cvs}}"/>
</DockPanel>

</UserControl>

public class YourViewModel
{

public ObservableCollection<YourDomainType> ElementsInViewModel
{
get
{
return _elementsInViewModel;
}
set
{
if (_elementsInViewModel != value)
{
_elementsInViewModel = value;
RaisePropertyChanged("ElementsInViewModel");
}
}
}
ObservableCollection<YourDomainType> _elementsInViewModel;


public YourViewModel()
{

}
}

public class YourDomainType
{

public ObservableCollection<YourDomainType> ChildElements
{
get
{
return _childElements;
}
set
{
if (_childElements != value)
{
_childElements = value;
RaisePropertyChanged("ChildElements");
}
}
}
ObservableCollection<YourDomainType> _childElements;


public bool IsExpanded
{
get
{
return _isExpanded;
}
set
{
if (_isExpanded != value)
{
_isExpanded = value;
RaisePropertyChanged("IsExpanded");
}
}
}
bool _isExpanded;


public bool IsSelected
{
get
{
return _isSelected;
}
set
{
if (_isSelected != value)
{
_isSelected = value;
RaisePropertyChanged("IsSelected");
}
}
}
bool _isSelected;


public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged("Name");
}
}
}
string _name;
}

关于c# - TreeView 的 PropertyChanged 始终为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30775858/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com