在 WPF UserControl 中附加 ICommand [英] Attach ICommand in WPF UserControl

查看:20
本文介绍了在 WPF UserControl 中附加 ICommand的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现了一个带有图像的简单按钮:

I implemented a simple button with an image in it:

    <Button Command="{Binding ButtonCommand, ElementName=ImageButtonControl}">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding ButtonImage, ElementName=ImageButtonControl}"/>
            <TextBlock Text="{Binding ButtonText, ElementName=ImageButtonControl}" Margin="2,0,0,0"/>
        </StackPanel>
    </Button>

如您所见,我公开了一个 ButtonCommand 属性,以便能够将 ICommand 附加到此 UserControl:

As you can see, I expose a ButtonCommand property in order to be able to attach an ICommand to this UserControl:

public partial class ImageButton : UserControl
{
    /// <summary>
    /// The dependency property that gets or sets the source of the image to render.
    /// </summary>
    public static DependencyProperty ImageSourceProperty = 
        DependencyProperty.Register("ButtonImage", typeof(ImageSource), typeof(ImageButton));

    public static DependencyProperty TextProperty =
        DependencyProperty.Register("ButtonText", typeof(string), typeof(ImageButton));

    public static DependencyProperty ButtonCommandProperty =
        DependencyProperty.Register("ButtonCommand", typeof(ICommand), typeof(ImageButton));

    public ImageButton()
    {
        this.DataContext = this;
        InitializeComponent();
    }

    /// <summary>
    /// Gets or sets the button command.
    /// </summary>
    public ICommand ButtonCommand
    {
        get { return (ICommand)GetValue(ImageButton.ButtonCommandProperty); }
        set { SetValue(ImageButton.ButtonCommandProperty, value); }
    }

    /// <summary>
    /// Gets or sets the button image.
    /// </summary>
    public ImageSource ButtonImage
    {
        get { return (ImageSource)GetValue(ImageButton.ImageSourceProperty); }
        set { SetValue(ImageButton.ImageSourceProperty, value); }
    }

    /// <summary>
    /// Gets or sets the button text.
    /// </summary>
    public string ButtonText
    {
        get { return (string)GetValue(ImageButton.TextProperty); }
        set { SetValue(ImageButton.TextProperty, value); }
    }
}

然后当我声明我的按钮时,它会给出:

Then when I declare my button it gives this:

<uc:ImageButton Grid.Row="1" Grid.Column="0" ButtonCommand="{Binding AttachContextCommand}" ButtonImage="{StaticResource AssociateImage}" ButtonText="Associer"/>

badaboom,当我点击我的 ImageButton 时,什么都不会发生.当我用一个简单的按钮替换 ImageButton 时,会调用 ICommand.

And badaboom, nothing never happen when I click on my ImageButton. When I replace the ImageButton with a simple button, the ICommand is called.

我什至试图简单地扩展 Button 类并绑定一个 ICommand,但再一次,它不起作用......

I even tried to simply extends the Button class and bind an ICommand, but once again, it didn't work...

感谢帮助!

谢谢.

推荐答案

您可以使用样式和几个附加属性以更简洁的方式实现此目的.

You can achieve this in a much cleaner way using a style and a couple of attached properties.

附加的属性将存储您的特定信息.样式将使用这些属性并构建您想要的外观.

The attached properties will store your specific information. The style will use these properties and build the look you want.

该元素仍将是一个按钮,因此命令和其他一切都将起作用.

The element will still be a button so the command and everything else will work.

 public class ImageButton
    {

        public static ImageSource GetImage(DependencyObject obj)
        {
            return (ImageSource)obj.GetValue(ImageProperty);
        }

        public static void SetImage(DependencyObject obj, ImageSource value)
        {
            obj.SetValue(ImageProperty, value);
        }

        public static readonly DependencyProperty ImageProperty =
            DependencyProperty.RegisterAttached("Image", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata(null));

        public static String GetCaption(DependencyObject obj)
        {
            return (String)obj.GetValue(CaptionProperty);
        }

        public static void SetCaption(DependencyObject obj, String value)
        {
            obj.SetValue(CaptionProperty, value);
        }

        public static readonly DependencyProperty CaptionProperty =
            DependencyProperty.RegisterAttached("Caption", typeof(String), typeof(ImageButton), new UIPropertyMetadata(null));

    }

<Style TargetType="{x:Type Button}"
               x:Key="ImageButton">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="{Binding Path=(local:ImageButton.Image), RelativeSource={RelativeSource AncestorType={x:Type Button}}}" />
                            <TextBlock Text="{Binding Path=(local:ImageButton.Caption), RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
                                       Margin="2,0,0,0" />
                        </StackPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>   
        </Style>

然后您可以使用它来声明按钮:

You can then use this to declare buttons:

   <Button Style="{DynamicResource ImageButton}"
                        local:ImageButton.Caption="Foo" 
                        local:ImageButton.Image="..." />

注意:

我很确定通过模板"属性并使用 ControlTemplate 和 TemplateBindings 会更清晰,但这意味着在内容周围重新创建边框和其他内容,因此如果您只想定义一个默认的内容",我认为我的例子是可行的.

I'm pretty sure it would be cleaner to go through the "Template" property and use a ControlTemplate and TemplateBindings, but that would mean re-creating the border and other stuff around your content, so if you are looking to just define a default "Content", my example would be the way to go, I think.

这篇关于在 WPF UserControl 中附加 ICommand的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆