WPF provides IsPressed Property on button that can be used to write triggers based on its value. There is no such propery available on other control. I recently had to show a DropShadowEffect when a Border is pressed. I used solution described below which can be used for any other WPF control as well that derives from FrameworkElement. I have used attached properties for this.
public class FrameworkElementExt
{
public static readonly DependencyProperty IsPressedProperty = DependencyProperty.RegisterAttached("IsPressed", typeof(bool),
typeof(FrameworkElementExt), new PropertyMetadata(false));
public static readonly DependencyProperty AttachIsPressedProperty = DependencyProperty.RegisterAttached("AttachIsPressed", typeof(bool), typeof(FrameworkElementExt), new PropertyMetadata(false, PropertyChangedCallback));
public static void PropertyChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
{
FrameworkElement element = (FrameworkElement)depObj;
if (element != null)
{
if ((bool)args.NewValue)
{
element.MouseDown += new MouseButtonEventHandler(element_MouseDown);
element.MouseUp += new MouseButtonEventHandler(element_MouseUp);
element.MouseLeave += new MouseEventHandler(element_MouseLeave);
}
else
{
element.MouseDown -= new MouseButtonEventHandler(element_MouseDown);
element.MouseUp -= new MouseButtonEventHandler(element_MouseUp);
element.MouseLeave -= new MouseEventHandler(element_MouseLeave);
}
}
}
static void element_MouseLeave(object sender, MouseEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
if (element != null)
{
element.SetValue(IsPressedProperty, false);
}
}
static void element_MouseUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
if (element != null)
{
element.SetValue(IsPressedProperty, false);
}
}
static void element_MouseDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
if (element != null)
{
element.SetValue(IsPressedProperty, true);
}
}
public static bool GetIsPressed(UIElement element)
{
return (bool)element.GetValue(IsPressedProperty);
}
public static void SetIsPressed(UIElement element, bool val)
{
element.SetValue(IsPressedProperty, val);
}
public static bool GetAttachIsPressed(UIElement element)
{
return (bool)element.GetValue(AttachIsPressedProperty);
}
public static void SetAttachIsPressed(UIElement element, bool val)
{
element.SetValue(AttachIsPressedProperty, val);
}
}
Effect is defined in Resorces
<DropShadowEffect x:Key="effect" ShadowDepth="0" Color="White" BlurRadius="20" />
Now Define The Trigger as below, notice that AttachIsPressed needs to be set to true.
<Border CornerRadius="10" local:FrameworkElementExt.AttachIsPressed="True">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="local:FrameworkElementExt.IsPressed" Value="True">
<Setter Property="Effect" Value="{StaticResource effect}"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
public class FrameworkElementExt
{
public static readonly DependencyProperty IsPressedProperty = DependencyProperty.RegisterAttached("IsPressed", typeof(bool),
typeof(FrameworkElementExt), new PropertyMetadata(false));
public static readonly DependencyProperty AttachIsPressedProperty = DependencyProperty.RegisterAttached("AttachIsPressed", typeof(bool), typeof(FrameworkElementExt), new PropertyMetadata(false, PropertyChangedCallback));
public static void PropertyChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
{
FrameworkElement element = (FrameworkElement)depObj;
if (element != null)
{
if ((bool)args.NewValue)
{
element.MouseDown += new MouseButtonEventHandler(element_MouseDown);
element.MouseUp += new MouseButtonEventHandler(element_MouseUp);
element.MouseLeave += new MouseEventHandler(element_MouseLeave);
}
else
{
element.MouseDown -= new MouseButtonEventHandler(element_MouseDown);
element.MouseUp -= new MouseButtonEventHandler(element_MouseUp);
element.MouseLeave -= new MouseEventHandler(element_MouseLeave);
}
}
}
static void element_MouseLeave(object sender, MouseEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
if (element != null)
{
element.SetValue(IsPressedProperty, false);
}
}
static void element_MouseUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
if (element != null)
{
element.SetValue(IsPressedProperty, false);
}
}
static void element_MouseDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
if (element != null)
{
element.SetValue(IsPressedProperty, true);
}
}
public static bool GetIsPressed(UIElement element)
{
return (bool)element.GetValue(IsPressedProperty);
}
public static void SetIsPressed(UIElement element, bool val)
{
element.SetValue(IsPressedProperty, val);
}
public static bool GetAttachIsPressed(UIElement element)
{
return (bool)element.GetValue(AttachIsPressedProperty);
}
public static void SetAttachIsPressed(UIElement element, bool val)
{
element.SetValue(AttachIsPressedProperty, val);
}
}
Effect is defined in Resorces
<DropShadowEffect x:Key="effect" ShadowDepth="0" Color="White" BlurRadius="20" />
Now Define The Trigger as below, notice that AttachIsPressed needs to be set to true.
<Border CornerRadius="10" local:FrameworkElementExt.AttachIsPressed="True">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="local:FrameworkElementExt.IsPressed" Value="True">
<Setter Property="Effect" Value="{StaticResource effect}"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>