我们正在连接我们的视图并“外部”查看模型,这意味着我们在某处有以下类型的代码:
var viewModel = new MyViewModel();
var view = Application.Current.FindResource("MyView") as UserControl;
view.DataContext = viewModel;
这是一种解释。我们这样做是为了包含所有视图的dll可以在运行时切换出来。只要dll定义了一个名为“MyView”的资源,它指向用户控件MyView,一切都很好。
我担心的是确保FindResource不会因为执行以下操作而受到影响或处于劣势:
var view = new MyView();
这可以用IoC取代。 (我们不允许用户切换使用哪个视图DLL。确定应用程序何时启动。)
我发现FindResource的一件事是你可能不得不使用x:Shared="False"
,否则WPF会将你送回现有的实例,你必须确保它已经“初始化”回到原来的状态。
有什么想法?
答案 0 :(得分:2)
将UIElement实例声明为Resources几乎总是一个坏主意。你已经看到了这样做的一个主要问题(和解决方法)。它也很容易导致内存泄漏,因为应用程序级资源中的项目在启动时被实例化并保持在那里直到应用程序关闭(除非你做更多的手动工作以强制它们清理)。
使用模板是一个更好的解决方案,它应该很容易从你正在做的转换。模板将根据需要实例化其子元素的新实例,并在本地注入它们,就好像它们是内联声明的一样。只需将现有的UserControl声明包装在DataTemplate元素中,然后移动x:Key声明即可。然后当你到达上面的代码时(也可以在XAML中完成,或者可能在DataType模板中隐式完成),执行:
var viewModel = new MyViewModel();
var view = Application.Current.FindResource("MyView") as DataTemplate;
var control = new ContentControl { Content = viewModel, ContentTemplate = view };