【问题标题】:In WPF, how do I get the current theme's button background?在 WPF 中,如何获取当前主题的按钮背景?
【发布时间】:2010-11-16 20:12:34
【问题描述】:

在我的 wpf 应用程序中,我需要获取主题的按钮背景画笔来绘制另一个控件的背景。

我已经尝试引用 PresentationFramework.Aero.dll 并使用 ButtonChrome,但到目前为止没有运气。

我也尝试过使用 VisualStyleRenderer,但似乎这个类只能用于绘制背景(我无法获取画笔并将其设置为另一个控件的背景)。

有什么想法吗?

亲切的问候, 爱德华多·梅洛

【问题讨论】:

    标签: c# wpf wpf-controls


    【解决方案1】:

    可以通过在资源中查找默认按钮样式在代码中完成:

        private static object GetValueFromStyle(object styleKey, DependencyProperty property)
        {
            Style style = Application.Current.TryFindResource(styleKey) as Style;
            while (style != null)
            {
                var setter =
                    style.Setters
                        .OfType<Setter>()
                        .FirstOrDefault(s => s.Property == property);
    
                if (setter != null)
                {
                    return setter.Value;
                }
    
                style = style.BasedOn;
            }
            return null;
        }
    
        ...
    
        this.Background = GetValueFromStyle(typeof(Button), BackgroundProperty) as Brush;
    

    如果您需要在 XAML 中执行此操作,您可以从上面的代码轻松创建标记扩展:

    public class ValueFromStyleExtension : MarkupExtension
    {
        public ValueFromStyleExtension()
        {
        }
    
        public object StyleKey { get; set; }
        public DependencyProperty Property { get; set; }
    
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (StyleKey == null || Property == null)
                return null;
            object value = GetValueFromStyle(StyleKey, Property);
            if (value is MarkupExtension)
            {
                return ((MarkupExtension)value).ProvideValue(serviceProvider);
            }
            return value;
        }
    
        private static object GetValueFromStyle(object styleKey, DependencyProperty property)
        {
            Style style = Application.Current.TryFindResource(styleKey) as Style;
            while (style != null)
            {
                var setter =
                    style.Setters
                        .OfType<Setter>()
                        .FirstOrDefault(s => s.Property == property);
    
                if (setter != null)
                {
                    return setter.Value;
                }
    
                style = style.BasedOn;
            }
            return null;
        }
    }
    

    XAML

    Background="{util:ValueFromStyle StyleKey={x:Type Button}, Property=Control.Background}">
    

    编辑:在值被定义为 DynamicResource(或另一个 ME)的情况下修复了 ValueFromStyleExtension

    【讨论】:

    • 这正是我正在寻找的。非常感谢。 :)
    • 只有一件事:对于那些遇到“MS.Internal.Markup.MarkupExtensionParser+UnknowMarkupExtension”错误的人,这里有一个解决方案:hardcodet.net/2008/04/nested-markup-extension-bug
    • 是的,这是一个烦人的错误...如果 ME 定义在单独的程序集中,则不会发生这种情况
    • 哦,我不知道。 Thomas,还有一件事:如果我将其定义为 DynamicResource,那么当系统主题发生变化时,背景也会发生变化?
    • 您的意思是,如果它被定义为样式中的 DynamicResource ?不,它不会自动更新。为此,ME 必须返回 DynamicResource 标记扩展,但由于某种原因,当我尝试时它似乎不起作用......
    猜你喜欢
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    相关资源
    最近更新 更多