Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In WPF, how do I get the current theme's button background?

In my wpf application, I need to get the theme's button background brush to draw the background of another control.

I have tried referencing PresentationFramework.Aero.dll and using ButtonChrome, but no luck so far.

I've tried using VisualStyleRenderer also, but it seems that this class can be used only to draw the background (I can't get a brush and set it as the background of another control).

Any ideas?

Kind Regards, Eduardo Melo

like image 554
Carlos Melo Avatar asked Nov 16 '10 20:11

Carlos Melo


1 Answers

It can be done in code by looking up the default button style in the resources :

    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;

If you need to do it in XAML, you can easily create a markup extension from the code above:

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

EDIT: fixed ValueFromStyleExtension for the case where the value is defined as a DynamicResource (or another ME)

like image 141
Thomas Levesque Avatar answered Nov 18 '22 12:11

Thomas Levesque