首先,如果我的问题看起来“简单”,我道歉。
我必须将一个使用.Net Framework 4.5.2设计的旧WPF项目升级到.Net 6(还有一些其他改进)。
从.Net Framework 4.5.2到.Net 6的迁移已经完成,并且运行得非常好。
但是,在旧项目中,有一个带有菜单的MainView,每个菜单项都使用ShowDialog()打开一个新窗口。在这些新窗口中,还可以使用ShowDialog()等打开其他窗口。
因此,您最终可能会打开四个窗口,但由于ShowDialog(),前三个窗口被冻结(let it go,let it go,sorry XD)。您必须关闭第四个窗口,然后是第三个,然后是第二个,然后才能到达主窗口。
看上去真的很乱。
我想通过只有一个活动/可见的窗口而不重写整个项目来改善这种情况。
当前,MainView(MainView.xaml.cs)使用以下代码打开一个新窗口:
var v = new MyNewView();
v.Owner = this;
v.ShowDialog();
字符串
在这个新视图中,您将获得具有以下内容的视图模型:
public MyNewView()
{
DataContext = ViewModelLocator.GetViewModelInstance<ModelContext, MyNewViewModel>(this);
InitializeComponent();
}
型
(ModelContext是DBContext)
ViewModelLocator是这样的:
public class ViewModelLocator
{
static ViewModelLocator()
{
Ioc.Default.ConfigureServices(
new ServiceCollection()
.AddSingleton<ApplicationContext>()
.AddTransient<MainViewModel>()
.AddTransient<MyNewViewModel>()
.BuildServiceProvider());
}
public static Tvm GetViewModelInstance<TContext, Tvm>(ICloseableEvent w, bool initializeContext = true) where Tvm : IDisposable where TContext : ModelContext
{
Tvm VMInstance = Ioc.Default.GetService<Tvm>();
if (initializeContext)
(VMInstance as CommonViewModel<TContext>)!.InitializeContext();
w.Closed += (sender, args) =>
{
WeakReferenceMessenger.Default.UnregisterAll(VMInstance);
VMInstance.Dispose();
};
return VMInstance;
}
}
型
我找到的解决方案是在MainView.xaml中定义一个ContentControl,如下所示:
<ContentControl x:Name="MainContent"/>
型
然后,我没有用“ShowDialog”打开一个新窗口,而是简单地用MyNewView的内容替换MainView的内容,就像这样(在MainView.xaml.cs中):
MyNewView myNewView = new MyNewView();
myNewView.Owner = App.MainView;
App.MainView.MainContent.Content = myNewView.Content;
App.MainView.Title = myNewView.Title;
myNewView.Close();
型
如果我关闭“MyNewView”,我只需使用MainView的内容重置MainContent。它工作(但我不确定这是否是一个好的解决方案)。但是,视图模型没有改变。视图仍然寻找MainViewModel而不是MyNewViewModel,即使“DataContext = ViewModelLocator.GetViewModelInstance<ModelContext,MyNewViewModel>(this);”正确调用。
所以,我不认为这是一个很好的解决方案,毕竟。
在WPF应用程序中从一个视图导航到另一个视图的最佳方法是什么(在.Net 6中使用MVVM)?
- 是否将Window转换为UserControl更好(MainView除外)?
- 是否有更好的方法来调用视图?
请让我知道如果你需要更多的细节,请理解,因为我是相当新的WPF,我只是想做正确的方式。
提前感谢!
1条答案
按热度按时间enyaitl31#
多亏了@Andy,我找到了一些可能的解决方案。
我没有试图解释我是如何做到的,而是创建了一个我所阐述的解决方案的示例项目。
左侧菜单有意消失以显示导航级别(子->父)。
https://github.com/damgot/WpfMvvmNavigationSample