5

私は今日、WPF プログラムでロジックを処理する方法の設計パターンを選択することについて誰かと話し、SO コミュニティが決定を容易にするためのさらなるアドバイスを提供してくれることを望んでいました。コマンドを支持する要因は、不便さを上回っていますか?

3 つのアプローチのうち最初の 2 つのUML ダイアグラムとともに完全なサンプルを用意しました。

  1. ボタンとメニューで Click イベント ハンドラーを使用します。
  2. XAML にバインドされたコマンドを使用します。
  3. コードにバインドされたコマンドを使用し、純粋な GUI レイアウトとスタイリングのために XAML を保持します。

彼が受講した入門コースや多くの書籍では、ロジックを UI オブジェクトに接続する自然な方法として単純な Click イベント ハンドラーが示されています。

彼は、コマンドを使用するために必要なオーバーヘッドの量に少し驚いていました。両方のコマンドがコード ビハインド ファイルで作成されています。

public static readonly ICommand cmdShow2 = new RoutedUICommand(
  "Show Window2", "cmdShow2", 
  typeof(TestDespatchWindow));

次に、コマンドを識別してバインドする必要がある冗長な方法を使用して、XAML 内にさらに多くのコードを記述します。

<Window x:Class="WPFDispatchDemo.TestDespatchWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:w="clr-namespace:WPFDispatchDemo"..>

    <Window.CommandBindings>
      <CommandBinding Command="{x:Static w:TestDespatchWindow.cmdShow2}"
        Executed="OnShow2" />
    </Window.CommandBindings>
      <DockPanel>
        <StackPanel Margin="0,8,0,0">
          <Button x:Name="Show2EventBased" 
                  Margin="10,2,10,2" 
                  Click="OnShow2" 
                  Content="Show2 via WPF Event"/>
          <Button x:Name="Show2Command" 
                  Command="{x:Static w:TestDespatchWindow.cmdShow2}"
                  Margin="10,2,10,2" 
                  Content="Show2 via WPF"/>
        </StackPanel>
    </DockPanel>
  </Window>

私は (まだ) WPF の専門家であるとは言えないので、実際よりも複雑に描いているかもしれませんが、上記よりもはるかに単純化することはできないのではないかと疑っています。

編集:

DelegateCommand、RoutedCommand、および Eventの興味深い3 方向の比較を見つけました。

4

4 に答える 4

6

それぞれの長所と短所を考慮して、状況に応じて選択する必要があります。ケースごとに選択することを強くお勧めします。プロジェクト全体で「唯一の正しい方法」を選択しないでください。

場合によっては、送信側と受信側を分離し、XAML のみを使用してコマンドを送信できることが大きな利点となります ( http://msdn.microsoft.com/enで、ScrollBar コントロール テンプレートがコントロール ロジックと通信する方法を参照してください)。 -us/library/ms742173.aspx )。

他のケースでは、コマンドは、アプリケーション内の 4 つの別々の場所を変更することを含む、2 行のイベント ハンドラーであったものを、追跡不可能な怪物に変えることができます ( ViewModel はフォームをどのように閉じる必要がありますか? )。

于 2009-02-18T09:04:25.863 に答える
3

唯一の理由は、コマンドのレジストリをよく知っていることです。イベントはプライベート メソッドである可能性が高く、ウィンドウのコードと密接に結びついていると感じます。同時に、コマンドは実装 (イベント) と定義 (コマンド) を別々に保持する機能を提供します。別のクラスを使用することもできます (ApplicationCommands を見てください)。

さらに、WPF の作業を行っているときは、ICommand( Command Pattern ) の実装を使用します。コマンドのすべてのロジックは、Execute メソッドに渡されます。これにより、ウィンドウ コードを過度に複雑にすることなく、より構造化された方法でロジックを分離し続けることができます。このオプションを使用すると、モデルにコマンドを作成できるため、ノイズなしでそれらをバインドできます。見てください。

モデルを作成します。

public class Model
{
  ICommand CloseMessagePopupCommand {get; set;}
}

次に、データ コンテキストを割り当てます

public MainWindow()
{

  this.DataContext = new Model();
}

そして、次の XAML コードを使用します。

<Button 
    Command="{Binding CloseMessagePopupCommand}"
    Content="{StaticResource Misc.Ok}" />
于 2009-02-17T19:42:10.190 に答える
2

Andy の #2 と #3 のアプローチを組み合わせて使用​​して、Mike が WPF アプリケーションを開発するときに参照するコマンド パターンに忠実であり続けるようにしています。

私の見解では、コマンドの欠点は 1 つだけ考えられます。それは、特定の UI 要素の特定のアクションだけがコマンドを呼び出すことです。これを回避する 1 つの方法は、イベント ハンドラーでコマンドの Execute メソッドを呼び出すことです。コマンドは、実行ロジックをカプセル化するための非常に優れた方法を提供すると思います。UI の大部分を維持し、MVC/MVC/MVVM パターンを使用して実装すると、これは非常に明白になります。

DataModel-View-ViewModelパターンに関する Dan Crevier のシリーズ、特にコマンドとカプセル化コマンドに関するセクションを参照することをお勧めします。このパターンがニーズを満たさない場合でも、別のクラス内にロジックをカプセル化する方法の概要を説明しています。

于 2009-02-18T03:12:24.057 に答える
1

ICommand の他のバリエーションは、複雑なコマンド構造を実装する一般的な方法のようです。

Brian Noyes は、PRISM に関する記事で次のように述べています。

WPF のルーティング コマンドは非常に強力で便利ですが、複合アプリケーションに適用するといくつかの欠点があります。1 つ目は、それらがビジュアル ツリーに完全に結合されていることです。呼び出し元はビジュアル ツリーの一部である必要があり、コマンド バインディングはビジュアル ツリーを介して結び付けられている必要があります。... 2 つ目の欠点は、それらが UI のフォーカス ツリーと密接に結びついており、 CAL (Prism) に含まれる DelegateCommand と CompositeCommand について話し続けることです。

于 2009-02-20T08:01:01.583 に答える