以编程方式更改wpf中的切换颜色(TreeView)

时间:2013-04-04 21:49:03

标签: c# wpf treeview wpf-controls togglebutton

我遇到了以编程方式在TreeView中更改Toggle颜色的问题。 我在ResourceDictionary SolidColorBrush中定义了:

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

我也在ResourceDictionary中为toggleButton创建了样式:

<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>

在代码中我试图以编程方式更改FillBrush键的值:

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

但是当我改变它时,Toggle按钮不会改变。

如何更改现有组件的颜色? 我对通过ResourceDictionary模板化组件感到有些困惑,所以我猜它有些不对劲。 感谢您的帮助

代码中的

编辑:我在说“使用StaticResource”。我也尝试使用DynamicResource,但没有任何事情发生,颜色值也没有变化。

编辑2:如果我使用以下方法检查FillBrush资源中的值:

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

该值将替换为新值。所以它有效。在这种情况下,在ToggleButton样式中使用它时必定存在问题。

4 个答案:

答案 0 :(得分:0)

StaticResource只会读取初始颜色。要动态更新颜色,您需要将Brush声明为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">

this post中有一个例子。

答案 1 :(得分:0)

尝试替换Brush - 不更改其Color,例如...

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

即。 Brush可能是Freezed。检查例如这个链接(只是第一个)Style Setter Freezing Brush

如果您执行以下操作......

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

......你永远不会进入的机会。如果访问冻结对象,您也会遇到异常。

或者更好的是,你应该......

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;

有关详细信息,请查看关于该主题的第一个MS链接,其中涉及这些问题......

Freezable Objects Overview

答案 2 :(得分:0)

使用Blend我可以在不到5次鼠标点击的情况下完成,

(要以完整尺寸查看图像,请右键单击该图像,然后根据您使用的Web浏览器选择“在新标签页中查看图像或打开图像”)

enter image description here

我没有粘贴生成的XAML,因为有很多,只是Blends突出显示的部分。

enter image description here

答案 3 :(得分:0)

有时候,如果您要更改的项目是&#34;埋藏&#34;在尝试更改它时,它似乎没有得到识别,至少这是我之前尝试设置项目样式然后想要能够动态更改颜色或字体系列时所经历的。试试这个:

<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>

当您想要更改togglebutton的颜色时 - 而不是更改FillBrush =的颜色,您可以更改实际ToggleButton的Foreground值。由于Path的Fill绑定到前景色,因此应该触发它更改。

希望这对您有用并且对您有用,我承认我没有测试过这个特定的XAML代码片段,但我不得不在之前的项目中做过类似的工作。