Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.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# 从不同的ViewModel访问数据_C#_Wpf_Mvvm_Viewmodel_Mvvm Light - Fatal编程技术网

C# 从不同的ViewModel访问数据

C# 从不同的ViewModel访问数据,c#,wpf,mvvm,viewmodel,mvvm-light,C#,Wpf,Mvvm,Viewmodel,Mvvm Light,我希望在单个视图中访问不同ViewModel的数据。 但是DataContext是完全不同的(MainView中的MainViewModel)。是否可以为每个窗口控件设置相应的ViewModel? 还是只在MainViewModel中创建和引用ObservableCollection学生更好 目前,我想将ViewModelStudentViewModel中的属性Students分配给这个组合框 MainViewModel(将ApplicationViewModel设置为CurrentViewMo

我希望在单个视图中访问不同ViewModel的数据。 但是DataContext是完全不同的(MainView中的MainViewModel)。是否可以为每个窗口控件设置相应的ViewModel? 还是只在MainViewModel中创建和引用
ObservableCollection学生
更好

目前,我想将ViewModel
StudentViewModel
中的属性
Students
分配给这个组合框

MainViewModel(将ApplicationViewModel设置为CurrentViewModel)

ApplicationViewModel和StudentViewModel(加载数据并创建ObservableCollection)

公共类应用程序ViewModel:ViewModelBase
{
公共应用程序视图模型()
{
}
}
公共类StudentViewModel:ViewModelBase
{
私立大学学生;
公共学生视图模型()
{
DataStudentService dataService=新的DataStudentService();
学生=新的ObservableCollection(dataService.GetAllStudents());
}
公选学生
{
get=>\u学生;
专用设备
{
如果(_students==value)返回;
_学生=价值观;
RaisePropertyChanged(“学生”);
}
}
}
MainView.xaml(设置要显示的CurrentViewModel)


应用程序视图.xaml(当前显示)


最直接的解决方案是坚持MVVM模式,创建一个集合并用您已经提到的其他类的数据填充它。这很容易,每个人都知道发生了什么。此外,这样数据的上下文就保持在同一个viewmodel中,如果您更改了某些内容,它也会保持在该上下文中。在您的情况下,这意味着您必须创建一个
observeCollection Students
,并将其内容填入
MainViewModel


如果必须从整个应用程序访问这些数据,您应该考虑实现一个数据管理器(例如单例),而不是在每个viewmodel中复制数据

找到了一个解决方案:

MainViewModel

public class MainViewModel : ViewModelBase
{
    public StudentViewModel StudentViewModel { get; set; }

    public MainViewModel()
    {
        StudentViewModel = new StudentViewModel();
    }
}
private ObservableCollection<Student> _students;

public ObservableCollection<Student> Students
    {
        get => _students;
        set
            {
                if (_students == value) return;
                _students = value;
                RaisePropertyChanged("Students");
            }
        }
MainView

<ComboBox
DataContext="{Binding StudentViewModel}"
ItemsSource="{Binding Path=Students, UpdateSourceTrigger=PropertyChanged}"
/>

学生视图模型

public class MainViewModel : ViewModelBase
{
    public StudentViewModel StudentViewModel { get; set; }

    public MainViewModel()
    {
        StudentViewModel = new StudentViewModel();
    }
}
private ObservableCollection<Student> _students;

public ObservableCollection<Student> Students
    {
        get => _students;
        set
            {
                if (_students == value) return;
                _students = value;
                RaisePropertyChanged("Students");
            }
        }
private observedcollection\u学生;
公选学生
{
get=>\u学生;
设置
{
如果(_students==value)返回;
_学生=价值观;
RaisePropertyChanged(“学生”);
}
}

请注意,您同时绑定SelectedValue、SelectedItem和SelectedIndex看起来很奇怪。通常只绑定其中一个。在所有绑定上设置
Mode=TwoWay
UpdateSourceTrigger=PropertyChanged
也是多余的。虽然这些设置已经是
Selected…
属性的默认值,但它们对
ItemsSource
绑定没有任何影响。@Clemens:谢谢您的提示,我使用SelectedStudentIndex重置选择(“-1”)。我正在尝试减少其他参数a ViewModel可以具有(子)ViewModels的属性,这没有问题。仅使用SelectedValue,通过将Name设置为不存在的值(例如null),可以进行重置。或者在没有SelectedValue(Path)的情况下,将SelectedItem设置为null。是的,请注意它是
Binding Path=Students
,而不是
Binding Property=Students
。路径意味着它可以是a.b.C谢谢你的回复!不幸的是,我有太多可观察到的收集。我希望在各自的viewmodel中保留所有相同的类元素
<ComboBox
DataContext="{Binding StudentViewModel}"
ItemsSource="{Binding Path=Students, UpdateSourceTrigger=PropertyChanged}"
/>
private ObservableCollection<Student> _students;

public ObservableCollection<Student> Students
    {
        get => _students;
        set
            {
                if (_students == value) return;
                _students = value;
                RaisePropertyChanged("Students");
            }
        }