2

私は MVVM を試していますが、それについて完全に理解することはできません。

いくつかの繰り返しコントロールを持つビュー (ウィンドウ) があります。

テキストボックスとボタンのペアが 4 つあるとします。ボタンを押した後、ペアになったテキストボックスは「Hello World!」と表示されます。

考えられるいくつかのオプションを試しました:

  1. 1 つの ViewModel、テキスト ボックスにバインドされた 4 つの文字列プロパティ、1 つのコマンド
    • 各ボタンを同じコマンドにバインドすると、どのプロパティを設定する必要があるかわかりません。
    • enum を CommandParameter に渡すのは厄介です。
  2. テキストボックスとボタンをホストする 1 つの ViewModel と UserControl が 4 回繰り返されます。
    • ここで、Command、CommandParameter、Text などのすべてのプロパティを公開する必要があります。大変な作業のようです。
    • クリック後にどのプロパティを更新する必要があるかはまだわかりません。
  3. 各 UserControl には ViewModel があります
    • これにより、ボタンのクリックとプロパティの設定が解決されますが、ネストされたViewModelからウィンドウViewModelにテキストを抽出する方法がわかりません。

他に方法はありますか?DataTemplates が役立つ可能性があると思われますが、その方法がわかりません。

4

3 に答える 3

2

あなたが説明しているのは、MVVMを保証しないほど抽象的で不自然なアイデアです。あなたはTextBoxes とについて話しているのですがButtons、これらはすべて「ビュー」であり、MVVM の考え方ではありません。ほとんどの場合、モデルから始めます。

ただし、ここには「モデル」自体はありません。あなたの仕様は、文字通りクリックTextBox時に aの値を設定することです。Button「4」個のアイテムの一見ランダムなリスト (どこからともなく選ばれた) と、一見役に立たないように見えるアイテムは、TextBox何の意味もありません。

それはさておき、4 つのビジネス エンティティのセットがあり、それぞれにユーザーが編集可能なフィールドがあり、ユーザーがトリガーできるアクションがあると仮定すると、次のようになります。

  • アイテムを表す ViewModel クラスを作成します。MyItemModel
  • アイテムのセットを表すViewModelクラスを作成します(おそらく最初のコレクションを返すだけです)-例AllMyItemsListModel

次に、ビューの場合:

  • 2 番目の ViewModel クラスの「コレクション」のインスタンスにバインドされたItemsControlを作成しますItemsSource
  • ごとItemTemplateに、テンプレートを用意するかUserControl、アイテムごとに
  • テンプレート または 内で、の Text プロパティを最初のクラスの適切なプロパティにUserControlバインドします。TextBox
  • を返す最初のクラスのプロパティにButtonのプロパティをバインドします-たとえば、CommandICommandRelayCommand

「ネストされたViewModelからウィンドウViewModelへのテキストの抽出」についてあなたが何を意味するのかわかりません-それはどういう意味で、なぜそれをしたいのですか?

それが役立つことを願っています。

于 2010-07-23T19:35:34.523 に答える
1

番号3。viewmodelを持つUserControlが1つだけで、そのUserControlの複数のインスタンスが含まれるメインページがあることを除いて。メインウィンドウにUserControlからの情報が必要な場合は、イベントを通過させるか、MVVMLightなどのメッセンジャークラスを使用できます。

于 2010-07-23T17:27:17.173 に答える
1

このような単純な動作をする再利用可能なコントロール用に、個別のViewModelを作成する必要はありません。いくつかのDependencyPropertiesとイベントハンドラーを単純なUserControlに追加するだけで、ロジックを再利用して、インスタンスごとに実際に異なるプロパティのみを設定できます。UserControl XAMLの場合は、TextBoxをDependencyPropertyに接続し、ButtonをClickハンドラーに接続する必要があります。

<DockPanel>
    <Button Content="Reset" Click="Button_Click"/>
    <TextBox Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=Text}"/>
</DockPanel>

UserControlのコードは、外部でバインドできるプロパティと、テキストをリセットするためのハンドラーを定義する必要があります。

public partial class ResetTextBox : UserControl
{
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text",
        typeof(string),
        typeof(ResetTextBox),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty ResetTextProperty = DependencyProperty.Register(
        "ResetText",
        typeof(string),
        typeof(ResetTextBox),
        new UIPropertyMetadata(String.Empty));

    public string ResetText
    {
        get { return (string)GetValue(ResetTextProperty); }
        set { SetValue(ResetTextProperty, value); }
    }

    public ResetTextBox()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Text = ResetText;
    }
}

次に、コントロールを使用するには、ViewModel文字列プロパティにバインドし、ここでハードコーディングするか、他のVMプロパティにバインドできるリセット時に適用するデフォルトのテキストを設定する必要があります。

<StackPanel>
    <local:ResetTextBox ResetText="One" Text="{Binding Name1}"/>
    <local:ResetTextBox ResetText="Two" Text="{Binding Name2}"/>
    <local:ResetTextBox ResetText="Three" Text="{Binding Name3}"/>
</StackPanel>
于 2010-07-23T22:53:24.543 に答える