Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Once a property has been set, styles no longer will be applied. By setting the inner and outer brush properties in your changed handler yourself, the dependency property subsystem is not aware that the the change was actually due to a style versus you doing it explicitly.</p> <p>One solution is to expose protected read-only <code>ActualInnerBorderBrush</code> and <code>ActualOuterBorderBrush</code> properties and then have all three of the user-definable properties set these actual values in their respective change handlers. This way the user-visible properties can always be "as set by the user" without interfering with each other.</p> <p><strong>Edit:</strong></p> <p>Here is a complete working implementation of the five properties:</p> <pre><code>public class Clock : StackPanel { public Brush Brush { get { return (Brush)GetValue(BrushProperty); } set { SetValue(BrushProperty, value); } } public static readonly DependencyProperty BrushProperty = DependencyProperty.Register("Brush", typeof(Brush), typeof(Clock), new UIPropertyMetadata((d, e) =&gt; (d as Clock).OnBrushChanged(d, e))); public void OnBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ActualInnerBrush = e.NewValue as Brush; ActualOuterBrush = e.NewValue as Brush; } public Brush InnerBrush { get { return (Brush)GetValue(InnerBrushProperty); } set { SetValue(InnerBrushProperty, value); } } public static readonly DependencyProperty InnerBrushProperty = DependencyProperty.Register("InnerBrush", typeof(Brush), typeof(Clock), new UIPropertyMetadata((d, e) =&gt; (d as Clock).OnInnerBrushChanged(d, e))); public void OnInnerBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ActualInnerBrush = e.NewValue as Brush; } public Brush OuterBrush { get { return (Brush)GetValue(OuterBrushProperty); } set { SetValue(OuterBrushProperty, value); } } public static readonly DependencyProperty OuterBrushProperty = DependencyProperty.Register("OuterBrush", typeof(Brush), typeof(Clock), new UIPropertyMetadata((d, e) =&gt; (d as Clock).OnOuterBrushChanged(d, e))); public void OnOuterBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ActualOuterBrush = e.NewValue as Brush; } public Brush ActualInnerBrush { get { return (Brush)GetValue(ActualInnerBrushProperty); } private set { SetValue(ActualInnerBrushPropertyKey, value); } } private static readonly DependencyPropertyKey ActualInnerBrushPropertyKey = DependencyProperty.RegisterReadOnly("ActualInnerBrush", typeof(Brush), typeof(Clock), new UIPropertyMetadata()); public static readonly DependencyProperty ActualInnerBrushProperty = ActualInnerBrushPropertyKey.DependencyProperty; public Brush ActualOuterBrush { get { return (Brush)GetValue(ActualOuterBrushProperty); } private set { SetValue(ActualOuterBrushPropertyKey, value); } } private static readonly DependencyPropertyKey ActualOuterBrushPropertyKey = DependencyProperty.RegisterReadOnly("ActualOuterBrush", typeof(Brush), typeof(Clock), new UIPropertyMetadata()); public static readonly DependencyProperty ActualOuterBrushProperty = ActualOuterBrushPropertyKey.DependencyProperty; } </code></pre> <p>and here is a little test program to prove that it works:</p> <pre><code>&lt;Grid&gt; &lt;Grid.Resources&gt; &lt;Style x:Key="styleBrush" TargetType="local:Clock"&gt; &lt;Setter Property="Brush" Value="Red"/&gt; &lt;/Style&gt; &lt;Style x:Key="styleInnerOnly" TargetType="local:Clock"&gt; &lt;Setter Property="InnerBrush" Value="Green"/&gt; &lt;/Style&gt; &lt;Style x:Key="styleInnerOuter" TargetType="local:Clock"&gt; &lt;Setter Property="InnerBrush" Value="Blue"/&gt; &lt;Setter Property="OuterBrush" Value="Yellow"/&gt; &lt;/Style&gt; &lt;Style x:Key="styleEmpty" TargetType="local:Clock"/&gt; &lt;/Grid.Resources&gt; &lt;StackPanel&gt; &lt;local:Clock x:Name="clock" Orientation="Horizontal"&gt; &lt;Rectangle Width="100" Height="100" Fill="{Binding ActualInnerBrush, ElementName=clock}"/&gt; &lt;Rectangle Width="100" Height="100" Fill="{Binding ActualOuterBrush, ElementName=clock}"/&gt; &lt;/local:Clock&gt; &lt;StackPanel Orientation="Horizontal"&gt; &lt;Button Content="Default"&gt; &lt;i:Interaction.Triggers&gt; &lt;i:EventTrigger EventName="Click"&gt; &lt;ei:ChangePropertyAction TargetObject="{Binding ElementName=clock}" PropertyName="Style" Value="{x:Null}"/&gt; &lt;/i:EventTrigger&gt; &lt;/i:Interaction.Triggers&gt; &lt;/Button&gt; &lt;Button Content="BrushOnly"&gt; &lt;i:Interaction.Triggers&gt; &lt;i:EventTrigger EventName="Click"&gt; &lt;ei:ChangePropertyAction TargetObject="{Binding ElementName=clock}" PropertyName="Style" Value="{StaticResource styleBrush}"/&gt; &lt;/i:EventTrigger&gt; &lt;/i:Interaction.Triggers&gt; &lt;/Button&gt; &lt;Button Content="InnerOnly"&gt; &lt;i:Interaction.Triggers&gt; &lt;i:EventTrigger EventName="Click"&gt; &lt;ei:ChangePropertyAction TargetObject="{Binding ElementName=clock}" PropertyName="Style" Value="{StaticResource styleInnerOnly}"/&gt; &lt;/i:EventTrigger&gt; &lt;/i:Interaction.Triggers&gt; &lt;/Button&gt; &lt;Button Content="InnerOuter"&gt; &lt;i:Interaction.Triggers&gt; &lt;i:EventTrigger EventName="Click"&gt; &lt;ei:ChangePropertyAction TargetObject="{Binding ElementName=clock}" PropertyName="Style" Value="{StaticResource styleInnerOuter}"/&gt; &lt;/i:EventTrigger&gt; &lt;/i:Interaction.Triggers&gt; &lt;/Button&gt; &lt;Button Content="Empty"&gt; &lt;i:Interaction.Triggers&gt; &lt;i:EventTrigger EventName="Click"&gt; &lt;ei:ChangePropertyAction TargetObject="{Binding ElementName=clock}" PropertyName="Style" Value="{StaticResource styleEmpty}"/&gt; &lt;/i:EventTrigger&gt; &lt;/i:Interaction.Triggers&gt; &lt;/Button&gt; &lt;/StackPanel&gt; &lt;/StackPanel&gt; &lt;/Grid&gt; </code></pre> <p>This example uses behaviors. If you are not familiar with behaviors, install the Expression Blend 4 SDK and add these namespaces:</p> <pre><code>xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" </code></pre> <p>and add <code>System.Windows.Interactivity</code> and <code>Microsoft.Expression.Interactions</code> to your project.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload