我的表单上有一个DatePicker。当用户键入无效日期时,控件将获得红色边框。但是,我还想在它旁边显示错误。
<Style TargetType="{x:Type DatePicker}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<Border BorderThickness="1" BorderBrush="#FFdc000c" VerticalAlignment="Top">
<Grid>
<AdornedElementPlaceholder x:Name="adorner" Margin="-1"/>
</Grid>
</Border>
<Border x:Name="errorBorder" Background="#FFdc000c" Margin="8,0,0,0"
Opacity="0" CornerRadius="0"
IsHitTestVisible="False"
MinHeight="24" >
<TextBlock Text="{Binding ElementName=adorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Foreground="White" Margin="8,2,8,3" TextWrapping="Wrap" VerticalAlignment="Center"/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<Binding ElementName="adorner" Path="AdornedElement.IsKeyboardFocused" />
</DataTrigger.Binding>
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="fadeInStoryboard">
<Storyboard>
<DoubleAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="fadeInStoryboard"/>
<BeginStoryboard x:Name="fadeOutStoryBoard">
<Storyboard>
<DoubleAnimation Duration="00:00:00"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
在我的app.xaml
中,我将其包括在内:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/<assembly>.App;component/Styles/DatePicker.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
日期选择器旁边没有显示验证文本。我做错了什么?
更新
它出现此问题与在动画中使用AdornedElement.IsKeyboardFocused
有关。如果我删除动画并将不透明度设置为1,则会显示验证,但这显然不是我想要在这里实现的。但是,此代码适用于其他控件,如文本框,复选框,..
有没有其他方法可以让它发挥作用?
答案 0 :(得分:5)
DatePicker是一个控件,其中IsKeyboardFocused不会填充属性(请尝试WPF Inspector自行检查)。可能是因为它可能不是典型的输入控件,键盘焦点可能是日历按钮或实际文本框。 该分辨率用于IsKeyboarFocusWithin。
<DataTrigger.Binding>
<Binding ElementName="adorner" Path="AdornedElement.(DatePicker.IsKeyboardFocusWithin)" />
</DataTrigger.Binding>
答案 1 :(得分:0)
使用弹出窗口作为模板,您可以使用展示位置属性将其放置在控件周围。
<Popup x:Name="Popup"
Placement="Right"
PlacementTarget="{Binding ElementName=adorner}">
<Grid>
<Border Background="{DynamicResource UI.ErrorBrush}" Padding="5 4">
<TextBlock Text="{Binding Path=AdornedElement.(Validation.Errors)[0].ErrorContent,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Adorner}},
FallbackValue=null, Mode=OneTime}"/>
</Border>
</Grid>
</Popup>
要为弹出窗口添加行为,您需要应用数据触发器,以便在需要时执行所需操作。
在顶部包含此内容
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
并在弹出窗口中创建触发器
<i:Interaction.Triggers>
<!-- Shows Popup when TextBox has focus -->
<ei:DataTrigger Binding="{Binding ElementName=ErrorAdorner, Path=AdornedElement.IsFocused, FallbackValue=False}" Value="True">
<ei:ChangePropertyAction PropertyName="IsOpen"
TargetObject="{Binding ElementName=Popup,
FallbackValue=null}"
Value="True" />
<ei:DataTrigger Binding="{Binding ElementName=ErrorAdorner, Path=AdornedElement.IsFocused, FallbackValue=False}" Value="False">
<ei:ChangePropertyAction PropertyName="IsOpen"
TargetObject="{Binding ElementName=Popup,
FallbackValue=null}"
Value="False" />
</ei:DataTrigger>
当错误为空时,您还希望触发器隐藏弹出窗口,因为如果它有动画(例如淡入淡出),弹出窗口中的文本将在淡出时显示为null。这可以是错误计数等于0并将动画设置为无/隐藏的单个触发器。