【问题标题】:ICommand for Button Press AND Release in an MVVM styleMVVM 样式中用于按钮按下和释放的 ICommand
【发布时间】:2014-10-27 15:22:20
【问题描述】:

我很高兴使用ICommand 实现来处理按钮上的单个操作:

<Button Command="{Binding Path=ActionDown}">Press Me</Button>

ICommand 通过 RelayCommand 实现

但我无法找到一种简单的方法来为新闻发布操作(在 SO 和互联网上的其他地方)提供操作。 IE 我想做一些类似的事情,但我不知道该怎么做:

<Button PressCommand="{Binding Path=ActionDown}" ReleaseCommand="{Binding Path=ActionUp}">Press and Release Me</Button>

处理此类需求的正确 MVVM 方法是什么?

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    您可以使用System.Windows.Interactivity 中的EventTrigger 来触发事件命令

    <Button Content="Press Me">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                <i:InvokeCommandAction Command="{Binding Path=ActionDown}"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="PreviewMouseLeftButtonUp">
                <i:InvokeCommandAction Command="{Binding Path=ActionUp}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>
    

    您需要添加对System.Windows.Interactivity 的引用并定义命名空间

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    

    【讨论】:

    • 谢谢你,但是你如何将它包装成一个可重用的组件呢?一次性按钮很好,但我需要删除大约 20 个这样的按钮,所以我也在寻找减少剪切和过去的方法。
    【解决方案2】:

    您可以轻松地创建自己的扩展自 Button 的类,为 MouseDown 和 MouseUp 定义可绑定命令。

    例子:

    public class PressAndReleaseButton : Button
    {
        public static readonly DependencyProperty PressCommandProperty = DependencyProperty.Register(
            "PressCommand", typeof(ICommand), typeof(PressAndReleaseButton), new PropertyMetadata(null));
    
        /// <summary>
        /// The Press command to bind
        /// </summary>
        public ICommand PressCommand
        {
            get { return (ICommand)GetValue(PressCommandProperty); }
            set { SetValue(PressCommandProperty, value); }
        }
    
        public static readonly DependencyProperty ReleaseCommandProperty = DependencyProperty.Register(
            "ReleaseCommand", typeof(ICommand), typeof(PressAndReleaseButton), new PropertyMetadata(null));
    
        /// <summary>
        /// The Release command to bind
        /// </summary>
        public ICommand ReleaseCommand
        {
            get { return (ICommand)GetValue(ReleaseCommandProperty); }
            set { SetValue(ReleaseCommandProperty, value); }
        }
    
        /// <summary>
        /// Default constructor registers mouse down and up events to fire commands
        /// </summary>
        public PressAndReleaseButton()
        {
            MouseDown += (o, a) => 
                     {
                         if (PressCommand.CanExecute(null)) PressCommand.Execute(null);
                     }
            MouseUp += (o, a) => 
                     {
                         if (ReleaseCommand.CanExecute(null)) ReleaseCommand.Execute(null);
                     } 
        }
    }
    

    【讨论】:

    • 我知道你要去哪里,但这不是要绕过CanExecuteRelayCommand 部分吗?
    • 糟糕,我在这方面有点太快了。你可以自己打电话给CanExecute,让我更新事件处理程序
    • 完成。在这种情况下,我假设没有参数(因此在 Execute 的参数中为 null),但如果需要,您当然可以使用任何/绑定它们(例如创建 PressCommandParameter 依赖属性)
    • 除了MouseUp/MouseDown += 上缺少逗号之外,用户控件不会响应MouseUp/MouseDown。但是他们确实回复了PreviewMouseUp/PreviewMouseDown
    猜你喜欢
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多