在我的 WPF 应用程序中,我只想在用户编辑/输入/聚焦控件后显示验证装饰器。这样,用户就有机会在字段中提供有效输入,并且只有当他们选择不提供时,才会显示验证。
我们希望鼓励完成每个字段,以便在首次打开表单时指示必填字段可能会规避用户立即倾向于完成他们需要完成的内容以摆脱也可能绕过表单流程的大红色验证错误。
有没有办法知道控件是否已经获得焦点?附加属性可能会起作用吗?
如果它有助于提供更具体的响应:这是我当前的验证样式,显示红色边框 [如果控件有边框] 和带有错误消息工具提示的小感叹号(真的很标准):
<Style TargetType="Control">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="true">
<Image Source="../Resources/Icons/Error.ico" Margin="4" Width="15" ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}" />
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
<Border BorderBrush="red" BorderThickness="1" Visibility="{Binding ElementName=customAdorner, Path=AdornedElement.BorderThickness, Converter={StaticResource hasBorderToVisibilityConverter}}" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsVisible" Value="False">
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>
最佳答案
您可以将附加行为与附加属性结合起来执行此操作。附加行为 ObserveFocus
将订阅 GotFocus
事件并在事件处理程序中将 HasHeldFocus
附加属性设置为 True
它可以用来像这样在 ViewModel 中设置一个属性
<Button local:HasHeldFocusBehavior.ObserveFocus="True"
local:HasHeldFocusBehavior.HasHeldFocus="{Binding HasHeldFocus,
Mode=OneWayToSource}"/>
这是一个示例,说明如何使用它来更改 Button
的 Background
一旦它被聚焦
<Style TargetType="Button">
<Setter Property="Background" Value="Red"/>
<Setter Property="local:HasHeldFocusBehavior.ObserveFocus" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},
Path=(local:HasHeldFocusBehavior.HasHeldFocus)}"
Value="True">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
HasHeldFocusBehavior
public static class HasHeldFocusBehavior
{
public static readonly DependencyProperty ObserveFocusProperty =
DependencyProperty.RegisterAttached("ObserveFocus",
typeof(bool),
typeof(HasHeldFocusBehavior),
new UIPropertyMetadata(false, OnObserveFocusChanged));
public static bool GetObserveFocus(DependencyObject obj)
{
return (bool)obj.GetValue(ObserveFocusProperty);
}
public static void SetObserveFocus(DependencyObject obj, bool value)
{
obj.SetValue(ObserveFocusProperty, value);
}
private static void OnObserveFocusChanged(DependencyObject dpo,
DependencyPropertyChangedEventArgs e)
{
UIElement element = dpo as UIElement;
element.Focus();
if ((bool)e.NewValue == true)
{
SetHasHeldFocus(element, element.IsFocused);
element.GotFocus += element_GotFocus;
}
else
{
element.GotFocus -= element_GotFocus;
}
}
static void element_GotFocus(object sender, RoutedEventArgs e)
{
UIElement element = sender as UIElement;
SetHasHeldFocus(element, true);
}
private static readonly DependencyProperty HasHeldFocusProperty =
DependencyProperty.RegisterAttached("HasHeldFocus",
typeof(bool),
typeof(HasHeldFocusBehavior),
new UIPropertyMetadata(false));
public static void SetHasHeldFocus(DependencyObject element, bool value)
{
element.SetValue(HasHeldFocusProperty, value);
}
public static bool GetHasHeldFocus(DependencyObject element)
{
return (bool)element.GetValue(HasHeldFocusProperty);
}
}
更新
在您的情况下,您可以将 Validation.HasError
触发器替换为 MultiTrigger
<Style TargetType="Control">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.HasError)}"
Value="True"/>
<Condition Binding="{Binding RelativeSource={RelativeSource Self},
Path=(local:HasHeldFocusBehavior.HasHeldFocus)}"
Value="True"/>
</MultiDataTrigger.Conditions>
<!-- Setters.. -->
</MultiDataTrigger>
<!-- ... -->
</Style.Triggers>
</Style>
关于.net - WPF 验证装饰器 - 仅显示控件之前是否保持焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5097449/