Я хочу создать приложение UWP с навигацией по списку, чей выбранный элемент определяет содержимое кадра.Когда выбор изменяется, содержимое кадра должно измениться.Я нашел пример того, как это сделать (метод 1 ниже), но он использует обработчики событий в коде позади.Я хочу изучить MVVM с этим проектом и, таким образом, хочу использовать MVVM-решение этой проблемы.Я новичок в MVVM, и мое текущее понимание состоит в том, что для того, чтобы отделить View от ViewModel, ViewModels не должен ссылаться на что-то определенное для View.Это правильное понимание?Единственный способ, с помощью которого я могу использовать ViewModel для изменения представления фрейма, - это в основном переместить код обработчика события в ViewModel и передать фрейм в конструктор (метод 2 ниже).Но это нарушает мое понимание связи ViewModel с View, поскольку ViewModel ссылается на конкретные экземпляры вещей в View;кроме того, это кажется бессмысленным расходом средств и может принести очень мало пользы для организации.
Как бы вы реализовали решение MVVM для этой проблемы?Или это тот случай, когда лучше использовать обработчики событий?
МЕТОД 1 - Обработчик событий: Этот код основан на примере, предоставленном Microsoft.(Вот ссылка на соответствующий код: https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/Playlists/cs)
public sealed partial class MainPage : Page
{
List<Scenario> scenarios = new List<Scenario>
{
new Scenario() { Title = "Scenario 1", ClassType = typeof(Scenario1) },
new Scenario() { Title = "Scenario 2", ClassType = typeof(Scenario2) }
};
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ScenarioControl.ItemsSource = scenarios;
}
private void ScenarioControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox scenarioListBox = sender as ListBox;
Scenario s = scenarioListBox.SelectedItem as Scenario;
if (s != null)
{
ScenarioFrame.Navigate(s.ClassType);
}
}
}
public class Scenario
{
public string Title { get; set; }
public Type ClassType { get; set; }
public override string ToString()
{
return Title;
}
}
<!-- MainPage.xaml -->
<Grid>
<SplitView x:Name="Splitter" IsPaneOpen="True" DisplayMode="Inline">
<SplitView.Pane>
<RelativePanel>
<ListBox x:Name="ScenarioControl" SelectionChanged="ScenarioControl_SelectionChanged"/>
</RelativePanel>
</SplitView.Pane>
<RelativePanel>
<Frame x:Name="ScenarioFrame" />
</RelativePanel>
</SplitView>
</Grid>
МЕТОД 2 - MVVM (?):
<!-- MainPage.xaml -->
<Grid>
...
<ListBox x:Name="ScenarioControl" SelectionChanged="{x:Bind MyViewModel.SwitchScenario}"/>
...
</Grid>
// MainPage.xaml.cs
...
public MainPage()
{
this.InitializeComponent();
MyViewModel = new MyViewModel(ScenarioFrame);
}
...
MyViewModel MyViewModel { get; set; }
}
// MyViewModel.cs
public class MyViewModel
{
public MyViewModel(Frame scenarioFrame)
{
ScenarioFrame = scenarioFrame;
}
public void SwitchScenario(object sender, SelectionChangedEventArgs e)
{
ListBox scenarioListBox = sender as ListBox;
Scenario s = scenarioListBox.SelectedItem as Scenario;
if (s != null)
{
ScenarioFrame.Navigate(s.ClassType);
}
}
public Frame ScenarioFrame { get; set; }
}