0

I got a problem with changing color of Toggle in TreeView programmatically. I defined in ResourceDictionary SolidColorBrush with:

<SolidColorBrush x:Key="FillBrush" Color="#000000" />

i created style for toggleButton in ResourceDictionary as well:

<Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton">
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToggleButton">
                    <Grid Width="auto" Height="auto" Background="Transparent" ShowGridLines="True">                        
                        <Path Fill="{StaticResource FillBrush}" x:Name="ExpandPath" HorizontalAlignment="Center"  VerticalAlignment="Center"
                                        Data="M 0 0 L 0 2 L 6 0 z M 6 2 L 6 0 L 0 2 z">
                        </Path>
                    </Grid>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="True">
                            <Setter Property="Data" TargetName="ExpandPath" Value="M 0 0 L 0 8 L 2 0 z M 2 8 L 2 0 L 0 8 z"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

In code i am trying to change programmatically the value of the FillBrush key:

SolidColorBrush cc = (SolidColorBrush)Resources["FillBrush"];
cc.Color=c.Color; 

but when i change it, the Toggle button doesnt change.

Any hints how to change color of existing component? I am a bit confused of templating the components throught ResourceDictionary so i guess its something wrong in there. Thanks for all help

EDIT : in code i am "saying" use StaticResource. I tried it with DynamicResource as well, but nothing happend and the color value didnt change.

EDIT 2 : if i check the value in the FillBrush resource with:

MessageBox.Show(((SolidColorBrush)Resources["FillBrush"]).Color.ToString());

the value is replaced with the new value. So it works. In this case there must be something wrong with aplying it in the ToggleButton style.

tomdelahaba
  • 948
  • 3
  • 13
  • 26
  • Your problem seems very similar in nature to the one put forward here: http://stackoverflow.com/questions/15819796/change-wpf-button-background-image-programatically/15819880#15819880 The answers and discussion may be useful to you. – Clint Apr 04 '13 at 21:52
  • thx for hint i will check it out.. – tomdelahaba Apr 04 '13 at 21:54
  • You can find the default `ControlTemplate` for the `ToggleButton` at [this web page](http://msdn.microsoft.com/en-us/library/cc296245(v=vs.95).aspx). Alternatively if that doesn't help, maybe you could achieve what you want using binding or event handlers? Try looking at it from another direction. What is your overall aim? – Sheridan Apr 06 '13 at 00:38
  • my aim was: User change background color of the togglebutton. :] but i "solve" it with no togglebutton and it is the best solution i think :D – tomdelahaba Apr 10 '13 at 05:40

4 Answers4

0

A StaticResource will only read the initial colour. In order to update the colour dynamically, you will need to declare your Brush as a DynamicResource.

<Path Fill="{DynamicResource FillBrush}" x:Name="ExpandPath" HorizontalAlignment="Center"
    VerticalAlignment="Center" Data="M 0 0 L 0 2 L 6 0 z M 6 2 L 6 0 L 0 2 z">

There is an example in this post.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183
0

Try replacing the Brush - not changing its Color, e.g...

this.Resources["FillBrush"] = new SolidColorBrush(Colors.Red);

i.e. Brush is likely Freezed. Check e.g. this link (just first) Style Setter Freezing Brush

If you do the following...

if( !brush.IsFrozen ) // 'not froze' i.e. free to change
    brush.Color = Colors.Red;  

...chances are you'll never enter. You also get exception if accessing a freezed object.

Or better yet, you should do...

var brush = (SolidColorBrush)this.Resources["FillBrush"];
if (brush.IsFrozen)
{
    SolidColorBrush clone = brush.Clone();
    clone.Color = Colors.Red;
    this.Resources["FillBrush"] = clone;
}
else
    brush.Color = Colors.Red;

For more details check this very first MS link on the subject which involves exactly these issues...

Freezable Objects Overview

Community
  • 1
  • 1
NSGaga-mostly-inactive
  • 14,052
  • 3
  • 41
  • 51
0

With Blend I could do that in less than 5 mouse clicks,

(To view the image at full size, right-click it and choose View Image or Open image in new tab, depending the web browser you are using)

enter image description here

I'm not pasting the generated XAML because there's a lot, just the part that Blends has highlighted.

enter image description here

aybe
  • 15,516
  • 9
  • 57
  • 105
  • from that second picture it looks like that you changed the value of borderBrush. But i am not able to change the Path fill color..:/..border color (background of border) works perfectly for me.. – tomdelahaba Apr 05 '13 at 01:29
  • No, actually it's the Background property, image is cropped. (sorry I didn't pay attention) – aybe Apr 05 '13 at 01:34
0

Sometimes if the item you want to change is "buried" in a style it doesn't seem to get recognized when you try and change it, at least this is what I have experienced before when trying to style items and then wanting to be able to change either a color or font-family dynamically. Try this:

<Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton">
   <Setter Property="Focusable" Value="False"/>
   <Setter Property="Foreground" Value="{StaticResource FillBrush}"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="ToggleButton">
            <Grid Width="Auto" Height="Auto" Background="Transparent" ShowGridLines="True">
               <Path Fill="{Binding Foreground}" x:Name="ExpandPath" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 0 2 L 6 0 z M 6 2 L 6 0 L 0 2 z"/>
            </Grid>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

and when you want to change the color of the togglebutton - instead of changing the color of the FillBrush = you change the Foreground value of the actual ToggleButton. Since the Fill of the Path is bound to the foreground color, this should trigger it to change.

Hope this is helpful and works for you, I admit I have not tested this particular XAML code snippet but I have had to do similar work arounds in previous projects.