3

MV-VMアーキテクチャを使用して、他のユーザーコントロール(さまざまなウィジェットを含むWidgetContainerを想像してください)を含むWPFユーザーコントロールを設計しています。開発中、ウィンドウにWidgetContainerViewがあり、ウィンドウ(View)がそのリソースとしてWidgetContainerViewModelを生成し、WidgetContainerViewModelのパラメーターなしのコンストラクターで、公開されたコレクションにいくつかのサンプルウィジェット(WidgetViewModels)を入力します。

WidgetContainerコントロールはウィンドウからDataContextを継承し、その中には、ウィジェットをWidgetViewコントロール(ListView.ItemTemplate内にある)にバインドするListViewがあります。

サンプルウィジェットを見ると、これはWindowViewで正常に機能しますが、WidgetContainerViewまたはWidgetViewを編集すると、コンテンツはありません。設計時には、コントロールはスタンドアロンであり、DataContextを継承しないため、コンテンツが表示され、デザインに問題があります(ListViewが空で、ウィジェットのフィールドも空です...)。

サンプルウィジェットをWidgetViewに追加してみました。

public partial class WidgetView : UserControl
{
    public WidgetView()
    {
        InitializeComponent();
        if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
        {
            //btw, MessageBox.Show(...) here sometimes crashes my Visual Studio (2008), but I have seen the message - this code gets executed at design time, but with some lag - I saw the message on reload of designer, but at that time, I have already commented it - wtf?
            this.DataContext = new WidgetViewModel(); //creates sample widget
        }
    }
}

しかし、それはうまくいきませんでした-私はまだデザイナーに何も見えません。

また、次のように、WidgetViewのリソースとしてWidgetViewModelを作成したいと思いました。

<UserControl x:Class="MVVMTestWidgetsControl.View.WidgetView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="WidgetViewModel" //this doesn't work!
    Height="Auto" Width="Auto">
    <UserControl.Resources>
        <ResourceDictionary>
            <ViewModel:WidgetViewModel x:Key="WidgetViewModel" />
        </ResourceDictionary>
    </UserControl.Resources>

    <TextBlock Text="{Binding Path=Title}"></TextBlock>

</UserControl>

しかし、WidgetViewModelをウィジェット全体のDataContextとして割り当てる方法がわかりません-WidgetViewModelはコードの後半で定義されているため、UserControlにDataContext属性を追加することはできません。これを行う方法はありますか?この方法でサンプルデータを使用し、コードでオーバーライドして、実行時に適切なコンテンツが含まれるようにすることができます...

ユーザーコントロールを開発する際のベストプラクティスは何ですか?ありがとう、空のコントロールを設計するのは楽しいことではありません:))。

4

2 に答える 2

3

2番目のスニペットでは、DataContextをDynamicResourceとして参照できるはずです。

DataContext="{DynamicResource WidgetViewModel}"

ただし、ほとんどのカスタムユーザーコントロールには、ある種のトップレベルのレイアウトコンテナがあり、そのコンテナのDataContextをStaticResourceとして設定できます。

ただし、あなたの場合、カスタムUserControlを作成しているので、コードのVM部分を完全に削除することを検討することをお勧めします。1つのビュー(つまり、カスタムUserControl)用に設計された実際のバッキングモデルがない、完全に自己完結型のViewModelからどのようなメリットが得られるかを自問する必要があります。おそらく、いくつかのDependencyPropertiesを定義して、それらを使用することができますか?

于 2009-06-15T20:08:40.533 に答える
1

私はいくつかの解決策を思いつきました:リソースとしてDCを追加し(パラメーターなしのコンストラクターで自動的にインスタンス化されます)、Viewのコードビハインドで次のことを行います。

    public PanelView()
    {
        InitializeComponent();

        if (!DesignerProperties.GetIsInDesignMode(new DependencyObject())) //DeleteAtRelease:
        {
            //we are in runtime, reset DC to have it inherited
            this.DataContextHolder.DataContext = DependencyProperty.UnsetValue;
        }

    }

より良い方法は、設計時にDCを割り当てることですが、VSはそれを気に入らなかった-それはたまにしか機能せず、まったく非決定論的であり、一度クラッシュしたことさえあります。

設計時のその他のチェックは次のとおりです。

        if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
        {
            this.DataContext = new WidgetViewModel();
        }
于 2009-06-16T22:35:04.823 に答える