2

Below is a template that works from a binding perspective, but the error template doesn't show, and without an AdornedElementPlaceholder the result looks a bit garish.

My view models implement IDataErrorInfo, and normally I would trigger the error template by having ValidatesOnError=True as part of my binding. This particular view model is display only, so the IDataErrorInfo indexer is never invoked. I do have a number of useful properties related to validation though, including a boolean IsValid property as well as IDataErrorInfo.Error, both of which properly respond to the view model being invalid.

Should I translate the error to a ValidationResult and trigger it that way? Or is there something easier?

Cheers,
Berryl

current template

<!-- FooterViewModel DataTemplate -->
<DataTemplate DataType="{x:Type model:FooterViewModel}">

    <Label x:Name="lblTotalTime"
        Style="{StaticResource FooterStyle}" 
        Content="{Binding TotalTime, Converter={StaticResource TotalAmountConv}}" >
        <Label.ToolTip>
            <TextBlock Text="{Binding FeedbackMessage}" ></TextBlock>
        </Label.ToolTip>
        <Validation.ErrorTemplate>
            <ControlTemplate>
                <DockPanel LastChildFill="True">
                    <TextBlock DockPanel.Dock="Right" Text=" *" 
                               Foreground="Red" 
                               FontWeight="Bold" FontSize="16" 
                               />
                    <Border BorderBrush="Red"  BorderThickness="1">
                        <AdornedElementPlaceholder Name="placeholder"></AdornedElementPlaceholder>
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Validation.ErrorTemplate>
    </Label>

    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsValid}" Value="False">
            <Setter TargetName="lblTotalTime" Property="Control.BorderBrush" Value="Red"/>
            <Setter TargetName="lblTotalTime" Property="Control.BorderThickness" Value="1"/>
            <Setter TargetName="lblTotalTime" Property="Control.Background" Value="LightYellow"/>
        </DataTrigger>
    </DataTemplate.Triggers>

</DataTemplate>

UPDATE

Ok, I am getting IDataErrorInfo to kick in just by changing my binding to include ValidatesOnErrors, BUT the error template still does not show up.

Here is the binding

    <ItemsControl 
        ItemsSource="{Binding Path=FooterViewModels, Mode=OneWay, ValidatesOnDataErrors=True}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
4

1 回答 1

3

默认情况下,验证仅在绑定的源更新时运行。在您的 ItemsControl.ItemsSource 绑定中,Sources 是您的 FooterViewsModels,显然永远不会更新(因为您有 Mode=OneWay)。

您也可以使用DataErrorValidationRule.ValidatesOnTargetUpdated在更新目标时运行验证。该链接给出了一个例子。

请记住,Binding.ValidatesOnDataErrors属性只是将 DataErrorValidationRule 的实例添加到 Binding.ValidationRules 集合的捷径。

最后,定义绑定的控件将具有Validation.Errors。在您的情况下,这是 ItemsControl,而不是其中的项目。因此,我相信您需要将 DataErrorValidationRule 添加到您的 Label.Content 绑定中。或者您需要在 ItemsControl 上定义您的 ErrorTemplate,具体取决于您的目标。

于 2011-03-11T01:11:08.777 回答