他のいくつかのコントロールで再利用したいキーパッドと言うユーザーコントロールがあります。キーパッドは INotifyPropertyChanged に応答しますが、親コントロールの変更をキャプチャして、その中のテキスト ボックスを更新したいと考えています。
親ビューモデルからコントロールにアクセスしようとしましたが、これは MVVM でこれを行う正しい方法ではありません。
どんな考えでも大歓迎です。
あなたはアイデアを少し混ぜていると思います。
MVVM の方法は、2 つのビューモデルと 2 つのビューを持つことです。
MasterControlViewModel
&MasterControlView
KeypadControlViewModel
&KeypadControlView
MasterControlViewModel
で発生した主要なイベントをサブスクライブしますKeypadControlViewModel
。
KeypadControl
ただし、独自のビューモデルを持たない、単なる標準コントロールであると推測しているようです。ビューとの密接な関係を考えると、これは理にかなっています (挿入はカーソルの場所などに依存するキーボード入力を提供します)。このような場合はKeypadControl
、MasterControlView
. キーがクリックされるとKeypadControl
、ターゲット コントロールが更新されるか、実際のキーボード イベントのようにビジュアル ツリーを移動するキーボード RoutedEvents が起動され、ターゲット プロパティが不要になります。
このようにして、すべての入力内容がビューで処理されMasterControlViewModel
、文字列が変更されたという事実だけが気になります。
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;
}
...
}