树视图项验证

本文关键字:验证 视图 | 更新日期: 2023-09-27 18:02:49

我试图验证一个树视图内的项目。其主要思想是用户从树中选择一个对象,并加载其可编辑的详细信息。这一切都很好,因为我已经把INotifyPropertyChanged连接起来了,但是……我的模型已经连接了验证逻辑(IDataErrorInfo),我也想在树视图中显示它(突出显示有验证错误的项目)。

我已经尝试了一些东西,但我就是不知道在绑定中放置验证以使其像我希望的那样工作。

My Validation ControlTemplate:

<ControlTemplate x:Key="validationTemplate">
            <StackPanel Orientation="Horizontal">
                <AdornedElementPlaceholder x:Name="MyAdorner" />
                <Image
                                            MaxHeight="{Binding ElementName=MyAdorner, Path=ActualHeight}" 
                                            MaxWidth="20"
                                            Source="{Binding Source={StaticResource ValidationIcon}, Converter={StaticResource UriConverter}}" 
                                            Margin="1" RenderOptions.BitmapScalingMode="HighQuality"
                                            VerticalAlignment="Center" HorizontalAlignment="Center" />
            </StackPanel>
        </ControlTemplate>
treeView

:

<TreeView ItemsSource="{Binding Path=ProductCategories}"
              Name="treeView" SelectedItemChanged="treeView_SelectedItemChanged">           
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate DataType="{x:Type data:ProductCategory}"
                                      ItemsSource="{Binding Path=ProductCategories}">
                        <StackPanel Orientation="Horizontal">
                            <StackPanel.Style>
                                <Style TargetType="StackPanel">
                                    <Style.Triggers>
                                        <Trigger Property="Validation.HasError" Value="True">
                                            <Setter Property="ToolTip"
                                                    Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                                            <Setter Property="Validation.ErrorTemplate"
                                                    Value="{StaticResource validationTemplate}" />
                                        </Trigger>
                                    </Style.Triggers>
                                </Style>
                            </StackPanel.Style>
                            <StackPanel.BindingGroup>
                                <BindingGroup />
                            </StackPanel.BindingGroup>
                            <StackPanel.ToolTip>
                                <TextBlock Margin="2" Text="{Binding Path=Description}" />
                            </StackPanel.ToolTip>
                            <TextBlock Text="{Binding Path=Name}" FontSize="10" FontWeight="Medium" />
                            <TextBlock Text="{Binding Path=ProductCount, StringFormat='   ({0})'}" />
                        </StackPanel>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>

基本上,如果底层模型有验证错误,我试图在树视图中的项目旁边放一个小图标。

我试着玩了一下BindingGroup,但这对我来说是一个新的主题,所以我不确定这是否是要走的路。

任何想法?

树视图项验证

首先,在数据类中需要像下面这样的几个属性:

public ObservableCollection<string> Errors
{
    get
    {
        ObservableCollection<string> errors = new ObservableCollection<string>();
        errors.AddUniqueIfNotEmpty(this["PropertyToValidate1"]);
        errors.AddUniqueIfNotEmpty(this["PropertyToValidate2"]);
        ...
        errors.AddUniqueIfNotEmpty(this["PropertyToValidateN"]);
        return errors;
    }
}

第一个调用为IDataErrorInfo添加的索引器,并将所有验证错误添加到集合中,如果它们还没有在那里。AddUniqueIfNotEmpty方法是一个扩展方法,它"做它在罐头上说的"。我相信你能自己搞定这部分。这个集合的好处是,您可以绑定到它并看到每个验证错误的集合,而不是像简单的IDataErrorInfo实现那样一次只看到一个。

public bool HasError
{
    get { return Errors != null && Errors.Count > 0; }
}

第二个属性只是返回一个bool,表示数据对象中是否存在验证错误。

然后,您可以简单地在TemplateStyle中绑定此属性。下面是一个例子,如果相关的数据对象有任何验证错误,将改变Border的颜色。

<Style x:Key="ValidationBorderStyle" TargetType="{x:Type Border}">
    <Setter Property="Border.BorderBrush" Value="Black" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding HasError, FallbackValue=False}" Value="True">
            <Setter Property="Border.BorderBrush" Value="Red" />
        </DataTrigger>
    </Style.Triggers>
</Style>