使用MVVM的上下文相关命令

时间:2012-09-04 12:02:34

标签: c# wpf mvvm key-bindings relaycommand

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

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

Three custom components with an attached button each

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

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

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

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

有没有什么好方法可以让它与MVVM一起工作?

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

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

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

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

我知道有一个标准命令绑定到窗口的代码隐藏,它查找当前关注的元素,检查它是否是我的自定义控件的类型,然后只是执行底层命令。因此代码隐藏实际上只是将命令执行委托给集中控件。

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

相关问题