wpf – 在按钮的控件模板中,如何设置包含文本的颜色?

前端之家收集整理的这篇文章主要介绍了wpf – 在按钮的控件模板中,如何设置包含文本的颜色?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用Silverlight 4& WPF 4,我试图创建一个按钮样式,改变任何包含的文本的文本颜色,当按钮是mouSEOver’d.因为我试图使它兼容Silverlight& WPF,我正在使用视觉状态管理器:

<Style TargetType="{x:Type Button}">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="Button">
            <Border x:Name="outerBorder" CornerRadius="4" BorderThickness="1" BorderBrush="#FF757679">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal" />
                        <VisualState x:Name="MouSEOver">
                            <Storyboard>
                                <ColorAnimation Duration="0" To="#FFFEFEFE"
                                                Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                                                Storyboard.TargetName="contentPresenter"/> 
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Grid>
                    <Border x:Name="Background" CornerRadius="3" BorderThickness="1" BorderBrush="Transparent">
                        <Grid>
                            <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}"/>
                        </Grid>
                    </Border>
                </Grid>
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>

既然这是一个常规的旧按钮的模板,我知道这里不存在一个文本框,不知道这是甚么可能的.奇怪的是,如果按钮被声明为如下,文本颜色会改变:

<Button Content="Hello,World!" />

但是如果按钮被声明为:

<Button>
    <TextBlock Text="Hello,World!" /> <!-- Same result with <TextBlock>Hello,World </TextBlock> -->
</Button>

即使视觉树(在snoop中进行检查)是相同的(Button – > ContentPresenter – > TextBlock),与第一版本中创建的文本块的数据上下文设置为“Hello,World”的警告相反,第二个版本中的textblock仅设置其text属性.我假设这与控件创建的顺序有关(按钮创建TextBlock的第一个版本,在第二个版本中可能会首先创建文本框),真的不知道这一点).

在研究这个过程中,我看到了一些在Silverlight中工作的解决方案(比如用ContentControl替换ContentPresenter),但这在WPF(程序实际上是崩溃)中不起作用.

因为这是在按钮的控件模板中,如果可能,我想使用VSM,我认为也排除了显式地更改Button自己的Foreground属性(我不知道如何从模板中访问它? )

我真的很感激任何帮助,任何人都可以给予.

解决方法

所以经过一些思考之后,我最终得到的解决方案是在按钮控件模板中的ContentPresenter元素中添加一个附加的属性.附加的属性接受颜色,当设置检查任何TextBlocks的内容呈现者的可视树,并将Foreground属性设置为传入的值.这显然可以扩展/使其处理其他元素,但现在它工作为我所需要的

public static class ButtonAttachedProperties
    {
        /// <summary>
        /// ButtonTextForegroundProperty is a property used to adjust the color of text contained within the button.
        /// </summary>
        public static readonly DependencyProperty ButtonTextForegroundProperty = DependencyProperty.RegisterAttached(
            "ButtonTextForeground",typeof(Color),typeof(FrameworkElement),new FrameworkPropertyMetadata(Color.FromArgb(255,0),FrameworkPropertyMetadataOptions.AffectsRender,OnButtonTextForegroundChanged));

        public static void OnButtonTextForegroundChanged(DependencyObject o,DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue is Color)
            {
                var brush = new SolidColorBrush(((Color) e.NewValue)) as Brush;
                if (brush != null)
                {
                    SetTextBlockForegroundColor(o as FrameworkElement,brush);
                }
            }
        }

        public static void SetButtonTextForeground(FrameworkElement fe,Color color)
        {
            var brush = new SolidColorBrush(color);
            SetTextBlockForegroundColor(fe,brush);
        }

        public static void SetTextBlockForegroundColor(FrameworkElement fe,Brush brush)
        {
            if (fe == null)
            {
                return;
            }

            if (fe is TextBlock)
            {
                ((TextBlock)fe).Foreground = brush;
            }

            var children = VisualTreeHelper.GetChildrenCount(fe);
            if (children > 0)
            {
                for (int i = 0; i < children; i++)
                {
                    var child = VisualTreeHelper.GetChild(fe,i) as FrameworkElement;
                    if (child != null)
                    {
                        SetTextBlockForegroundColor(child,brush);
                    }
                }
            }
            else if (fe is ContentPresenter)
            {
                SetTextBlockForegroundColor(((ContentPresenter)fe).Content as FrameworkElement,brush);
            }
        }
    }

修改了模板:

<ContentPresenter x:Name="contentPresenter" 
                  ContentTemplate="{TemplateBinding ContentTemplate}" 
                  local:ButtonAttachedProperties.ButtonTextForeground="{StaticResource ButtonTextNormalColor}" />

猜你在找的Silverlight相关文章