我试图了解MVVM,我目前仍然坚持如何处理导航。
目前我有一个页面,在该页面内是一个框架,该框架负责在各种其他页面中框架。之前使用下拉框处理导航,并且在选择更改后,它将导航。
我不确定如何在不触摸模型视图中的框架的情况下完成此操作,最终会破坏mvvm。
最后我想要完成的是,点击组合框,选择一个项目,然后在下方框架导航到正确的视图。
我没有使用Prism或任何其他框架与MVVM,只是尝试手动完成。
答案 0 :(得分:1)
ComboBox
将显示主视图模型公开的ObservableCollection
个框架项,并且viewmodel将具有所选项的另一个属性。
您的主视图模型和框架项视图模型都继承自实现ViewModelBase
的{{1}}类,以及其他一些东西。
所以,C#:
INotifyPropertyChanged
您的主视图模型将在其构造函数中填充public ObservableCollection<ViewModelBase> FrameItems { get; protected set; }
private ViewModelBase _selectedFrameItem;
public ViewModelBase SelectedFrameItem {
get { return _selectedFrameItem; }
set {
value = _selectedFrameItem;
// Defined in ViewModelBase
OnPropertyChanged();
}
}
:
FrameItems
每个框架项都是public MainViewModel()
{
FrameItems = new ObservableCollection<ViewModelbase> {
new IceCreamMenu(),
new SmurfOptions(),
new MagicSparklePonyFourierTransformConfiguration()
};
}
的子类。它使用通知公开属性,包括它可能具有的任何子项内容的ViewModelBase
。我们将通过为它编写一个数据模板来显示它。
我们假设您已为ObservableCollections
班级提供ViewModelBase
财产。或者您可能想要编写引入String Title { get; set; }
的{{1}}子类;你的来电。现在,为了简单起见,我们将其放在ViewModelBase
中。
XAML - 这省略了所有布局,但你不需要这里。
Title
好的,但它究竟怎么知道如何处理ViewModelBase
?!
轻松!编写一个名为<ComboBox
ItemsSource="{Binding FrameItems}"
SelectedItem="{Binding SelectedFrameItem}"
DisplayMemberPath="Title"
/>
<Frame Content={Binding SelectedFrameItem}" />
的资源词典,并将其合并到SelectedFrameItem
中,使其内容为&#34;可见&#34;在您的应用程序中的任何XAML中。
的App.xaml
ViewModelDataTemplates.xaml
...加上任何主题或任何东西。
在App.xaml
中,为您的框架类定义数据模板。
假设您有一个<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Source is a relative path from project root directory -->
<ResourceDictionary Source="ViewModelDataTemplates.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
视图模型,其中包含ViewModelDataTemplates.xaml
IceCreamMenu
...和Flavors
。您可以使用资源字典上的public ObservableCollection<IceCreamFlavor> Flavors { get; protected set; }
属性适当地定义名称空间SelectedFlavor
。
ViewModelDataTemplates.xaml
vm
如果您希望通过数据模板使用现有的xmlns:vm
,那很简单:假设您有<DataTemplate DataType="{x:Type vm:IceCreamMenu}">
<Grid>
<ListBox
ItemsSource="{Binding Flavors}"
SelectedItem="{Binding SelectedFlavor}"
/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:IceCreamFlavor}">
<StackPanel Orientation="Horizontal">
<Border
Height="20"
Width="20"
Margin="4"
Background={Binding Color, Converter={StaticResource ColorToBrushConverter}}"
/>
<Label Content="Name" />
</StackPanel>
</DataTemplate>
UserControls
该&{ #39;您的NotesTabView
的视图,您可以像这样定义DataTemplate:
UserControl
答案 1 :(得分:0)
@EdPlunkett:作为每个视图的DataTemplate的替代方法,您可以使用ViewModelToViewConverter将框架绑定到选定的页面视图模型,就像我在此处所做的那样:https://stackoverflow.com/a/31721236/475727
隐式DataTemplates和DataTemplateSelectors是WPF和XAML独有的,所以人们认为它是推荐的解决方案,但我认为它不适合导航。它感觉很乱,它闻起来违反了DRY原则。