我有一个如下所示的树视图。
说我想显示错误信息 a)树节点或 b)其容器
基于我的验证规则的值。
例如,如果我应用此树的验证逻辑,
验证规则>>>所有以“p”开头的父母都有效
结果,我的“xx”节点有效。我需要突出显示该元素并通知用户。
我在WPF中使用MVVM。我该怎么做。请帮帮我。
答案 0 :(得分:2)
我过去做过类似的事情,你可以做的就是:
bool IsValid {get;set;}
属性。 (确保在ViewModel属性中实现INotifyPropertyChanged
)为您在节点的View(例如Button)中使用的控件类型创建样式,并创建样式触发器(在线大量示例),当IsValid为false时,将节点背景设置为红色将它应用于您的控制:
<HierarchicalDataTemplate DataType="{x:Type ViewModel:NodeViewModel}" ItemsSource="{Binding Children}">
<Button Style="{StaticResource MyNodeStyle}"
Content="{Binding Path=.}"
</HierarchicalDataTemplate>
在您的业务逻辑层或容器ViewModel中创建一个方法,以递归方式验证树中的所有节点,并将IsValid属性设置为所有节点,或者在IsValid Get中定义业务规则(使其读取 - 只要)。当验证发生时,如果节点根据您的规则无效,则会自动变为红色。
希望这有帮助,如果您有疑问,请与我联系。
编辑:添加了一些示例类来说明解决方案。我的业务规则是任何以'p'开头的节点都是有效的(绿色),无论它是否是父节点,但你明白了......
public class TreeNodeViewModel : ViewModelBase<TreeNodeViewModel>
{
private string _NodeText;
private ObservableCollection<TreeNodeViewModel> _Children;
public TreeNodeViewModel()
{
Children = new ObservableCollection<TreeNodeViewModel>();
}
public string NodeText
{
get { return _NodeText; }
set
{
_NodeText = value;
NotifyPropertyChanged(m => m.NodeText);
NotifyPropertyChanged(m => m.IsValid);
}
}
public bool IsValid
{
get { return !string.IsNullOrEmpty(NodeText) && NodeText.ToLower().StartsWith("p"); }
}
public ObservableCollection<TreeNodeViewModel> Children
{
get { return _Children; }
set
{
_Children = value;
NotifyPropertyChanged(m => m.Children);
}
}
}
public class TreeViewModel : ViewModelBase<TreeViewModel>
{
private ObservableCollection<TreeNodeViewModel> _RootNodeContainer;
private TreeNodeViewModel _RootNode;
public TreeViewModel()
{
InitializeTree();
}
private void InitializeTree()
{
RootNodeContainer = new ObservableCollection<TreeNodeViewModel>();
RootNode = new TreeNodeViewModel() { NodeText = "R1" };
RootNodeContainer.Add(RootNode);
TreeNodeViewModel p1 = new TreeNodeViewModel() {NodeText = "P1"};
p1.Children.Add(new TreeNodeViewModel(){NodeText = "Child1"});
RootNode.Children.Add(p1);
TreeNodeViewModel p2 = new TreeNodeViewModel() {NodeText = "P2"};
p2.Children.Add(new TreeNodeViewModel() { NodeText = "Child1" });
RootNode.Children.Add(p2);
TreeNodeViewModel xx = new TreeNodeViewModel() {NodeText = "XX"};
xx.Children.Add(new TreeNodeViewModel() { NodeText = "Child3" });
RootNode.Children.Add(xx);
}
public TreeNodeViewModel RootNode
{
get { return _RootNode; }
set
{
_RootNode = value;
NotifyPropertyChanged(m => RootNode);
}
}
public ObservableCollection<TreeNodeViewModel> RootNodeContainer
{
get { return _RootNodeContainer; }
set
{
_RootNodeContainer = value;
NotifyPropertyChanged(m => RootNodeContainer);
}
}
}
<TreeView Name="GoldTree" ItemsSource="{Binding RootNodeContainer}"
Background="#FFF0EDD1">
<TreeView.Resources>
<ResourceDictionary>
<Style TargetType="Button" x:Key="MyNodeStyle">
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=IsValid,UpdateSourceTrigger=PropertyChanged}"
Value="False">
<Setter Property="Border.Background" Value="Red" />
</DataTrigger>
<DataTrigger
Binding="{Binding Path=IsValid,UpdateSourceTrigger=PropertyChanged}"
Value="True">
<Setter Property="Border.Background" Value="GreenYellow" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="TreeViewItem">
<Setter Property="Margin" Value="0,0,0,0" />
<!-- Disable blue highlighting on selection-->
<Setter Property="Focusable" Value="false" />
</Style>
<HierarchicalDataTemplate DataType="{x:Type ViewModel:TreeNodeViewModel}"
ItemsSource="{Binding Children}">
<Button Style="{StaticResource MyNodeStyle}" Content="{Binding Path=NodeText}" />
</HierarchicalDataTemplate>
</ResourceDictionary>
</TreeView.Resources>
</TreeView>
这是你得到的:
此解决方案的限制是在为每个节点设置NodeText属性时进行验证,因此您可能不知道该节点是否有子节点,因此我宁愿在TreeViewModel中创建一个方法来设置{ {1}}某个点上所有节点的标志。