web-dev-qa-db-ja.com

DataModel(ViewModel)タイプを指定して、ViewModelオブジェクトを作成せずにXAMLエディターでデザイン時バインディングチェックを取得するにはどうすればよいですか?

次のようにDataContextを指定できます。

_<Window ... >
    <Window.DataContext>
        <MainViewModel />
    </Window.DataContext>
    ...
</Window>
_

この場合、WPFはMainViewModel型のオブジェクトを作成し、それをウィンドウのDataContextプロパティに割り当てます(これはWindowのInitializeComponent()メソッド内で発生します)。

しかし、私のViewModelにデフォルトのコンストラクタがない場合はどうなりますか。または、ViewModelを初期化し、Window.InitializeComponent()が実行された後にそれをDataContextに割り当てる場合(Windowのコンストラクタ内またはウィンドウをインスタンス化する同じコードから)-この場合、WPFはViewModelを作成します(InitializeComponent())、それをウィンドウのDataContextに割り当て、ViewModelの別のインスタンスで上書きします(ここでは不要なオブジェクトのインスタンス化が心配です)。

タイプViewModelのみを指定できるようにしたいので、{Binding}内で(またはプロパティの名前を変更した後)プロパティ名のスペルを間違えると、デザイン時の警告が表示されます。 {Binding PropertyName}内のプロパティ名をクリック(XAMLで)することによる宣言。

貴重な時間をありがとうございました。

41
WpfNewbie

自分でMVVMを実行する場合、これは難しい部分です。

基本的にあなたのオプション:

依存性注入を使用

Page/WindowのコンストラクターにViewModelを注入して、その中に割り当てることができます。

ただし、これにはいくつかの欠点があります。

  • 設計時のビューモデルの使用が困難
  • ビューはXAMLからインスタンス化できなくなりました

ViewModel First with Navigation Service

ViewModelsを解決し、ナビゲーションサービスを介してすべてのナビゲーションを実行します。 ViewModelsでは、INavigationServiceを渡します。 ViewModelタイプを使用して、ビューにナビゲートできます。その内部で、Dependency Injectionを介してViewModelをインスタンス化し、次に(命名規則またはDI構成を介して)ビューをインスタンス化します

それは少し優れていますが、それでもXAML内でビューをインスタンス化することはできません。大きなプラスは、ViewModelsにパラメーターを簡単に渡すことができることです(ViewModelsにINavigationAwareプロパティを実装し、NavigatedToメソッドをインスタンス化してからパラメーターを渡します)

ViewModelLocator /添付プロパティ/動作

これを使用して、true(自動配線)またはViewModelタイプ(インスタンス化されたViewModelをさらに制御するため)に設定する添付プロパティを作成し、ViewModelを検索して解決し、割り当てます。それ。

基本的に、上記のすべての利点に加えて、Viewからのインスタンス化が提供されます。

最後の1つは、基本的にMicrosoftのMVVMフレームワーク「Prism」が行うことです(ナビゲーションサービスnavigationService.Navigate("MyPage", myParameterForViewModel)、DataContextのインスタンス化、および自動配線によるXAMLからの割り当て(XAML:prism:ViewModelLocator.AutoWireViewModel="True")。

そうは言っても、配線のこの部分を実行する成熟したMVVMフレームワークを使用するのが最善です(BindableBaseなどの基本クラスを使用しない場合でも、フレームワークで呼び出されるものは何でも)。

ViewModelの設計時のViewModel /自動補完に関して:

これを行うには、Blendのデザイン時属性を使用できます。最初にブレンドアセンブリ参照を追加する必要があります。その後、xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"名前空間をページ/ビューに追加できます。

その後、d:DataContext="{d:DesignInstance my:DesignTimeViewModel, IsDesignTimeCreatable=True}を介してページにバインドできます。 DataContextの前のd:に注意してください。これは重要です。このDataContextは、デザイナー(Visual Studio XAMLデザイナーまたはBlend)でのみ使用されます。これは、通常のDataContext(プレフィックスなし)への干渉を防ぐためです。

例:

<Window x:Class="WpfApplication1.Window2"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
        xmlns:myApp="clr-namespace:WpfApplication1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance myApp:Window2ViewModel, IsDesignTimeCreatable=True}">
    <Grid>
        <TextBlock Text ="{Binding Test}"/>
    </Grid>
</Window>

ViewModelsにInterfacesを使用する場合、Visual StudioにすべてのInterfaceプロパティを実装してデフォルト値を与えるだけで、デザインインスタンスを作成するのは非常に高速です(ViewModelにサンプルデータがあり、バインディングが正しく動作することを確認するためのプロパティ) 。

これには、設計時のViewModelと実際のViewModelを別々に作成する必要がありますが、これは見た目ほど悪くはありません。これにより、実際のViewModelがまだ完成/実装されていない場合でも、UIデザイナーが作業する機会が得られます。

43
Tseng