Поскольку я новичок в этом мире, моей отправной точкой является шаблон, созданный с помощью Template Studio.
Я также использую MVVM Community Toolkit.
Я планирую использовать пустое пространство в левой панели навигации для добавления контекстно-зависимых элементов управления пользовательского интерфейса.
Так, например, если пользователь находится на странице SimpRec и нажимает кнопку, на левой панели навигации появляется раздел с двумя полями со списком, используемыми для фильтрации некоторых данных.
Панель навигации определяется в моем ShellPage.xaml следующим образом, и ее свойство Visibility имеет значение быть привязано к свойству IsFilterMenuVisible.
ShellPage.xaml:
Код: Выделить всё
SimpRecViewModel.cs:
Код: Выделить всё
public partial class SimpRecViewModel : ObservableRecipient, INavigationAware
{
private readonly INavigationService _navigationService;
private readonly IAppService _appDiagnosticsService;
[ObservableProperty]
private Visibility isFilterMenuVisible = Visibility.Collapsed;
public SimpRecViewModel(INavigationService navigationService, IAppService appDiagnosticsService)
{
_navigationService = navigationService;
_appDiagnosticsService = appDiagnosticsService;
}
public async void OnNavigatedTo(object parameter)
{
// Some code
}
public void OnNavigatedFrom()
{
}
[RelayCommand]
private async Task ShowFilters(int selectedIndex)
{
// Some code
IsFilterMenuVisible = Visibility.Visible;
// More code
}
ShellPage.xaml.cs:
р>
Код: Выделить всё
public sealed partial class ShellPage : Page
{
public ShellViewModel ViewModel
{
get;
}
public SimpRecViewModel SRViewModel
{
get;
}
public ShellPage(ShellViewModel viewModel, SimpRecViewModel srViewModel)
{
ViewModel = viewModel;
InitializeComponent();
SRViewModel = srViewModel;
ViewModel.NavigationService.Frame = NavigationFrame;
ViewModel.NavigationViewService.Initialize(NavigationViewControl);
// More code
}
ShellPage.xaml:< /p>
Код: Выделить всё
xmlns:srvm="using:MyApp.ViewModels">
Когда я попробовал код, раздел фильтра слева Панель была правильно свернута, но когда я нажал кнопку, ничего не изменилось. Я ожидал увидеть вместо этого раздел.
Другой подход, который я попробовал, основан на ответе на аналогичный вопрос (https://stackoverflow.com/questions/165 ... a-property -in-one-viewmodel-from-another) заключалось в создании [ObservableProperty] IsFilterMenuVisible в ShellViewModel следующим образом:
ShellViewModel.cs :
Код: Выделить всё
public partial class ShellViewModel : ObservableRecipient
{
// Some code
[ObservableProperty]
private Visibility isFilterMenuVisible = Visibility.Collapsed;
public INavigationService NavigationService
{
get;
}
public INavigationViewService NavigationViewService
{
get;
}
public ShellViewModel(INavigationService navigationService, INavigationViewService navigationViewService)
{
NavigationService = navigationService;
NavigationService.Navigated += OnNavigated;
NavigationViewService = navigationViewService;
}
private void OnNavigated(object sender, NavigationEventArgs e)
{
IsBackEnabled = NavigationService.CanGoBack;
if (e.SourcePageType == typeof(SettingsPage))
{
Selected = NavigationViewService.SettingsItem;
return;
}
// More code
}
}
SimpRecViewModel.cs:
р>
Код: Выделить всё
public partial class SimpRecViewModel : ObservableRecipient, INavigationAware
{
private readonly INavigationService _navigationService;
private readonly IAppService _appDiagnosticsService;
// Some code
public ShellViewModel ShellViewModel { get; set; }
public SimpRecViewModel(INavigationService navigationService, IAppService appDiagnosticsService, ShellViewModel shellViewModel)
{
_navigationService = navigationService;
_appDiagnosticsService = appDiagnosticsService;
ShellViewModel = shellViewModel;
}
public async void OnNavigatedTo(object parameter)
{
// Other code
}
public void OnNavigatedFrom()
{
}
[RelayCommand]
private async Task ShowFilters(int selectedIndex)
{
// Some code
ShellViewModel.IsFilterMenuVisible = Visibility.Visible;
// More code
}
В качестве проверки я добавил возможность изменения Видимость в результате выбора страницы настроек в ShellViewModel.
ShellViewModel.cs:
Код: Выделить всё
public partial class ShellViewModel : ObservableRecipient
{
// Some code as before
[ObservableProperty]
private Visibility isFilterMenuVisible = Visibility.Collapsed;
// Same code too
private void OnNavigated(object sender, NavigationEventArgs e)
{
IsBackEnabled = NavigationService.CanGoBack;
if (e.SourcePageType == typeof(SettingsPage))
{
Selected = NavigationViewService.SettingsItem;
IsFilterMenuVisible = Visibility.Visible;
return;
}
// Same code shown previously
}
}
В связанном ответе также предлагалось создать статический экземпляр ShellViewModel (в моем случае) и получить к нему доступ из SimpRecViewModel.
Я попробовал этот подход, сначала создав конструктор без параметров для ShellViewModel.
Причина в том, что я этого не делаю. знать, какие параметры передавать
Код: Выделить всё
private static ShellViewModel _instance = new ShellViewModel();
Код: Выделить всё
public ShellViewModel(INavigationService navigationService, INavigationViewService navigationViewService)
Код: Выделить всё
public partial class ShellViewModel : ObservableRecipient
{
// Usual code
[ObservableProperty]
private Visibility isFilterMenuVisible = Visibility.Collapsed;
private static ShellViewModel _instance = new ShellViewModel();
public static ShellViewModel Instance { get { return _instance; } }
ShellViewModel() { }
public INavigationService NavigationService
{
get;
}
public INavigationViewService NavigationViewService
{
get;
}
public ShellViewModel(INavigationService navigationService, INavigationViewService navigationViewService)
{
NavigationService = navigationService;
NavigationService.Navigated += OnNavigated;
NavigationViewService = navigationViewService;
}
// All the other code
}
SimpRecViewModel.cs:
Код: Выделить всё
public partial class SimpRecViewModel : ObservableRecipient, INavigationAware
{
// Previous code
public SimpRecViewModel(INavigationService navigationService, IAppService appDiagnosticsService)
{
_navigationService = navigationService;
_appDiagnosticsService = appDiagnosticsService;
}
// Unrelated code
[RelayCommand]
private async Task ShowFilters(int selectedIndex) // async Task ShowFilters(int selectedIndex)
{
// Other code
ShellViewModel.Instance.IsFilterMenuVisible = Visibility.Visible;
// Final code
}
Мой идеальный сценарий — это тот, в котором DataContext установлен на странице SRViewModel. Это связано с тем, что я планирую использовать другие свойства этой страницы, которые будут влиять на некоторые элементы управления пользовательского интерфейса в ShellPage.xaml.
И другие страницы будут иметь аналогичное влияние на ShellPage.xaml.
Любая помощь приветствуется.
Подробнее здесь: https://stackoverflow.com/questions/785 ... -viewmodel