2

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

文本字段绑定到 ViewModel 中的属性。它基本上看起来像这样:

三个自定义组件,每个组件都有一个附加按钮

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

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

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

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

有什么好方法可以使这个工作与 MVVM 一起工作吗?

4

2 回答 2

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>
于 2012-09-04T12:31:37.427 回答
0

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

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

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

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

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

于 2012-09-27T12:26:45.367 回答