通过创建具有水平导航项目类型,MVVM Light 设计模式和两个空白页面(MainPage和StatsPage)的Windows Template Studio应用程序开始学习UWP开发。 / p>
在MainPage中,我有一个项目列表,当用户点击相关的NavigationViewItem
时,我想在StatsPage中显示所选项目的统计信息。在我的wpf应用程序中,我将在主视图的按钮上设置一个带有命令参数的RelayCommand
,然后在viewmodel中,使用param / arg调用命令的方法以使用正确的信息打开Stats视图。在创建的Template Studio应用中,ShellPage中的NavigationViewItem
在其VM中调用OnItemInvoked()
,而该VM不知道MainPage视图中的选择。
<winui:NavigationView.MenuItems>
<winui:NavigationViewItem x:Uid="Shell_Main" helpers:NavHelper.NavigateTo="LG_Ess.ViewModels.MainViewModel" />
<winui:NavigationViewItem x:Uid="Shell_Stats" helpers:NavHelper.NavigateTo="LG_Ess.ViewModels.StatsViewModel" />
</winui:NavigationView.MenuItems>
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="ItemInvoked">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.ItemInvokedCommand}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
如何通过ShellPage的NavigationViewItem
将MainPage选择的项目作为参数传递给StatsPage?我可以通过在主页上添加一个按钮并隐藏Shell导航来解决该问题,但是我更喜欢使用Template Studio样式。
进一步的调查表明,对于Studio Studio创建的所有页面,ShellViewModel似乎是默认的DataContext。在我的页面中,我通过添加以下内容将数据上下文设置为自动生成的视图模型:
<Page.DataContext>
<local:{PageName}ViewModel/>
</Page.DataContext>
因此,似乎我可以拥有一个ViewModel并将页面视为UserControls,或者将每个页面的DataContext映射到其自己的ViewModel,然后执行一些ViewModelLocator来从另一个VM中的一个VM访问属性。
答案 0 :(得分:0)
因此,似乎我可以拥有一个ViewModel并将页面视为UserControls,或者将每个页面的DataContext映射到其自己的ViewModel,然后执行一些ViewModelLocator来从另一个VM中的一个VM访问属性。
正确。您可以在MainViewModel中定义一个“ SelectedStats”相关属性,并使ListView的SelectedItem绑定到此属性并设置Mode=TwoWay
。然后,在“ StatsPage”上,您可以使用EventTriggerBehavior
绑定StatsViewModel中的“ LoadedCommand”,例如“ ShellPage”。在StatsViewModel中,您可以通过调用ViewModelLocator.Current.MainViewModel.SelectedStats
来获取选定的项目。
请参阅我的简单代码示例:
<!--MainPage.xaml-->
<ListView ItemsSource="{x:Bind ViewModel.list}" SelectedItem="{x:Bind ViewModel.SelectedStats,Mode=TwoWay}">
</ListView>
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
list = new ObservableCollection<string>();
list.Add("string1");
list.Add("string2");
list.Add("string3");
}
public ObservableCollection<string> list { get; set; }
private object _SelectedStats;
public object SelectedStats
{
get { return _SelectedStats; }
set
{
if (_SelectedStats != value)
{
_SelectedStats = value;
RaisePropertyChanged("SelectedStats");
}
}
}
}
<!--StatsPage.xaml-->
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="Loaded">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.LoadedCommand}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
public class StatsViewModel : ViewModelBase
{
public StatsViewModel()
{
}
private ICommand _LoadedCommand;
public ICommand LoadedCommand => _LoadedCommand ?? (_LoadedCommand = new RelayCommand(LoaedAsync));
private async void LoaedAsync()
{
var selectedObject = ViewModelLocator.Current.MainViewModel.SelectedStats;
//TODO:...
await Task.CompletedTask;
}
}