7

アップデート

StackOverflow の wiki の精神では、ここに更新があります。

以下に、Joe White の IValueConverter の提案をスパイクしました。それは魅力のように機能します。

これの「クイックスタート」の例を書きました。これは、安価な文字列置換を使用して、ViewModels->Views のマッピングを自動化します。ViewModel を表す View が見つからない場合、デフォルトで「Under Construction」ページが表示されます。Joe White のアイデアだったので、このアプローチを「WPF MVVM White」と呼んでいます。ここにいくつかのスクリーンショットがあります。

最初の画像は、純粋な命名規則に基づいて、「[SomeControlName]ViewModel」に対応する「[SomeControlName]View」がある場合です。2 つ目は、ModelView にそれを表すビューがない場合です。ViewModel から View への長いマッピングを持つ ResourceDictionaries はもうありません。現在は純粋な命名規則です。

Wpf Mvvm ホワイト

ここにプロジェクトのダウンロードを投稿しました: Mvvm.White.Quickstart.zip


元の投稿

週末、WPF MVVMに関するJosh Smith の素晴らしい MSDN 記事を読みました。カルトクラシックになる運命にあります。

ViewModelをレンダリングするように WPF に要求するという魔法に頭を悩ませるのに、しばらく時間がかかりました。

「これがクラス、WPF です。それを表示するために使用する UI を見つけてください」と言っているようなものです。

この魔法を逃した人のために、WPF はResourceDictionary マッピングでModelViewのViewを検索し、対応するViewを引き出すことでこれを行うことができます。(下にスクロールして、図 10 ビューの提供)。

最初にすぐに思いつくのは、次の強力な命名規則が既に存在することです。

classNameView  ("View" suffix)
classNameViewModel ("ViewModel" suffix)

私の質問は:

ResourceDictionaryはプログラムで操作できるので、だれかが Regex.Replace に成功したかどうか疑問に思っています。そのため、ルックアップは自動的に行われ、新しい View/ViewModel は命名規則によって解決されますか?

[編集] 私が想像しているのは、ResourceDictionary へのフック/傍受です。

...また、相互運用機能を使用してプルアウトし*View$*ViewModel$クラス名を使用してコードで DataTemplate ディクショナリを構築する起動時のメソッドを検討します。

//build list
foreach ....
    String.Format("<DataTemplate DataType=\"{x:Type vm:{0} }\"><v:{1} /></DataTemplate>", ...)
4

2 に答える 2

17

コードを明示的に ResourceDictionary に追加するのではなく、必要に応じて適切なビューを生成するだけではどうですか? これは、ValueConverter を使用して行うことができます。

リソースは次のようになります。

<Views:ConventionOverConfigurationConverter x:Key="MyConverter"/>
<DataTemplate DataType="{x:Type ViewModels:ViewModelBase}">
    <ContentControl Content="{Binding Converter={StaticResource MyConverter}}"/>
</DataTemplate>

DataTemplate リソースは引き続き必要ですが、すべての ViewModel に共通の基本クラスがある限り、それらすべてを処理するために必要な DataTemplate は 1 つだけです。

次に、値コンバーター クラスを定義します。

public class ConventionOverConfigurationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        // value is the ViewModel. Based on its GetType(), build a string
        // with the namespace-qualified name of the view class, then:
        return Activator.CreateInstance(Type.GetType(viewName));
    }
    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

必要なのは、Convert 内にロジックを記述することだけです。これは、View と ViewModel が同じ名前空間にあるかどうかなどに依存します。

于 2009-04-25T16:53:06.530 に答える
-1

ほとんど同じことを行うことにしたので、DataTemplates を直接 ResourceDictionary にロードします。

    private void RegisterResources()
    {
        ResourceDictionary dictionary = new ResourceDictionary();
        dictionary.Source = new Uri("pack://application:,,,/StartupModule;Component/UIResources.xaml");
        Application.Current.Resources.MergedDictionaries.Add(dictionary);
    }

ここで、UIResources ファイルは、すべての DataTemplates を含む ResourceDictionary xamls ファイルです。

于 2009-05-01T14:55:03.190 に答える