对于冗长而描述性的问题感到抱歉,但很长一段时间它确实让我烦恼。我有MVVM模式的问题。
我写的应用程序确实有效,但我不认为它的风格很好。我的视图模型结构看起来像树:它引用了所有子视图模型,用于在ContentPresenter中呈现正确的视图。
看一下示例GUI:
主页标签
--------------------------------------
HOME SETTINGS ADMINPANEL
======---------------------------------
______________________________________
/////////
///////// Home content
/////////
“设置”标签
--------------------------------------
HOME SETTINGS ADMINPANEL
------============---------------------
______________________________________
settings1 > settings2 > other...
/////////
///////// Settings1 content
/////////
请注意仅在“设置”视图中显示的子菜单。每个可切换的视图都以某种方式依赖于模型类型。仅当model属性为Type.One时,settings1才可见,当属性为Type.Two时,settings2可见。
快速查看我当前的代码:每个视图的通用界面,我可以通过点击更改。 PageHeader显示在按钮更改内容视图上:
public interface IPageVM
{
string PageHeader { get; set; }
}
并查看模型:
public class WindowVM : ViewModelBase
{
public ObservableCollection<IPageVM> ViewModels { get; set; }
public IPageVM CurrentTab { get; set; }
public ICommand ChangeViewModel { get; set; }
private Model _model;
public WindowVM()
{
_model = new Model();
ViewModels = new ObservableCollection<IPageVM>();
ViewModels.Add(new HomeVM(model));
ViewModels.Add(new SettingsVM(model));
if(_model.Admin)
ViewModels.Add(new AdminVM(model));
}
}
public class HomeVM : ViewModelBase, IPageVM
{
public string PageHeader { get { return "HOME"; } }
string Property { get; set; }
public HomeVM(Model model)
{
this.Property = model.Property;
}
}
public class SettingsVM : ViewModelBase, IPageVM
{
public string PageHeader { get { return "SETTINGS"; } }
public ObservableCollection<IPageVM> Tabs { get; set; }
public IPageVM CurrentTab { get; set; }
public ICommand ChangeViewModel { get; set; }
public SettingsVM(Model model)
{
Tabs = new ObservableCollection<IPageVM>();
if(model.Type = Type.One)
Tabs.Add(new Settings1VM(model));
if(model.Type = Type.Two)
Tabs.Add(new Settings2VM(model));
Tabs.Add(new OtherSettingsVM());
CurrentTab = Tabs[0];
}
}
public class Settings1VM: ViewModelBase, IPageVM
{
public string PageHeader { get { return "settings1"; } }
public Settings1VM(Model model)
{
}
}
public class Settings2VM: ViewModelBase, IPageVM
{
public string PageHeader { get { return "settings2"; } }
public Settings1VM(Model model)
{
}
}
XAML: 在ItemsControl中显示按钮,这些按钮将更改CurrentViewModel并呈现绑定到视图模型的适当视图。按DataTemplate键入。
优点:
缺点:
所以我决定将我的ViewModel改为看起来更像WPF MVVM的东西:
public class WindowVM : ViewModelBase
{
public bool AdminMode { get; set; }
public WindowVM()
{
_model = new Model();
AdminMode = _model.Admin;
AnotherTabVisibilityDependency = _model.Dependency;
}
}
XAML:
<TabControl>
<TabItem Header="HOME">
<TabItem.DataContext>
<vm:HomeVM/>
</TabItem.DataContext>
</TabItem>
<TabItem Header="SETTINGS">
<TabItem.DataContext>
<vm:SettingsVM/>
</TabItem.DataContext>
</TabItem>
<TabItem Header="ADMINPANEL" Visibility="{Binding AdminMode, Converter BoolToVisibility}">
<TabItem.DataContext>
<vm:AdminVM/>
</TabItem.DataContext>
</TabItem>
<TabItem Header="DEPENDANT" Visibility="{Binding AnotherTabVisibilityDependency, Converter BoolToVisibility}">
</TabItem>
</TabControl>
正如您可能看到的,一切都很干净,用户界面很简单;没有太多的模板可写。一切看起来都很好......但有一点我不明白:现在每个ViewModel都是一个不了解其父级的独立实例。我不能轻易通过模型。
问题: