首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Validation.ErrorTemplate未显示

Validation.ErrorTemplate未显示
EN

Stack Overflow用户
提问于 2014-07-30 13:24:11
回答 3查看 2.9K关注 0票数 0

我有一个MainWindow和一个UserControl。MainWindow显示UserControl。UserControl本身遵循MVVM模式,并在ViewModel中实现IDataErrorInfo接口。这很好,但是Validation.ErrorTemplate没有显示。

我的UserControl.xaml

代码语言:javascript
复制
 <TextBox x:Name="txtName" 
          Text="{Binding Path=Name, Mode=TwoWay, 
                 UpdateSourceTrigger=PropertyChanged, 
                 ValidatesOnDataErrors=True}" 
          Grid.Row="0" Grid.Column="2"
          VerticalAlignment="Bottom" MinWidth="100" FontSize="12">
       <TextBox.Resources>
           <Style TargetType="TextBox">
               <Setter Property="Validation.ErrorTemplate">
                   <Setter.Value>
                       <ControlTemplate>
                           <StackPanel Orientation="Horizontal">
                               <AdornedElementPlaceholder>
                                   <Border BorderBrush="Red" BorderThickness="1"/>
                               </AdornedElementPlaceholder>
                           </StackPanel>
                       </ControlTemplate>
                   </Setter.Value>
               </Setter>
           <Style.Triggers>
               <Trigger Property="Validation.HasError" Value="True">
                   <Setter Property="ToolTip" 
                        Value="{Binding RelativeSource={RelativeSource Self},
                                    Path=(Validation.Errors)[0].ErrorContent}"/>
               </Trigger>
           </Style.Triggers>
           </Style>
       </TextBox.Resources>
   </TextBox>

ToolTip显示正确,但TextBox的红色边框仅当我使用Snoop并在VisualTree中选择TextBox时显示。

所以我漏掉了什么?有扳机吗?

我在两本书里查到了这个例子,这些例子都很有用。根据UserControl的说法,这是一个错误吗?我必须以某种方式手动更新它吗?

现在,编辑,当我只这样使用它时,我完全糊涂了:

代码语言:javascript
复制
<TextBox x:Name="txtName" 
    Text="{Binding Path=Name, Mode=TwoWay, 
            UpdateSourceTrigger=PropertyChanged, 
            ValidatesOnDataErrors=True}" 
      Grid.Row="0" Grid.Column="2"
      VerticalAlignment="Bottom" MinWidth="100" FontSize="12">
    <TextBox.Resources>
        <Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="ToolTip" 
                    Value="{Binding RelativeSource={RelativeSource Self},
                                Path=(Validation.Errors)[0].ErrorContent}"/>
                <Setter Property="BorderBrush" Value="Red"/>
                <Setter Property="BorderThickness" Value="3"/>
            </Trigger>
        </Style.Triggers>
        </Style>
    </TextBox.Resources>
</TextBox>

BorderBrush和BorderThickness总是“红色”/“3”!为什么或者怎么触发才能使它倒退?根据这一点:使用Validation.HasError触发器属性WPF时只显示假样式应该在清除Validation.HasError时出现默认值。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-31 15:10:05

因此,我发现了我的错误(或者至少是为什么Validation.HasError从未重置的部分),我错误地使用了IDataErrorInfo接口。如果验证通过,我没有返回null或String.Empty。:(

代码语言:javascript
复制
    //Not used in WPF so return value is null
    string IDataErrorInfo.Error { get { return null; } }

    string IDataErrorInfo.this[string propertyName]
    {
        get
        {
            //the wrong way
            string error = "false way";
            //the right way
            string error = null;
            //or
            string error = String.Empty;

            switch (propertyName)
            {
                case ("name"):
                    if (string.IsNullOrEmpty(name) || name.Trim() == String.Empty)
                    {
                        error = "Enter name";
                    }
                    break;
                case ("age"):
                    if (string.IsNullOrEmpty(age) || age.Trim() == String.Empty)
                    {
                        error = "Enter age";
                    }
                    break;
                default:
                    Debug.Fail("Validation: Unexpected property: " + propertyName);
                    break;
            }
            return error;
        }
    }

编辑有时我会得到这个错误,没有修剪.

System.Windows.Data错误: 17 :无法从'(Validation.Errors)‘获取'Item[]’值(键入'ValidationError') (键入‘Validation.Errors’1‘)。ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: BindingExpression:Path=(0).ErrorContent;DataItem='TextBox‘(Name='txtName');目标元素是'TextBox’(Name='txtName');目标属性是'ToolTip‘(类型'Object')

票数 2
EN

Stack Overflow用户

发布于 2015-04-06 19:54:23

我意识到这是一个旧的帖子,你可能已经转移到更大更好的事情上去了,但我想我会给那些发现这个问题的人一个答案,因为他们和我一样,也在努力解决类似的问题。

我也有类似的问题。对我来说,答案是

代码语言:javascript
复制
Path=(Validation.Errors)[0].ErrorContent

使用

代码语言:javascript
复制
Path=(Validation.Errors).CurrentItem.ErrorContent

这个处理掉了

代码语言:javascript
复制
System.Windows.Data Error: 17 : Cannot get 'Item[]' value (type 'ValidationError') from '(Validation.Errors)' (type 'ReadOnlyObservableCollection`1').

您在编辑时向您的答案报告错误。另外,请参阅这个博客 (它给了我这个想法)以获得更多细节。

票数 2
EN

Stack Overflow用户

发布于 2014-07-30 14:19:31

我认为你需要把Border移动到AdornedElementPlaceholder周围。下面是我使用的ValidationTemplate,它有一个剪切角,当您悬停在它上面时,它会显示错误消息。

代码语言:javascript
复制
<ControlTemplate x:Key="ErrorTemplate">
    <StackPanel>
        <!--TextBox Error template-->
        <Canvas Panel.ZIndex="1099">
            <DockPanel>
                <Border BorderThickness="1" BorderBrush="#FFdc000c" CornerRadius="0.7"
                        VerticalAlignment="Top" DockPanel.Dock="Bottom" HorizontalAlignment="Left">
                    <Grid>
                        <Polygon x:Name="toolTipCorner"
                                 Grid.ZIndex="2"
                                 Margin="-1"
                                 Points="11,11 11,0 0,0" 
                                 Fill="#FFdc000c" 
                                 HorizontalAlignment="Right" 
                                 VerticalAlignment="Top"
                                 IsHitTestVisible="True"/>
                        <Polyline Grid.ZIndex="3"
                                              Points="12,12 0,0" Margin="-1" HorizontalAlignment="Right" 
                                              StrokeThickness="1.5"
                                              StrokeEndLineCap="Round"
                                              StrokeStartLineCap="Round"
                                              Stroke="White"
                                              VerticalAlignment="Top"
                                              IsHitTestVisible="True"/>
                        <AdornedElementPlaceholder x:Name="ErrorAdorner" />
                    </Grid>
                </Border>
            </DockPanel>
            <Popup x:Name="ErrorPopup" Opacity="0" IsOpen="False" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=ErrorAdorner}" StaysOpen="True">
                <Border Canvas.Bottom="4"
                        x:Name="errorBorder"
                        Canvas.Left="{Binding Path=AdornedElement.ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Adorner}}"
                        CornerRadius="5"
                        Background="#FFdc000c">

                    <Border.Effect>
                        <DropShadowEffect ShadowDepth="2.25" 
                              Color="Black" 
                              Opacity="0.4"
                              Direction="315"
                              BlurRadius="4"/>
                    </Border.Effect>

                    <TextBlock TextWrapping="Wrap" Margin="4"  
                               MaxWidth="250" Foreground="White"
                               FontSize="12"
                               Text="{Binding Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Adorner}}" />
                </Border>
            </Popup>
        </Canvas>
    </StackPanel>

    <ControlTemplate.Triggers>
        <DataTrigger Value="True" Binding="{Binding ElementName=toolTipCorner, Path=IsMouseOver}">
            <DataTrigger.EnterActions>
                <BeginStoryboard x:Name="fadeInStoryboard">
                    <Storyboard>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ErrorPopup"
                                                        Storyboard.TargetProperty="IsOpen">
                            <DiscreteBooleanKeyFrame Value="True" KeyTime="00:00:00"/>
                        </BooleanAnimationUsingKeyFrames>
                        <DoubleAnimation Duration="00:00:00.15"
                                     Storyboard.TargetName="errorBorder"
                                     Storyboard.TargetProperty="Opacity"
                                     To="1"/>
                        <ThicknessAnimation Duration="00:00:00.15"
                                        Storyboard.TargetName="errorBorder"
                                        Storyboard.TargetProperty="Margin"
                                        FillBehavior="HoldEnd"
                                        From="1,0,0,0"
                                        To="5,0,0,0">
                            <ThicknessAnimation.EasingFunction>
                                <BackEase EasingMode="EaseOut" Amplitude="2"/>
                            </ThicknessAnimation.EasingFunction>
                        </ThicknessAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
            <DataTrigger.ExitActions>
                <StopStoryboard BeginStoryboardName="fadeInStoryboard"/>
                <BeginStoryboard x:Name="fadeOutStoryBoard">
                    <Storyboard>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ErrorPopup"
                                                        Storyboard.TargetProperty="IsOpen">
                            <DiscreteBooleanKeyFrame Value="False" KeyTime="00:00:00"></DiscreteBooleanKeyFrame>
                        </BooleanAnimationUsingKeyFrames>
                        <DoubleAnimation Duration="00:00:00"
                                     Storyboard.TargetName="errorBorder"
                                     Storyboard.TargetProperty="Opacity"
                                     To="0"/>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.ExitActions>
        </DataTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

然后,您可以将它设置为如下项目的ErrorTemplate

代码语言:javascript
复制
<Style TargetType="TextBox">
    <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ErrorTemplate2}"/>
</Style>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25037993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档