我在WPF项目的TreeView中实现搜索功能时遇到问题。
我使用this guide创建了一个带ViewModels的TreeView。我已经使用了TextSeachDemo并以适合我的应用程序的方式编辑了控件。 (添加了正确的类,更多层等。)
一切正常,我得到一个正确的孩子和父母的结构,搜索功能也可以,因为它找到了正确的条目。
现在的问题是:当我尝试从代码设置“IsExpanded”属性时没有任何反应。 Debubgging向我显示RaiseProperty Changed Method中的PropertyChanged事件始终为null。
在Josh Smith提供的测试项目中,一切似乎都运转正常。 我能解决的唯一显着差异是他在XAML中设置了datacontext代码:
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是一个公共的Observable属性,它也绑定了TreeView的DataContext(而不是上面的代码):
<TreeView DataContext="{Binding FactoryTree}" ItemsSource="{Binding FirstGeneration}">
顺便说一下,当我通过GUI打开一个项目时,我的属性上的断点会触发并引发一个事件。
有什么想法吗?
答案 0 :(得分:0)
此解决方案以更友好的mvvm方式解决问题。
UserControl
包含TreeView
。
它使用类型YourViewModel
作为数据上下文。
视图模型包含YourDomainType
的集合,其本身具有相同类型的子集合ChildElements
。
在xaml中,数据绑定到视图模型的ElementInViewModel
集合。另外还有一个HierarchicalDataTemplate
(适用于树视图)。
类型YourDomainType
包含属性IsExpanded
和IsSelected
,这些属性绑定到TreeViewItem
中Style
的相应属性。
如果在视图模型中设置这些属性,树视图应按预期反应(选择或展开相应的TreeViewItem
)。
我知道IsExpanded
和IsSelected
不属于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;
}