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
402 views
in Technique[技术] by (71.8m points)

c# - WPF : Re-usable template for image buttons?

My WPF project uses a lot of image buttons, but since I haven't found a way to do it properly (I have to write the same triggers and style each time, only difference is the image source), my resource dictionary became very long for nothing. Is there a better way of doing this?

Here's a sample of the style I'm using for my buttons :

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <!-- Some setters -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <Image Source="Images.png" Stretch="Fill"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <!-- Some triggers ( IsFocused, IsMouseOver, etc.) -->
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Thank you :)

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

The easiest way is to create a specific control with an Image property:

public class ImageButton : Button
{
    static ImageButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof (ImageButton),
            new FrameworkPropertyMetadata(typeof (ImageButton)));
    }


    public ImageSource Image
    {
        get { return (ImageSource)GetValue(ImageProperty); }
        set { SetValue(ImageProperty, value); }
    }

    public static readonly DependencyProperty ImageProperty =
        DependencyProperty.Register("Image", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));

}

Then you just create a style for it in generic.xaml, and bind to the Image property instead of setting the image explicitly:

<Style x:Key="{x:Type my:ImageButton}" TargetType="{x:Type my:ImageButton}">
    <!-- Some setters -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type my:ImageButton}">
                <Grid>
                    <Image Source="{TemplateBinding Image}" Stretch="Fill"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <!-- Some triggers ( IsFocused, IsMouseOver, etc.) -->
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Then you can just use it like this:

<my:ImageButton Image="Image.png" />

If you need more images for different states of the button, you can add more dependency properties to the control.

Another possible approach is to use what I call a "parameterized style", to avoid creating a specific control; see this blog post for details.


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

...