MVVMを使用して、複数のビューを切り替えるアプリケーションを作成しています。ビューは、このようなContentControl
によってインスタンス化されていますイベントから退会する必要があるときにビューをどのように伝えますか?
<ContentControl Name="DynamicViewControl" Content="{Binding }">
<ContentControl.Resources>
<DataTemplate x:Key="PageOneTemplate">
<pages:PageOne DataContext="{Binding PageOneViewModel}"/>
</DataTemplate>
<DataTemplate x:Key="PageTwoTemplate">
<pages:PageTwo DataContext="{Binding PageTwoViewModel}"/>
</DataTemplate>
<!-- And so on... -->
</ContentControl.Resources>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding CurrentPage}" Value="{x:Static model:Pages.PageOne}">
<Setter Property="ContentTemplate" Value="{StaticResource PageOneTemplate}"/>
</DataTrigger>
<DataTrigger Binding="{Binding CurrentPage}" Value="{x:Static model:Pages.PageTwo}">
<Setter Property="ContentTemplate" Value="{StaticResource PageTwoTemplate}"/>
</DataTrigger>
<!-- And so on... -->
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
:
public enum Pages {
PageOne,
PageTwo,
// etc...
}
public class PageViewModel : ObservableObject {
private Pages currentPage = Pages.PageOne;
public PageViewModel() {
PageOneViewModel= new PageOneViewModel(Model);
PageTwoViewModel= new PageTwoViewModel(Model);
// And so on...
NavButtonCommand = new RelayCommand(NavButton);
PreviousButtonCommand = new RelayCommand(PreviousButton);
}
public PageModel Model { get; } = new PageModel();
/// <summary>Gets or sets the current page.</summary>
public Pages CurrentPage {
get => currentPage;
set {
currentPage = value;
NotifyPropertyChanged();
}
}
public DataSelectionViewModel PageOneViewModel { get; }
public ProfileSelectionViewModel PageTwoViewModel { get; }
public ICommand NavButtonCommand { get; }
public ICommand PreviousButtonCommand { get; }
// This isn't my actual page change logic, just some code with a
// similar effect to get my point across
private void NavButton(object param) {
int next = (int)CurrentPage + 1;
if Enum.IsDefined(typeof(Pages), next) {
CurrentPage = (Pages)next;
}
}
private void PreviousButton(object param) {
int previous = (int)CurrentPage - 1;
if Enum.IsDefined(typeof(Pages), previous) {
CurrentPage = (Pages)previous;
}
}
}
問題がある私の見解の一部では、私はPropertyChanged
通知をサブスクライブする必要があることをそれぞれのViewModelで簡単にバインドできないView内のものを変更できるようにします。 ContentControl
が毎回新しいViewを作成し、ViewModelで参照を保持しているイベントハンドラのために決してクリーンアップされないため、メモリリークが発生します(C#でメモリリークが存在する限り)。
ビューの変更時にViewModelのすべてのイベントサブスクライバをクリーンアップしようとしましたが、ビューのクリーンアップコードがViewModel内にあり、意図しない結果が生じ、一部の機能が動作しなくなった。
イベントに登録を停止するように私の意見を伝える方法はありますか?または、それらをバインドする方法(バインドできるDependencyPropertiesでカスタムコントロールを作成するなど)を見つける必要があります。
あなたのビューモデルはどのようなイベントでも購読していますか? –
ビューはビューモデルの 'PropertyChanged'通知を購読しています。 – Lauraducky
質問に同じ質問があるという同じ質問があるからといって、必ずしもそうではないと思うが、将来の訪問者が同様の質問を参照するのに役立つかもしれない。 – Lauraducky