C# WPF MVVM навигация по страницам на каждой странице, без фреймворка
Эй,
У меня небольшие проблемы с текущим проектом. Я пытаюсь создать однооконное приложение с разными страницами для загрузки. Эффект, который я пытаюсь архивировать, заключается в том, чтобы перемещаться (загружать) с одной страницы на другую, в то время как кнопки для навигации являются частью самой страницы. Если бы у меня была дополнительная панель навигации, помимо моего презентера контента, это было бы довольно легко, но поскольку навигация уже является частью контента, я не нахожу хорошего решения.
В настоящее время у меня есть мое главное окно, которое выглядит так:
<Window.Resources> <DataTemplate DataType="{x:Type viewmodels:TitlePageVM}"> <views:TitlePageView /> </DataTemplate> // and further pages </Window.Resources> <Grid> <ContentControl Content="{Binding CurrentPageModel}" /> </Grid>
Внутри MainWindow.xaml.cs я установил DataContext в свою MainWindowViewModel.
Там я создаю экземпляр всех страниц внутри конструктора и добавляю их в массив внутри моего класса singleton Mediator, а также устанавливаю первую страницу. MainWindowViewModel также реализует интерфейс INotifyPropertyChanged следующим образом:
public IPageViewModel CurrentPageVM { get { return Mediator.Instance.CurrentPageViewModel; } set { Mediator.Instance.CurrentPageViewModel = value; OnPropertyChanged("CurrentPageVM"); } }
Мой класс посредника является Одноэлементным классом и содержит массив всех экземпляров страницы, а также свойство CurrentPageVM и метод для изменения страницы:
public List<IPageViewModel> PageVM { get { //.. some code here return _pageVM; } } public IPageViewModel CurrentPageVM { get { return _currentVM; } set { _currentVM = value; } } public void ChangeVM(IPageViewModel viewModel) { //.. some code here CurrentPageVM = PageVM.FirstOrDefailt(vm => vm == viewModel) }
На страницах у меня есть кнопки для навигации:
<Button Content="Button" Command="{Binding ChangePageCommand}" />
На странице также есть модель представления, которая реализует команду:
public ICommand ChangePageCommand { get { if(_changePageCommand == null) _changePageCommand = new RelayCommand(() => Mediator.Instance.ChangeVM((IPageViewModel)Mediator.Instance.PageViewModel[1]), () => true); return _changePageCommand; } }
И вот в чем собственно проблема. При нажатии на кнопку функция ChangeVM вызывается из экземпляра посредника. Он изменяет CurrentVM и устанавливает _currentVM в первый член массива PageViewModel, но страница не изменяется. Ну, на самом деле это невозможно, потому что метод OnPropertyChanged никогда не вызывался, который реализован внутри MainWindowVM. Но как я могу это заархивировать?
Я действительно не хочу давать классу посредника обратный вызов или что-то в этом роде, и для меня это решение выглядит довольно неэлегантным. Или, может быть, есть гораздо более простой способ, чем использование Одноэлементного посредника? На самом деле я не хочу использовать фреймворки, поэтому стараюсь архивировать функциональность самостоятельно.
Может быть, у кого-то есть какие-то предложения?
С уважением,
Маниакальный.
Что я уже пробовал:
1.) Создание решения без класса посредника, но здесь я не могу получить доступ к массиву страниц изнутри страниц. Изменить и загрузить новую страницу будет невозможно.
2.) Использование класса-посредника, который содержит экземпляры страниц внутри массива. проблема здесь в том, что событие notify никогда не будет вызвано, так как оно является частью MainWindowVM, а не класса-посредника.