To do this, you can combine Attached Behavior with Attached Property. The attached behavior ObserveFocuswill be subscribed to the event GotFocus, and in the event handler, set the HasHeldFocusAttached Property toTrue
It can be used to set a property in the ViewModel, as shown.
<Button local:HasHeldFocusBehavior.ObserveFocus="True"
local:HasHeldFocusBehavior.HasHeldFocus="{Binding HasHeldFocus,
Mode=OneWayToSource}"/>
Here is an example of how it could be used to change Backgroundfor Buttonafter focusing it
<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);
}
}
Update
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>
</MultiDataTrigger>
</Style.Triggers>
</Style>