对列表框选择更改执行页面导航的正确方法是什么
-
25-09-2019 - |
题
我正在尝试 MVVM Light Toolkit。尽管我仍然认为为如此小的应用程序拥有多个 ViewModel 有点过分,但我喜欢这些概念。我仍然不太明白的是,当列表框中的选择发生变化时,如何(或者我应该说“推荐的方式是什么”)从一个页面导航到另一个页面。
这个工具包的一个大问题是,它迫使您在使用之前通过其他来源学习 MVVM,而不是向您展示 MVVM(其愿景)来自框架、随附示例和文档。是否有展示不同概念的示例?拜托,没有视频。
解决方案
您是否尝试过修改 ListBox ItemTemplate 以使每个项目都是 HyperlinkButton,并将 NavigateURI 属性设置为您要导航到的页面?
其他提示
我还没有想出如何在不视图中的任何代码隐藏做到这一点(导航到在选择详细信息页面的列表框中改变)。但是,如果你是用具有的观点只是一个小代码隐藏确定这里就是我的建议:
<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}"
SelectionChanged="MainListBox_SelectionChanged"
SelectedItem="{Binding Path=SelectedListItem, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
首先,按照上述结合到列表框的与双向(在上述SelectedListItem
)结合到一个属性在您的视图模型SelectedItem属性。
然后在你的代码隐藏这个页面落实处理程序MainListBox_SelectionChanged:
// Handle selection changed on ListBox
private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// If selected index is -1 (no selection) do nothing
if (MainListBox.SelectedIndex == -1)
return;
// Navigate to the new page
NavigationService.Navigate(new Uri("/DetailsPage.xaml", UriKind.Relative));
}
这是唯一的代码隐藏在您的主视图所需要的。
在你的主视图模型,你需要一个SelectedListItem属性:
public const string SelectedListItemPropertyName = "SelectedListItem";
private ItemViewModel _SelectedListItem;
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding
/// </summary>
/// <returns></returns>
public ItemViewModel SelectedListItem
{
get
{
return _SelectedListItem;
}
set
{
if (value != _SelectedListItem)
{
_SelectedListItem = value;
RaisePropertyChanged(SelectedListItemPropertyName);
}
}
}
现在的窍门能让传递给您的详细信息页面的上下文(上下文是选择什么样的列表项),你需要设置的DataContext你的详细信息视图:
public DetailsPage()
{
InitializeComponent();
if (DataContext == null)
DataContext = App.ViewModel.SelectedListItem;
}
希望这有助于。
最终你会想设置一个自定义对象后做的不仅仅是导航,导航潜在
下面是这样做的MVVM光路。
您首先会想你的列表框中选择的项目绑定到一个属性在您的视图模型
<ListBox ItemsSource="{Binding Events}" Margin="0,0,-12,0" SelectedItem="{Binding SelectedEvent, Mode=TwoWay}">
声明你SelectedEvent
属性
public const string SelectedEventPropertyName = "SelectedEvent";
private Event _selectedEvent;
public Event SelectedEvent
{
get {return _selectedEvent;}
set
{
if (_selectedEvent == value)
{
return;
}
var oldValue = _selectedEvent;
_selectedEvent = value;
// Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
RaisePropertyChanged(SelectedEventPropertyName, oldValue, value, true);
}
}
可以然后定义绑定到轻敲事件的交互触发
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<cmd:EventToCommand Command="{Binding EventPageCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
在您的视图模型,定义EventPageCommand作为RelayCommand:
public RelayCommand EventPageCommand { get; private set; }
public MainViewModel()
{
EventPageCommand = new RelayCommand(GoToEventPage);
}
和最后声明你GoToEventPage
方法
private void GoToEventPage()
{
_navigationService.NavigateTo(new Uri("/EventPage.xaml", UriKind.Relative));
}
请注意,您可以导航到新页面之前从列表框中做其他动作,再加上你的选择的项目目前在你的约束太设置的属性。