0

WPF アプリの MVVM パターンとコマンドに問題があります。問題はMVVMパターンではなく、私のGUIで起こっていることです。状況を説明します:

私のアプリは、いくつかのファイルに DoStuff できます。function を持つクラスがありますDoStuff(int limit)。ユーザー インターフェイスには次の項目があります。

  • AButton DoStuffBtn解析を開始します。
  • ATextBox LimitTxt制限を埋めること。
  • ACheckBox LimitChk制限を有効または無効にします。

「チェックを外す」LimitChk場合は、LimitTxt.Text = ""LimitTxt.IsEnabled = false. 「チェック」LimitChkすると、LimitTxt.IsEnabled = false再び、何かを入力するまでテキストは空のままになります。

私は WPF と MVVM のコマンドに関する多くのチュートリアルを読みましたが、自分のケースをその型に注ぎ込むことができないようです。私が示した例は、実際には私の UI のほんの一部にすぎませんが、これもうまくできないようです。

次のような質問に出くわします。

  • 2 つ(有効化と無効化) または 1 つだけ (切り替え)Commandsが必要ですか?LimitChk
  • inttoをバインドする場合LimitTxt、空にして無効にするとどうなりますか?
  • が押されDoStuff(Int32.Parse(LimitTxt.Text))たときに使用するのはきれいな方法ですか?DoStuffBtn
  • で 2 つのコマンドを使用するLimitChkと、有効かどうかを判断するのCanExecute()機能はどうなりますか?ICommandLimitChk

したがって、主な質問は次のとおりです。私が説明した状況は、WPF でコマンドを使用する適切なパターンにどのように適合しますか?

私が見たWPF、コマンド、およびMVVMに関するいくつかのリンク:


これまでのところ、私が理解しているのは、UI から可能な限り遠ざけなければならないということです。UIに影響を与えるUIのようなものでさえ。つまり、チェックを外すとLimitChk無効になりますLimitText。それでも、UI 関連の情報と、実際に行わなければならない実際の作業に関係するアクションとの間の違いを維持する必要があると思います。

4

2 に答える 2

3

混乱していると思います...ここではコマンドは必要ありません。バインディングを使用するだけです。

  • LimitChk には 2 つのコマンド (有効化と無効化) が必要ですか、それとも 1 つだけ (トグル) が必要ですか?

何も必要ありません。LimitEnabledViewModel でプロパティを作成し、それにバインドCheckBoxするだけです ( IsChecked="{Binding LimitEnabled}")

  • int を LimitTxt にバインドする場合、空にして無効にするとどうなりますか?

無効にしても効果はありません。空にするTextBoxと、空の文字列を int に変換できないため、バインディングは失敗します (少なくともデフォルトのコンバーターでは変換できません)。

  • ParseBtn が押されたときに Parse(Int32.Parse(LimitTxt.Text)) を使用するのはきれいな方法ですか?

その必要はありません。LimitViewModel でプロパティを作成し、それにバインドTextBoxするだけです。に を追加しExceptionValidationRuleて、Binding無効な入力を強調表示することができます。

ボタンは必要ありません。解析は、 がフォーカスを失ったときに自動的に行われますTextBox(デフォルトの を使用する場合UpdateSourceTrigger)。解析方法をカスタマイズする場合は、バインディングで使用するカスタム コンバーターを作成できます。

于 2010-01-22T16:52:05.040 に答える
1

色や配置の属性、WrapPanels などの余分なものを除外して、いくつかの高レベルの考えを示します。

ViewModel にはいくつかのプロパティがあります。

public bool? LimitIsChecked { get; set; }
public bool LimitTextIsEnabled { get; set; }  //to be expanded, below
public ICommand ParseCommand { get; private set; } // to be expanded, below
public string LimitValue { get; set; } // further explanation, below

XAML には、次のような CheckBox と TextBox の定義があります。

<CheckBox Content="Limit Enabled" IsChecked="{Binding LimitIsChecked}" />
<TextBox Text="{Binding LimitValue}" IsEnabled="{Binding LimitIsEnabled}" />
<Button Content="Parse" Command="{Binding ParseCommand}" />

ParseCommand を次のように初期化する必要があります。

this.ParseCommand = new DelegateCommand<object>(parseFile);

それでは、その LimitTextIsEnabled プロパティも入力しましょう。

public bool LimitTextIsEnabled {
    // Explicit comparison because CheckBox.IsChecked is nullable.
    get { return this.LimitIsChecked == true; }
    private set { }
}

メソッドは、実際の解析を行うロジックparseFileにプロパティの値を渡します。LimitValue

LimitValueここでは、明示的なコンバーターやその他の検証コードでコードが煩雑になるのを避けるために、プロパティを文字列として宣言しました。「LimitValue は有効な int です」という検証/変換をいくつかの異なる方法で処理することを選択できます。

もちろん、これを完全に実装したわけではありませんが、他のウィジェットの状態を更新するためにコマンドを使用していないパターンを概説したかったのです。代わりに、これらの属性を ViewModel で管理されているプロパティにバインドします。

于 2010-01-22T16:56:24.853 に答える