web-dev-qa-db-ja.com

これらのユーザーコントロールが1回しか使用されない場合でも、ユーザーコントロールを使用してWPFフォームを構造化することは良い習慣ですか?

私はMVVMを使用してWPFアプリケーションを開発していて、最善の方法を学んでいます。

セレクター付きのWPFフォーム、検索フィールド付きの2つのリスト、およびその他の要素があります。現在、すべてが1つの形式になっており、機能します。しかし、今ではそのフォームのVMは800行を超えており、まだ完成していません。

このフォームとコードをよりよく構造化したい。リージョン、部分的なクラスとユーザーコントロールを含むファイルについて考えた。ユーザーコントロールは、いくつかのコントロールとロジックをカプセル化しているため、最善だと思う。もし私がユーザーコントロールを使用すると、そのウィンドウ内のコードの量とVMが大幅に削減されます。

これを正しく行うために、「Pro WPF 4.5 In C#4th Edition」という本の第18章-カスタム要素とColorPickerUserControlサンプルに取り組みます。サンプルは、3つのスライダーを備えたカラーピッカーに関するもので、150行のコードが含まれています。

私はそれがどのように機能するかを理解していると思いますそのサンプルのように非常に限られた機能でさえ、ユーザーコントロールを作成することは多くの作業であるように思えます。これらのコントロールを数回使用する場合、これを行うのが理にかなっていることを理解しています。しかし、コントロールを1回だけ使用し、これをフォームの構造化のみに使用する場合、これはほとんど利益を得るために多くの作業と思われます。

私の質問は、ユーザーコントロールを使用してフォームを構造化することは、これらのユーザーコントロールが1度しか使用されない場合でも良い習慣ですか?そうでない場合、より良い代替手段はありますか?

編集(読む必要はありません。詳細情報のみ):これまでは、原理について学びたいので詳細は書きませんでしたが、26の17の興味深い答えを読んだ後、ここにいくつかの詳細があります:これフォームは音楽のタイトルを選択することです。

  • グループA:(可能なユーザーコントロールA)は、アーティストまたはアルバムによる選択、ビデオの有無にかかわらず、おそらく発行年など、選択のタイプに関するものです。

  • グループB:このリストには、Aの基準に従ってフィルタリングされたアーティスト名が含まれています。ユーザーはリストをフィルタリングできます。つまり、「トップ」を含むアーティスト名のみを表示できます。

  • グループC:このリストには、Bで選択されたアーティストのタイトルが、Aの基準(オーディオまたはビデオ)を使用して表示されます。 Bと同様にフィルタリングできます。つまり、「あなた」を含むタイトルのみです。

ほとんどのロジックはVM(フォームのDataContext)で発生します。AとBのリストはデータベースから取得されます。リストはフィルタリングされ、プレゼンテーション用に準備されます(つまり、同じ名前は別のアルバムにあります。ユーザーは、Cリストのタイトルをダブルクリックして選択するか、別のWPFフォームにドラッグアンドドロップします。

欲しいもの:簡単に修正できるように、読みやすいコードが必要です。追加したい場合、つまり、別のフィルターを使用して、女性アーティストのみを表示する場合は、ユーザーに移動できればよいでしょう。コントロールA、男性および/または女性アーティストのチェックボックスを追加します。

現在の形式のXAMLは問題なく、適切に構造化されています。しかし、VMには上記のすべてのコードがあります。コンストラクタにあるもの、コマンドセクションにあるもの、プロパティとバッキングフィールドがあります。今でも見つけることができますが、コードがより構造化されていればより良いでしょうこれがユーザーコントロールについて考える理由です.

MVVMの背後にあるロジックは理にかなっていると思うので、私はMVVMをフォローしようとしています。しかし、私は理論的な実践の狂信的なファンではありません。 I.e. CodeBehindの5行またはVMの50行で何かを実行できる場合は、CodeBehindで実行する可能性があります。私の質問は、WPFで構造化フォームを作成する方法の原則です。上記で説明したフォームは良い例ですが、答えはこれからの1つに集中するのではなく、WPFフォームを構造化する方法、つまりユーザーコントロールを使用する(または使用しない)方法に集中する必要があります。

ユーザーコントロールが多くの作業を必要とする理由について:依存関係プロパティ、ルーティングされたイベントなどがあります。これはすべて、バッキングフィールドとINotifyを持つ「通常の」プロパティよりもはるかに複雑に思えます。しかし、依存関係プロパティ、ルーティングされたイベントなどに慣れる必要があるだけかもしれません。

8
Edgar

もちろん。単一のタスクを実行するために、クラスに関係の分離を適用してそれぞれを独自に配置するのと同じように、それは良い考えです。そのクラスのインスタンスは1つしか持てませんが、重要ではありません。最適化はプログラムのパフォーマンスの観点ではなく、組織とプログラム全体の「健康」の観点からです。

リージョンに配置されたとしても、ある日プログラムに戻って、数百ページのコードをスクロールする必要がないことを望んでいます(多くのコードを持つクラスのリージョンを使用することは、豚に口紅を付けるようなものです)仕方)。いつか別の場所で使用することを決定した場合でも、多くの問題なしに、優雅に使用できます。

親フォームへのアクセスをユーザーに制御させようとしないでください。この方法で行う場合は、イベントを使用して、親フォームをサブスクライバーとして、親に情報を伝えます。

7
Neil

これは実際のコードを見ずに答えるのは本当に難しい質問です。また、用語を少し混ぜています。ユーザーコントロールは、ViewModelとの1対1のマッピングではありません。

ユーザーコントロールには特定の目的があります。これらは、1つの単位として一緒に使用される複数のUI要素の構成です。ユーザーコントロールは、ビューのサブセクションです。これは、Viewがバインドされているロジックを含むViewModelとは大きく異なります。

XAMLを複数のユーザーコントロールに分割して、すべてが単一のViewModelによって駆動されるようにするのは理にかなっています。 XAMLとC#のコードを複数のView-VMペアに分割することは意味があるかもしれません。多分それをあなたが今持っているままにしておくことは理にかなっています。問題のコードを見ずに判別することは不可能です。

ここでの最終目標は何ですか?コードのサイズが実際の苦痛を引き起こしているのですか、それとも単に理論上の慣習に従うためですか?

XAMLビューのサイズまたはC#ViewModelのサイズを縮小しようとしていますか?これらは、WPF MVVMの世界では2つの非常に異なるタスクです。

VMの場合、800行はそれほど大きくはありません。これは、何らかの複雑なUIをサポートします。VMを分割すると、 ViewModelは、「この他のリストが空のときにこの機能を無効にする」などの決定を行います。そのような決定を複数のコンポーネントに分割しようとしても、多くの場合意味がなく、コードが複雑になります。

これで、VMで実行している作業がある可能性があります。これは、ViewModelロジックとは関係なく、簡単に独自のクラスに分割できます。これにより、コードの全体的な複雑さを増すことなく、ViewModel。

それは、「それは場合によって異なり、問題のコードを見ないと分からない」という非常に長い時間のかかった方法だったと思います。

4
17 of 26

アプリについて何も知らない私が姓フィールドの上に新しいフィールドを追加するか、いくつかのフィールドの順序を変更しなければならなかった場合...私はそれが簡単か、気が遠くなるでしょうか?

コンパイラーは間違ったリージョンに何かを置き忘れたかどうかをチェックしないため、リージョンを信頼しません

あなたが作成したものの上に人々が簡単に構築できるようにするために、ソフトウェアを開発する必要があります。

0
A Bravo Dev