3

アプリケーションのメイン ウィンドウから、関係のない大量のコードを除いたもの。

<Window>
    <Window.Resources>
    <DataTemplate DataType="{x:Type presenters:DashboardViewModel}">
        <views:DashboardView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type presenters:SecondViewModel}">
        <views:SecondView />
    </DataTemplate>
    </Window.Resources>

    <ContentPresenter Content="{Binding WindowPresenter}"/>
</Window>

Window にバインドされているビュー モデル

public class RootViewModel {
    // IRL this implements notifypropchanged
    public IPresenter WindowPresenter {get; set;}
    public void ShowDashboard(){ this.WindowPresenter = new DashBoardViewModel(); }
    public void ShowSecond(){ this.WindowPresenter = new SecondViewModel(); }
}

DashboardViewまたSecondView、それぞれのビュー モデルのプロパティにバインドされている多くの依存関係プロパティを持つユーザー コントロールです。

// example of a common dependency property I have 
public static readonly DependencyProperty ColorPaletteProperty = DependencyProperty.Register("ColorPalette", typeof(ColorPalette), typeof(SurfaceMapControl), new PropertyMetadata(ColorPalette.Rainbow, new PropertyChangedCallback(SurfaceMapControl.ColorPalettePropertyChanged)));
private static void ColorPalettePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((SurfaceMapControl)d).OnColorRangeChanged(); }
private void OnColorRangeChanged() { 
    // code that uses this.SomeOtherDependencyProperty
    // throws null ref exception
}

を呼び出すShowDashboard()と、コンテンツ プレゼンターは正しいユーザー コントロールを表示し、すべてのプロパティが正しくバインドされます。の呼び出し時にShowSecond()、コンテンツ プレゼンターは正しいユーザー コントロールを表示し、すべてのプロパティが正しくバインドされます。

2 つのビューを切り替えると、一部のプロパティが他の依存関係プロパティを参照するため、ユーザー コントロールの 1 つの依存関係プロパティで null ref 例外が発生することがあります。これにより、viewmodel がビューの前にガベージ コレクションされ、viewmodel の変更により usercontrols 依存関係プロパティがトリガーされ、viewmodel が存在しなくなったため例外がスローされると思われます。

ビューモデルが破棄されたときに依存関係プロパティがトリガーされないようにすることはできますか?

それとも、すべての依存関係プロパティで null データ コンテキスト チェックが必要ですか?

これを完全に防ぐために、ユーザーコントロールのライフサイクルを確認するためにここに含める必要があるものはありますか?

4

1 に答える 1