Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF MVVM-将多个视图/视图模型绑定到同一个基本视图模型_C#_Wpf_Mvvm - Fatal编程技术网

C# WPF MVVM-将多个视图/视图模型绑定到同一个基本视图模型

C# WPF MVVM-将多个视图/视图模型绑定到同一个基本视图模型,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个使用MVVM模式的WPF应用程序。有一个视图沿顶部有5-6个选项卡。每个选项卡都是一个包含表单的视图,然后数据加载到表单下方的视图中 每个选项卡式视图中的表单几乎完全相同,其中一些表单只具有一个附加字段。我想这样做,当用户在一个选项卡上填写表单时,当您切换到另一个选项卡时,表单值将自动与您在其他选项卡中输入的内容结转 我现在尝试使用的实现包括一个“BaseViewModel”,其中包含如下属性 private string _SelectedProjectCollection;

我有一个使用MVVM模式的WPF应用程序。有一个视图沿顶部有5-6个选项卡。每个选项卡都是一个包含表单的视图,然后数据加载到表单下方的视图中

每个选项卡式视图中的表单几乎完全相同,其中一些表单只具有一个附加字段。我想这样做,当用户在一个选项卡上填写表单时,当您切换到另一个选项卡时,表单值将自动与您在其他选项卡中输入的内容结转

我现在尝试使用的实现包括一个“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继承自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我承认,我曾试图让大家明白这一点,我同意最好不要在这里有这样的例子,因为它们经常被复制,我会更新:)