Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
133 views
in Technique[技术] by (71.8m points)

c# - Create custom binding property for window.resources style

I've created a couple of custom bindings for a custom control before, but since this case is for a window.resources style for a button, (A control template rather), I don't know where to start for the code behind. Where would I create the viewmodel, and what would it inherit from or reference?

XAML:

<Style x:Key="UnifiedButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="Margin" Value="{Binding Margin}"/>

        <Setter Property="Background" Value="#FFDDDDDD"/>
        <Setter Property="BorderBrush" Value="#FF707070"/>
        <Setter Property="Foreground" Value="#FF000000"/>

        <Setter Property="BorderThickness" Value="1"/>

        <Setter Property="Content" Value="Button"/>

        <Setter Property="Width" Value="75"/>
        <Setter Property="Height" Value="20"/>
        <Setter Property="Padding" Value="5"/>

        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid
                        x:Name="ButtonGrid"
                        Background="{TemplateBinding Background}"
                        OpacityMask="{TemplateBinding OpacityMask}">
                        <Border
                            x:Name="ButtonBorder"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            OpacityMask="{TemplateBinding OpacityMask}"

                            BorderThickness="{TemplateBinding BorderThickness}">

                            <Label
                                x:Name="ButtonLabel"
                                Foreground="{TemplateBinding Foreground}"

                                Padding="{TemplateBinding Padding}">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Label>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="ButtonGrid" Property="Background" Value="{Binding HoverColorBackground}"/>
                            <Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{Binding HoverColorBorder}"/>
                            <Setter TargetName="ButtonLabel" Property="Foreground" Value="{Binding HoverColorForeground}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Hovercolor setters are the key here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Creating a viewmodel to customize wpf button colors is a wrong approach. Button color scheme is something which belongs strictly to a view. Also many buttons means many view model instances, since each button might want to be unique - too much code for such a simple setting.

Button class doesn't have enough dependency properties to set color representing HoverColorBackground/HoverColorBorder/HoverColorForeground. Alternatives are to create a derived Button class (way to go when DP are of some complex type and/or have associated logic) or use attached properties. I have written a tip, which coveres the second approach.

short version

create an attached DP

public static class Alt
{
    #region Background
    public static readonly DependencyProperty BackgroundProperty =
              DependencyProperty.RegisterAttached("Background", typeof(Brush),
              typeof(Alt), new PropertyMetadata(null));

    public static Brush GetBackground(DependencyObject obj)
    {
        return (Brush)obj.GetValue(Alt.BackgroundProperty);
    }

    public static void SetBackground(DependencyObject obj, Brush value)
    {
        obj.SetValue(Alt.BackgroundProperty, value);
    }
    #endregion
}

set custom value for that property

<Button Content="Blue" Foreground="White" Margin="5"
        Background="Blue" ui:Alt.Background="DarkBlue"/>

make sure that template know how to use that property

<Trigger Property="IsMouseOver" Value="True">
    <Setter TargetName="ButtonGrid" 
            Property="Background" 
            Value="{Binding Path=(ui:Alt.Background),
                            RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>

Works for any control. Many DP can be mixed in any combination.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...