我正在尝试将ContentControl的内容绑定到我在ViewModel中实例化的UserControl。我不能使用绑定到ViewModel的方法,然后让UserControl成为ViewModel的DataTemplate,因为我需要ContentControl的内容能够经常更改,使用相同的实例 UserControls / Views,每次重新绑定时都不实例化视图。
但是,当将UserControl属性设置为UserControl实例时,然后当呈现视图/数据绑定时,我得到:必须在连接到新父Visual之前断开指定子视图与当前父Visual。 / em>即使我以前没有将这个UserControl添加到任何地方,我只是提前创建了这个实例并将其保存在内存中。
有没有更好的方法来实现我的目标?
在ViewModel中
public class MyViewModel : INotifyPropertyChanged
{
//...
private void LoadApps()
{
var instances = new List<UserControl>
{
new Instance1View(),
new Instance2View(),
new Instance3View(),
};
SwitchInstances(instances);
}
private void SwitchInstances(List<UserControl> instances)
{
CenterApp = instances[0];
}
//...
private UserControl _centerApp;
public UserControl CenterApp
{
get { return _centerApp; }
set
{
if (_centerApp == value)
{
return;
}
_centerApp = value;
OnPropertyChanged("CenterApp");
}
}
//...
}
在View.xaml
中<ContentControl Content="{Binding CenterApp}"></ContentControl>
答案 0 :(得分:2)
评论太长了。
建立@Kent在评论中所说的内容,MVVM的重点是将视图模型与视图相关的东西(控件)断开连接,这些东西会阻止GUI应用程序的测试能力。因此,您拥有UserControl / Button /任何与图形视图相关的项目都会否定MVVM的整个原则。
如果使用MVVM符合其标准,然后重新解决您的问题,您应该这样做。
......还有更多。它在视图模型的范围内非常具体,没有视图相关的东西,例如甚至没有视图模型中的属性,如Visibility
。您通常持有bool
,然后在视图中使用转换器将其切换到Visibility
对象。
进一步了解MVVM肯定会对你有所帮助,
现在可以解决当前问题:
遵循MVVM结构,
你将拥有像
这样的ViewModelsMyViewModel
Instance1ViewModel
中单独列出或暂停Instance2ViewModel
,Instance3ViewModel
,MyViewModel
(自行创建或使用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
查看文件中,您应该(不必是最高级别)将顶级DataContext设置为MyViewModel
示例:
...
<Window.Resources>
<DataTemplate DataType="{x:Type local:Instance1ViewModel}">
<local:Instance1View />
</DataTemplate>
<DataTemplate DataType="{x:Type local:Instance2ViewModel}">
<local:Instance2View />
</DataTemplate>
<DataTemplate DataType="{x:Type local:Instance3ViewModel}">
<local:Instance3View />
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl Content="{Binding Path=CurrentFrame}" />
</Grid>
...
CurrentFrame
属性,并使其指向三个实例视图模型中的任何一个,视图将相应更新。这会让你获得一个符合MVVM标准的应用程序,因为你无需基于DataTemplate动态重新创建视图,你可以按照建议的方法here进行扩展,并根据自己的需要进行扩展。