0

Well hi, I am kind of new to WPF and this is the first time I tried change styles of WPF controls. Thanks to Expression Blend everything went better than expected until I made this style.

 <Style TargetType="{x:Type TextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PART_ContentHost">
                                        <EasingDoubleKeyFrame KeyTime="0" Value="0.5"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Background">
                                        <EasingColorKeyFrame KeyTime="0" Value="Red"/>
                                    </ColorAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Background">
                                        <EasingColorKeyFrame KeyTime="0" Value="Yellow"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="ReadOnly"/>
                            <VisualState x:Name="MouseOver"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Rectangle x:Name="Background" Fill="{StaticResource ControlBackgroundBrush}" Stroke="{StaticResource NormalBrush}" RadiusX="2" RadiusY="2"/>
                    <ScrollViewer x:Name="PART_ContentHost" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" FontFamily="{TemplateBinding FontFamily}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>
</Style>

Those two brushes are here:

    <Color x:Key="MainColor">#FF595959</Color>
<Color x:Key="ControlBackgroundColor">#FF333333</Color>

<SolidColorBrush x:Key="NormalBrush" Color="{DynamicResource MainColor}"/>
<SolidColorBrush x:Key="ControlBackgroundBrush" Color="{StaticResource ControlBackgroundColor}" />

Well and what is the problem. Disabling TextBox should change BorderColor and Background of TextBox but it also changes color of everything what uses NormalBrush. I want to have just few brushes common for all controls to let the theme be easily modified. One more thing I use them Usualy in other styles as StaticResource. Your suggestions and help would be highly appreciated.

Kapitán Mlíko
  • 4,498
  • 3
  • 43
  • 60
  • That is happening because you are animating (incrementally altering a static or SHARED resource). If you need to affect only the local element, you will need to create a local template. For what you are trying to accomplish, I think the `VisualState` approach is overkill, for the record. A `ControlTemplate.Trigger` can easily trigger a local color animation. – XamlZealot Nov 08 '12 at 18:03
  • Another possible approach (although I am not sure what other impact this would have on other app components) is to make the Brushes NOT shared: '' – XamlZealot Nov 08 '12 at 18:05

2 Answers2

1

StaticResource is by definition STATIC (Shared), so animating a property of a STATIC resource will affect ALL elements that use the StaticResource within its scope. By marking the x:Shared attribute to FALSE, WPF will create an instance for each element that uses it versus one static resource:

<SolidColorBrush x:Key="OniiNormalBrush" x:Shared="False" Color="{StaticResource MainColor}"/>
XamlZealot
  • 693
  • 5
  • 12
  • 1
    Rather than only post a block of code, please *explain* why this code solves the problem posed. Without an explanation, this is not an answer. – Martijn Pieters Nov 08 '12 at 18:29
0

Well I never found out why one color is changed everywhere and the second one is not. As suggested in comments I changed that style to use triggers instead of visualStates and everything works fine.

<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type TextBox}">
            <Grid>
                <Rectangle x:Name="Background" Fill="{StaticResource ControlBackgroundBrush}" Stroke="{StaticResource NormalBrush}" RadiusX="2" RadiusY="2"/>
                <ScrollViewer x:Name="PART_ContentHost" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" FontFamily="{TemplateBinding FontFamily}"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Fill" TargetName="Background" Value="Red" />
                    <Setter Property="Stroke" TargetName="Background" Value="Green" />
                    <Setter Property="Foreground" Value="Blue" />
                </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>

EDIT

Everything was coused by definition of NormalBrush where Color was DynamicResource

Kapitán Mlíko
  • 4,498
  • 3
  • 43
  • 60