C# WPF MVVM-将多个视图/视图模型绑定到同一个基本视图模型
我有一个使用MVVM模式的WPF应用程序。有一个视图沿顶部有5-6个选项卡。每个选项卡都是一个包含表单的视图,然后数据加载到表单下方的视图中 每个选项卡式视图中的表单几乎完全相同,其中一些表单只具有一个附加字段。我想这样做,当用户在一个选项卡上填写表单时,当您切换到另一个选项卡时,表单值将自动与您在其他选项卡中输入的内容结转 我现在尝试使用的实现包括一个“BaseViewModel”,其中包含如下属性C# WPF MVVM-将多个视图/视图模型绑定到同一个基本视图模型,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个使用MVVM模式的WPF应用程序。有一个视图沿顶部有5-6个选项卡。每个选项卡都是一个包含表单的视图,然后数据加载到表单下方的视图中 每个选项卡式视图中的表单几乎完全相同,其中一些表单只具有一个附加字段。我想这样做,当用户在一个选项卡上填写表单时,当您切换到另一个选项卡时,表单值将自动与您在其他选项卡中输入的内容结转 我现在尝试使用的实现包括一个“BaseViewModel”,其中包含如下属性 private string _SelectedProjectCollection;
private string _SelectedProjectCollection;
public string SelectedProjectCollection
{
get => _SelectedProjectCollection;
set
{
_SelectedProjectCollection = value;
OnPropertyChanged(nameof(SelectedProjectCollection));
}
}
public string SelectedProjectCollection
{
get => base.SelectedProjectCollection;
set
{
base.SelectedProjectCollection = value;
OnPropertyChanged(nameof(SelectedProjectCollection));
if (value != null)
{
RefreshProjectList();
}
}
}
然后,各个选项卡的ViewModels继承自BaseViewModel,并包含如下代码
private string _SelectedProjectCollection;
public string SelectedProjectCollection
{
get => _SelectedProjectCollection;
set
{
_SelectedProjectCollection = value;
OnPropertyChanged(nameof(SelectedProjectCollection));
}
}
public string SelectedProjectCollection
{
get => base.SelectedProjectCollection;
set
{
base.SelectedProjectCollection = value;
OnPropertyChanged(nameof(SelectedProjectCollection));
if (value != null)
{
RefreshProjectList();
}
}
}
我需要将它们放入各个选项卡ViewModels中,因为它们的每个RefreshProjectList方法将应用稍有不同的逻辑,因此我无法将第二个代码块放入BaseViewModel中
我已经设置了断点来监视数据流。当一个选项卡填充表单时,BaseViewModel的属性似乎会更改,但当我切换到另一个选项卡时,表单不会填充来自基础的值,尽管表单的组合框被赋予了绑定
xaml示例中的组合框绑定:
<ComboBox Grid.Row="0" Grid.Column="0" materialDesign:HintAssist.Hint="Project Collection" IsEditable="True" Style="{StaticResource MaterialDesignFloatingHintComboBox}" ItemsSource="{Binding Path=ProjectCollectionList}" SelectedItem="{Binding Path=SelectedProjectCollection, Mode=TwoWay}"></ComboBox>
如果有任何建议能把我引向正确的方向,我将不胜感激。解决这个问题的方法之一就是使用合成。如果使用所需的数据属性创建一个类,则可以在行为类中代理它们
公共类MyData:INotifyPropertyChanged
{
私有字符串_myProp;
公共字符串MyProp
{
get=>\u myProp;
设置
{
_myProp=值;
OnPropertyChanged();
}
}
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共类视图模型:INotifyPropertyChanged
{
私有只读MyData\u数据;
公共视图模型(MyData)
{
_数据=数据;
}
公共字符串MyProp
{
get=>\u data.MyProp;
set=>\u data.MyProp=value;
}
公共事件属性ChangedEventHandler属性已更改
{
add=>\u data.PropertyChanged+=值;
移除=>\u data.PropertyChanged-=值;
}
}
注意这将触发一个事件,发送方为
MyData
,如果希望ViewModel成为发送方,则需要实现INotifyPropertyChanged
,侦听该事件并使用新发送方调用外部事件。然后,您需要在处理侦听器的位置实现IDisposable
。您可以将RefreshProjectList()作为一个没有主体的虚拟/抽象函数放在基类上,并在各个视图模型中重写这些函数。那么你就不需要重写这个属性了。所有的数据都应该是一样的吗?但是您没有在所有选项卡上显示某些属性?基本上所有选项卡都有一个B C和D,一些选项卡也有E。我希望的是,当您在选项卡1上完成输入时,当您切换到选项卡2时,表单应该已经完成了输入。任何viewmodel都应该实现inpc。如果你不这样做,你会有内存泄漏的。@Andy我承认,我曾试图让大家明白这一点,我同意最好不要在这里有这样的例子,因为它们经常被复制,我会更新:)