C# 将数据从数据类传递到视图
我正在学习MVVM,并正在创建一个应用程序进行实践 我曾尝试制作一个应用程序,您可以添加和查看学生的所有内容,直到我尝试将可观察集合与ViewModel的其余部分分离,并能够将其用于其他ViewModels 我的问题是如何在每个视图中使用任何ViewModel之外的ObservableCollection或任何其他类型的数据保持器 告诉我你是否需要密码 这是包含数据的类 在解决方案资源管理器中,文件的路径是数据/数据库C# 将数据从数据类传递到视图,c#,wpf,mvvm,view,C#,Wpf,Mvvm,View,我正在学习MVVM,并正在创建一个应用程序进行实践 我曾尝试制作一个应用程序,您可以添加和查看学生的所有内容,直到我尝试将可观察集合与ViewModel的其余部分分离,并能够将其用于其他ViewModels 我的问题是如何在每个视图中使用任何ViewModel之外的ObservableCollection或任何其他类型的数据保持器 告诉我你是否需要密码 这是包含数据的类 在解决方案资源管理器中,文件的路径是数据/数据库 public class StudentDatabase { #re
public class StudentDatabase
{
#region Defining and Populating an ObservableCollection
// Defining an observable collection to hold the students
private ObservableCollection<Student> studentData;
// Populating the ObservableCollection
public StudentDatabase()
{
studentData = new ObservableCollection<Student>()
{
new Student(){Name="John", Surname="Smith", Age=17},
new Student(){Name="Barbara", Surname="Johnson", Age=16}
};
}
// Defining and setting the field for the Observable collection
public ObservableCollection<Student> StudentData
{
get { return studentData; }
set { RaisePropertyChanged("studentData"); }
}
#endregion
#region RaisePropertyChange implementation
/// <summary>
/// INotifyPropertyChanged implementation:
/// A property notifies something that it has changed
/// and the other object get's the new data
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
我在visual studio的输出窗口中遇到此错误
System.Windows.Data Error: 40 : BindingExpression path error: 'Data' property not found on 'object' ''StudentDatabase' (HashCode=2650314)'. BindingExpression:Path=Data.StudentDatabase; DataItem='StudentDatabase' (HashCode=2650314); target element is 'ListBox' (Name=''); target property is 'DataContext' (type 'Object')
我希望列表框的更新是动态的,所以我不包括更新按钮
编辑:我已经更新了代码,但我认为我没有再做正确的事情,有人能给我指路吗
编辑:如果我在codebehind中设置DataContext,一切正常,但是如果我尝试在XAML中为特定控件设置DataContext onlt,则我不获取列表,并且不显示数据
这里是我上传项目的链接
如果代码隐藏是这样的,那么一切都正常
InitializeComponent();
DataContext = new Data.StudentDatabase();
但是如果我不使用codebehind并在XAML中这样做,什么都不会发生
DataContext="{Binding Path=Data.StudentDatabase}"
我显然在这里遗漏了一些东西这是一个应用程序设计问题。如果希望与所有视图共享一个集合,则需要将其放入应用程序视图模型中,类似于
MainViewModel
。此外,您还需要具有albe才能从所有视图访问它,为此,您可以在要显示集合的每个视图的视图模型中引用MainViewModel
。另一种方法是共享MainViewModel
实例,您可以将其保存在应用程序资源中。如果使用Galasoft MVVMLight Toolkit
,则可以通过ViewModelLocator
访问MainViewModel
。希望这些想法能帮助
编辑
添加代码后,我可以注意到您对
ViewModel
模式的理解不是很好。您的类StudentObservableCollection
应该是StudentViewModel
,并且它应该只有student属性。此外,您还需要为创建一个类来管理StudentViewModel
s。在此类中,您应该具有StudentsData
或observedcollection
,在此类中,您还可以具有StudentViewModel
类型的其他属性,如SelectedStudent
。正如我在最初的回答中所说,如果学生集合应该可以在应用程序中的多个视图上保存,那么您可以在全局视图模型中创建它。这是一个应用程序设计问题。如果希望与所有视图共享一个集合,则需要将其放入应用程序视图模型中,类似于MainViewModel
。此外,您还需要具有albe才能从所有视图访问它,为此,您可以在要显示集合的每个视图的视图模型中引用MainViewModel
。另一种方法是共享MainViewModel
实例,您可以将其保存在应用程序资源中。如果使用Galasoft MVVMLight Toolkit
,则可以通过ViewModelLocator
访问MainViewModel
。希望这些想法能帮助
编辑 添加代码后,我可以注意到您对
ViewModel
模式的理解不是很好。您的类StudentObservableCollection
应该是StudentViewModel
,并且它应该只有student属性。此外,您还需要为创建一个类来管理StudentViewModel
s。在此类中,您应该具有StudentsData
或observedcollection
,在此类中,您还可以具有StudentViewModel
类型的其他属性,如SelectedStudent
。正如我在最初的回答中所说,如果学生集合可以在应用程序中的多个视图上浏览,您可以在全局视图模型中创建它。George
如果您希望在整个应用程序中共享数据库之类的内容,您可以在主窗口中创建资源,并且在主窗口的可视树下定义的任何控件都可以访问该资源
因此,在主窗口XAML中,执行以下操作:
<Window.Resources>
<local:StudentDatabase x:Key="StudentDatabase"/>
<Window>Resources>
乔治
如果您希望在整个应用程序中共享数据库之类的内容,您可以在主窗口中创建资源,并且在主窗口的可视树下定义的任何控件都可以访问该资源
因此,在主窗口XAML中,执行以下操作:
<Window.Resources>
<local:StudentDatabase x:Key="StudentDatabase"/>
<Window>Resources>
如果我想在其他视图中使用AllStudents,会发生什么?那么您所要做的就是将创建的
AllStudentsViewModel
对象的实例传递给您的视图。这就是学习MVVM并提出一个好的设计的乐趣。创建对象后,可以将其保留。然后,根据用户的操作,显示一个控件,您所要做的就是为它设置控件DataContext以填充数据。要继续使用MVVM或更重要的WPF,您必须了解DataContext。因此,我不需要为整个视图设置DataContext,只需要为控件设置DataContext。如果我创建一个不同的类来保存数据,并将其用作DataContext,而不是将数据放在其中一个ViewModel中,那么会有问题吗?这没有问题。这有点像数据库的工作原理。。。您存储数据,然后在需要时获取数据(称为获取上下文)并显示数据。如果我想在其他视图中使用AllStudents,会发生什么情况?然后您只需传递创建的AllStudentsViewModel
对象的实例,在你看来,这就是学习MVVM并提出一个好的设计的乐趣。创建对象后,可以将其保留。然后,根据用户的操作,显示一个控件和您拥有的所有内容
<Window.Resources>
<local:StudentDatabase x:Key="StudentDatabase"/>
<Window>Resources>
<Window x:Class="Project.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Project"
Title="Search" Height="300" Width="300">
<Window.Resources>
<local:StudentDatabase x:Key="StudentDatabase"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<ListBox x:Name="StudentItemListBox"
Grid.Row="5" Grid.ColumnSpan="3"
DataContext="{StaticResource StudentDatabase}"
ItemsSource="{Binding StudentData}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Surname}"
Grid.Column="1"/>
<TextBlock Text="{Binding Age}"
Grid.Column="2"/>
<!--Here go some other info about the students-->
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel>
<Button x:Name="Exit"
<!--TO-DO: Write an exit command-->/>
</StackPanel>
</Grid>