我正在定义一个策略,主视图将使用数据模板在视图之间切换。目前它可以在3个视图之间切换:
这个想法是当需要显示对话框视图时,它在主视图上被设置为当前视图。选择完成后,此信息将传递给ApplicationView或属于ApplicationView的视图。显示DialogView时,ApplicationView不能从内存中释放,因为ApplicationViewModel仍将使用数据进行操作(它需要在后台持续工作)。
我正在考虑使用DataTemplates实现此目的,并将ContentControl的内容绑定到CurrentView:
// in MainView
DataTemplate DataType="{x:Type vm:ApplicationViewModel}">
<vw:ApplicationView />
</DataTemplate>
.....
// in MainViewModel
public ViewModelBase CurrentView { get; set; }
基本上我试图避免使用模态窗口进行对话。
1)这个策略是否正常,或者有一些我不知道的问题?
2)当我切换到DialogView(我实际上正在切换视图模型)时,ApplicationView / ApplicationViewModel会发生什么?我是否需要在某处存储ApplicationViewModel的引用,因此不会收集垃圾?我没有测试过这个,但是当我设置CurrentView时,将会创建一个新的ViewModel / View实例。
3)连接到第二个问题,当使用DataTemplates时,先前使用的View / ViewModel会发生什么,现在用不同的view / viewmodel替换?
答案 0 :(得分:0)
就个人而言,我会发现在标准网格中使用ZOrdering更容易,并将所有内容放在同一视图中 - 使用ViewModel来管理可见性。
E.g
<Grid>
<Grid Visibility="{Binding IsView1Visible,
Converter={StaticResource BoolToVisibilityConverter}}">
<!-- view 1 contents -->
</Grid>
<Grid Visibility="{Binding IsView2Visible,
Converter={StaticResource BoolToVisibilityConverter}}">
<!-- view 2 contents -->
</Grid>
<Grid Visibility="{Binding IsView3Visible,
Converter={StaticResource BoolToVisibilityConverter}}">
<!-- view 3 contents -->
</Grid>
<Grid Visibility="{Binding IsDialogVisible,
Converter={StaticResource BoolToVisibilityConverter}}">
<!-- dialog contents contents -->
</Grid>
</Grid>
答案 1 :(得分:0)
我没有看到您切换视图的方式有任何问题,尽管通常您不希望在显示对话框时摆脱应用程序。
我过去所做的是将CurrentView
和DialogView
放在Grid
中,以便它们彼此重叠,然后拥有{ {1}}包含ApplicationViewModel
和IDialogViewModel
属性,当您想要显示对话框时,只需填充这两个字段即可。 (见下面的例子)
如果您想要返回IsDialogVisible
并避免创建新的ApplicationViewModel
ApplicationViewModel
存储在某处
WPF处理不再可见的UI对象,因此将CurrentView
从Login
切换为Application
将摆脱LoginView
并创建ApplicationView
ContentControl的内容已设置为ViewModel
,因此ViewModel实际上已放入应用程序VisualTree
。每当WPF在其VisualTree
中遇到一个不知道如何绘制的对象时,它将使用包含该对象的TextBlock
的{{1}}绘制它。通过定义.ToString()
,您告诉WPF如何绘制对象而不是使用其默认的DataTemplate
方法。一旦对象离开.ToString()
,任何为渲染对象而创建的可视对象都将被破坏。
虽然我会继续使用您目前用于切换视图的内容,但我不会对VisualTree
,Login
和Application
视图使用该方法。
通常情况下,Dialog
只应在登录时显示一次,但如果您允许用户在登录后切换登录,它可能会再次显示在LoginView
中。因此,我通常会显示启动代码中的Dialog
,一旦登录成功,就会显示LoginView
。
ApplicationView
就像我之前说过的那样,当我显示protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var login = new LoginDialog();
var loginVm = new LoginViewModel();
login.DataContext = loginVm;
login.ShowDialog();
if (!login.DialogResult.GetValueOrDefault())
{
Environment.Exit(0);
}
// Providing we have a successful login, startup application
var app = new ApplicationView();
var context = new ApplicationViewModel(loginVm.CurrentUser);
app.DataContext = context;
app.Show();
}
时,我不想隐藏Application
,所以我会将Dialog
<{1}} < / p>
以下是我将Dialog
用于Application
的示例,使用我自己的custom Popup from my blog作为对话
DataTemplate