将ContentControl绑定到UserControl,并重用相同的实例
我正在尝试将ContentControl的内容绑定到我在ViewModel中实例化的UserControl。 我不能使用绑定到ViewModel的方法,然后让UserControl成为ViewModel的DataTemplate,因为我需要ContentControl的内容能够使用UserControls / Views的相同实例频繁更改,而不是实例化每次重新绑定时的视图。
但是,当将UserControl属性设置为UserControl实例时,然后当呈现视图/数据绑定时,我得到: 必须在连接到新的父Visual之前断开指定的子视图与当前父Visual。 即使我以前没有将此UserControl添加到任何地方,我只是更早地创建了这个实例并将其保存在内存中。
有没有更好的方法来实现我的目标?
在ViewModel中
public class MyViewModel : INotifyPropertyChanged { //... private void LoadApps() { var instances = new List { new Instance1View(), new Instance2View(), new Instance3View(), }; SwitchInstances(instances); } private void SwitchInstances(List instances) { CenterApp = instances[0]; } //... private UserControl _centerApp; public UserControl CenterApp { get { return _centerApp; } set { if (_centerApp == value) { return; } _centerApp = value; OnPropertyChanged("CenterApp"); } } //... }
在View.xaml中
评论太久了。
建立@Kent在评论中所说的内容,MVVM的重点是将视图模型与视图相关的东西(控件)断开连接,这些东西会阻止GUI应用程序的测试能力。 因此,您拥有UserControl / Button /任何与图形视图相关的项目都会否定MVVM的整个原则。
如果使用MVVM符合其标准,然后重新解决您的问题,您应该这样做。
- 使用MVVM,您通常有1个视图< - > 1个视图模型
- View了解其View模型(通常通过DataContext)。 反向不应编入。
- 您尝试将控制视图的逻辑放在视图模型中以允许测试逻辑(命令和INPC属性)
……还有更多。 它在视图模型的范围内非常具体,没有视图相关的东西,例如甚至在视图模型中都没有像Visibility
这样的属性。 您通常持有bool
,然后在视图中使用转换器将其切换到Visibility
对象。
再读一下MVVM肯定会对你有所帮助,
现在要解决当前问题:
遵循MVVM结构,
你将拥有像ViewModels这样的
- 主要:
MyViewModel
- 从基础派生所有实例ViewModel,以允许它们保存在列表中。
- 在
MyViewModel
单独列出或保持Instance1ViewModel
,Instance2ViewModel
,Instance3ViewModel
(要么自己创建,要么使用IOC容器让它注入它) - 让
MyViewModel
公开一个属性,就像发布的示例一样:
例:
// ViewModelBase is the base class for all instance View Models private ViewModelBase _currentFrame; public ViewModelBase CurrentFrame { get { return _currentFrame; } private set { if (value == _currentFrame) return; _currentFrame = value; OnPropertyChanged(() => CurrentFrame); } }
- 现在在
MyView.xaml
View文件中,您应该(不必是顶级)将顶级DataContext设置为MyViewModel
- 您的View的xaml可以声明为:
例:
... ...
- 而已!。 现在,您只需在视图模型中切换
CurrentFrame
属性,并使其指向三个实例视图模型中的任何一个,并且视图将相应地更新。
这将为您提供一个符合MVVM的应用程序,因为您无需基于DataTemplate动态地重新创建视图,您可以按照此处建议的方法进行处理,并根据自己的需要进行扩展。