9

詳細を説明するケースの例を次に示します。

ビューで ItemsControl を使用して単純な棒グラフを動的に作成し、BarGraphViewModel で項目を BarViewModels (それぞれパーセンテージ値を含む) のコレクションにバインドしています。各バーは異なる色にする必要があります。色はコレクションから選択する必要があります。{Color1, Color2, ..}

コレクション自体は一定ですが、バーの数は状況によって異なります。

簡単な解決策は、次のような単純な BarViewModel を作成することです。

public class BarViewModel
{
    public int Percentage { get; set; }

    public SolidColorBrush Stroke { get; private set; }

    public BarGraphViewModel(SolidColorBrush stroke)
    {
        Stroke = stroke;
    }
}

(簡潔にするために、変更されたプロパティと検証の実装を省略しました)

これで、BarGraphViewModel からパーセンテージごとに BarViewModels を作成し、Color コレクションから作成した適切な ColorBrush を渡すことができました。

次に、Xaml で、これらのプロパティにバインドする単純な ItemsTemplate を作成します。

今だけ、SolidColorBrush 型のプロパティが含まれているため、ViewModel はプレゼンテーション フレームワークに依存しており、別の環境で使用する必要がある場合は変更する必要があります。

したがって、これはMVVMのベストプラクティスを破っていますか、それとも許容できますか(どこかで線を引くか、物事が複雑になりすぎます)

他の人がこれについてどう思うか、また複雑になりすぎずにViewModelがプレゼンテーションレイヤーを完全に認識しないようにする他のソリューションがあるかどうかを知りたかっただけです。ValueConverters が役立つと想像できますか?

4

3 に答える 3

9

Martin Fowler によって記述された元のプレゼンテーション モデル パターンでは、ビューはビューモデルにそれ自体を表示する方法を「尋ねます」。これは、ビューにトリガーするのではなく、ビューモデルに色とサイズのプロパティを配置することを好むようです。ただし、WPF 内でのこのパターンの適用は多少異なります。WPF では、通常、ビューで Styles と DataTemplates を使用して、ビューの外観を定義します。ビューモデルから特定の色を直接返すことは、このアプローチに反します。したがって、短い答えは次のとおりです。いいえ、ビューモデルに色のプロパティを設定しないでください。

また、元のプレゼンテーション モデル パターン内では、ビュー モデルはビューの抽象化です。したがって、正確な色を返す代わりに、ビューが実際の色を検索するために使用できる「キー」を返すことが望ましいでしょう。たとえば、PersonViewModel.FaceColor が Red を返す代わりに、PersonViewModel.Mood が Angry を返すようにします。ビューは、これを実際の赤色に変換する Style または DataTemplate トリガーを使用できます。

それが私の答えであり、私はそれに固執していますが、反対方向の議論を検討することも興味深いです. 1 つには、ビュー モデルに色のプロパティを配置することはまだ単体テスト可能であり、これはビュー モデルで何が問題ないかの主要な基準になっているようです。

ビュー技術に「とらわれない」ままでいることは、どちらの方向にも大きな要因ではありません。ビュー モデルと他のビュー テクノロジとのバイナリ互換性を維持するという目標は、XAML ファミリ内でのみ現実的です。すべてのビュー モデルを、WPF に直接依存しない独自のプロジェクトに移動するのは良い考えです。ただし、ICommand を使用するものはすべて除外するか、WindowsBase.dll 参照の例外を作成する必要があります。ただし、実際には、それほど多くはありません。私たちは、Microsoft の技術にほぼ釘付けです! 別の GUI フレームワークに移植する場合は、ソース コードの変換を検討していると思います。試してみる前に Microsoft がダウンするかどうかを確認するのを待っています ;) 移植には、ビューモデルに配置することにした場合、色の種類の変更が含まれる可能性があります。

于 2011-11-30T22:50:38.703 に答える
8

理論的には、あなたが説明した状況はMVVMのベストプラクティスに反しています。しかし、ビュー モデルをクリーンアップするための簡単な解決策があります。ビュー モデルで色を表す独自の型を作成する必要があります。文字列、int、または列挙型にすることができます。次に、カスタム ValueConverter (IValueConverter を実装) を記述して、ビュー モデルの色の種類をプレゼンテーション フレームワークに依存する色表現に変換できます。コンバーターは境界式と一緒に使用する必要があります。バインドされた値を変換する例はこちらです。

于 2009-12-13T14:30:20.597 に答える
2

上記のVMが悪いという技術的な理由はわかりませんBrushが、特定のサブクラスではなく個人的に使用します。VM はビューのモデルであるため、これが MVVM のベスト プラクティスに違反するとは思いません。ビューが構築されているテクノロジーに必ずしも依存している必要はありません。

ただし、それが悪い考えである理由は他にもあります。ビュー モデルは非 WPF 環境で使用される可能性がありますか? もしそうなら、プラットフォーム固有の構造に変換できる抽象化が必要になるでしょう。WPFBrushはそのような例の 1 つです。また、これには必ずしもコンバーターが必要なわけではありません。抽象化自体をビュー モデルにすることができ、それにはプラットフォーム固有のサブクラスがあります。たとえば、Colorビュー モデルとそれをWpfColor継承するビュー モデルがあるとします。

チームにデザイナーはいますか?その場合、VM で を使用するとBrush、UI をカスタマイズする機能が阻害される可能性があります。上記の特定のケースは外れ値かもしれませんが、一般的に言えば、デザイナーと開発者のコ​​ラボレーションは、VM が状態を公開し、ビューがその状態をレンダリングすることでメリットがあります。VM が何らかの形で視覚的な外観を決定するとすぐに、デザイナーが下す決定が制限されます。

私の経験では、2 番目の理由は、VM に UI 固有の構成要素を含めないという、はるかに一般的な理由です。

于 2009-12-13T17:54:42.763 に答える