【问题标题】:Context-sensitive command with MVVM带有 MVVM 的上下文相关命令
【发布时间】:2012-08-29 02:08:36
【问题描述】:

我有一个自定义组件,它基本上是一个带有附加按钮的文本框。该按钮应该对文本框执行操作;例如单击按钮可以用一些随机字符串填充文本框。

文本字段绑定到 ViewModel 中的属性。基本上是这样的:

设置对组件通用的命令的最佳方法是什么?

到目前为止,我所做的是在我的 ViewModel 中有一个通用的RelayCommand,它需要一个参数。每个按钮都将其命令设置为该单个命令,我使用CommandParameter 属性添加一些关于我实际谈论的文本字段组件的信息。然后 ViewModel 使用该信息找出正确的属性并更改其值(通过绑定更新文本框)。

虽然这很好用,但我不喜欢我必须手动插入有关相关文本框或 context 的信息。理想情况下,我希望在已经知道它正在谈论哪个文本框或绑定属性的上下文范围内执行命令。有没有办法做到这一点?

我遇到的另一个问题是我想将按钮操作绑定到键盘命令。所以当我关注一个文本框并按下一个快捷键时,我希望它表现得就像我点击了正确按钮,即执行命令并传递正确的上下文信息。我的替代方法是将其放入代码隐藏中,基本上从当前焦点中提取命令参数,但我更喜欢更简洁的解决方案。

有没有什么好的方法可以使用 MVVM 进行这项工作?

【问题讨论】:

    标签: c# wpf mvvm key-bindings relaycommand


    【解决方案1】:

    这样的事情怎么样:

    public class TextBoxAndCommandPresenter : INotifyPropertyChanged
    {
        private readonly Action<TextBoxAndCommandPresenter> _action;
    
        public TextBoxAndCommandPresenter(string description,
                                          Action<TextBoxAndCommandPresenter> action)
        {
            Description = description;
            _action = action;
        }
    
        public string Description { get; private set; }
        public string Value { get; set; }
        public ICommand Command
        {
            get { return new DelegateCommand(() => _action(this)); }
        }
    }
    

    这样使用:

    var presenter = new TextBoxAndCommandPresenter("Field 1",
                                                   p => p.Value = "hello world");
    

    使用 XAML:

    <UserControl ...>
        <UserControl.Resources>
            <DataTemplate DataType="{x:Type TextBoxAndCommandPresenter}">
                <StackPanel Orientation="Horizontal">
                    <Label Content="{Binding Description}"/>
                    <TextBox Text="{Binding Value}"/>
                    <Button Command="{Binding Command}">Click</Button>
                </StackPanel>
            </DataTemplate>
        </UserControl.Resources>
    
        <ContentPresenter Content="{Binding}"/>
    </UserControl>
    

    【讨论】:

    • 嗯,你知道如何解决按键绑定的问题吗?
    • 您可以在演示者上添加一个 IsSelected 标志,然后在父演示者上添加一个命令,该命令在 IsSelected 设置为 True 的演示者上调用 Command 并将按键绑定到那个。
    【解决方案2】:

    由于我已经为文本框和按钮组合创建了一个自定义控件,因此创建 UserControl 对我来说并不是一个必要的选项。我的控件为按钮的命令和命令参数公开了可绑定属性,现在,我坚持我在问题中解释的内容;使用命令参数更新视图模型中的相应属性,然后通过数据绑定进行更新。

    根据以后重复的程度,我可能会将其封装在多个自定义控件中,或者构建一个类似 Scroog1 所示的帮助器。

    至于键盘命令,这实际上是我最关心的问题,我意识到这最终是视图单独处理的事情。所以我的视图模型完全忘记了键盘命令。

    我知道有一个标准命令绑定到窗口的代码隐藏,它查找当前聚焦的元素,检查它是否属于我的自定义控件类型,然后简单地执行底层命令。因此,代码隐藏本质上只是将命令执行委托给焦点控件。

    虽然这不是一个完美的解决方案,因为我宁愿对命令有一些实际的“上下文敏感性”,但这目前工作正常,并且仍然可以正确地将视图与逻辑分开。

    【讨论】:

      猜你喜欢
      • 2013-03-09
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 2011-04-19
      • 2016-07-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多