1

我有一个用户控件,说一个我想在其他几个控件中重用的键盘。键盘响应 INotifyPropertyChanged 但我想捕获父控件中的更改以更新其中的文本框。

我试图从父视图模型访问控件,但这不是使用 MVVM 执行此操作的正确方法。

任何想法表示赞赏。

4

2 回答 2

0

我认为你有点混淆了想法。

MVVM 方式是有两个视图模型和两个视图。

MasterControlViewModel&MasterControlView

KeypadControlViewModel&KeypadControlView

MasterControlViewModel将订阅在KeypadControlViewModel.

但是,您似乎推断这KeypadControl只是一个标准控件,没有自己的视图模型。考虑到它与视图的密切关系(它提供键盘输入,插入取决于光标所在的位置等),这将是有意义的。如果是这种情况,拥有一个“目标”依赖属性可能更合适,KeypadControl该属性可以绑定到MasterControlView. 当一个键被点击时,它KeypadControl只是更新目标控件,或者,可能更好的是,它可以触发键盘 RoutedEvents,它会像真正的键盘事件一样沿着可视化树向上移动,从而不需要目标属性。

这样,您的所有输入内容都会在视图中处理,并且MasterControlViewModel唯一关心的是字符串已更改的事实。

于 2012-11-13T08:45:51.493 回答
0

我想说,如果你想做 MVVM 风格,那么键盘控件应该公开一个 ICommand 属性,命令本身由父级提供,并在单击某个键时执行该命令。

该命令将获取在命令参数中单击的键。

实际的命令实现将在父控件中(您可以为此使用RelayCommand 模式),然后可以更新其 TextBox。

键盘类应包括如下内容:

class Keypad : UserControl
{
     ...
     public DependencyProperty OnKeypadKeyClickedCommandProperty = ... ;
     ...
     void OnZeroButtonClicked(object sender, RoutedEventArgs e)
     {
         OnKeypadKeyClickedCommand.Execute(this, new SomeKeyIdentifier('0'));
     }
     ...
}

XAML 应包括如下内容:

<local:Keypad OnKeypadKeyClickedCommand="{Binding HandleKeypadKeyClickCommand, ElementName=parentControlName}" />

父控件中的实现应该是这样的:

class ParentControl : ...
{
    DependencyProperty HandleKeypadKeyClickCommand = ...;

    void Init()
    {
        HandleKeypadKeyClickCommand = new RelayCommand(new Action<SomeKeyIdentifier>(DoKeyPress));
    }
    ...
    void DoKeyPress(SomeKeyIdentifier key)
    {
         _Textbox.Text += key.Char;
    }
    ...
}
于 2012-11-13T08:28:08.013 回答