我正在研究MVVM,并正在为练习创建应用程序
我试图制作一个可以添加和查看学生所有内容的应用程序,直到我尝试将Observable Collection与ViewModel的其余部分分开,并能够将其用于其他ViewModels为止。
我的问题是如何在每个View中使用ObservableCollection或任何ViewModel之外的任何其他类型的数据持有人?
告诉我您是否需要代码?
这是带有数据的类
在解决方案资源管理器中,文件的路径为“数据/数据库”
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
}
这是我要显示它的页面的XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="15*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox DataContext="{Binding Path=Data.StudentDatabase}"
ItemsSource="{Binding StudentData}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="Name"
Grid.Column="0"
Text="{Binding Name}"/>
<TextBlock x:Name="Surname"
Grid.Column="1"
Text="{Binding Surname}"/>
<TextBlock x:Name="Age"
Grid.Column="2"
Text="{Binding Age}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
和搜索窗口中的c敏代码
public partial class Search: Window
{
public Search()
{
InitializeComponent();
}
}
我在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')
我希望列表框的更新是动态的,所以我不包括“更新”按钮
编辑:我已经更新了代码,但是我认为我没有再做正确的事,有人可以照亮我吗?
编辑:如果我在代码隐藏中设置DataContext一切都很好,但是如果我尝试为XAML中的特定控件设置DataContext onlt,那么我不会得到列表不显示数据
这是我上传项目的Skydrive的链接
如果背后的代码是这样,一切正常
InitializeComponent();
DataContext = new Data.StudentDatabase();
但是,如果我不使用背后的代码,而是在XAML中这样做,则不会发生任何事情
DataContext="{Binding Path=Data.StudentDatabase}"
我显然在这里缺少什么
最佳答案
这是一个应用程序设计问题。如果要与所有 View 共享一个集合,则需要将其放入应用程序 View 模型中,例如MainViewModel
。另外,您还可能需要从所有 View 访问它,为此,您可能在要显示集合的每个 View 的 View 模型中都有MainViewModel
的引用。另一种方法是共享MainViewModel
实例,您可以将其保存在应用程序资源中。如果您使用Galasoft MVVMLight Toolkit
,则可以在MainViewModel
中访问ViewModelLocator
。希望这个想法对您有帮助...
编辑
添加代码后,我可以注意到您对ViewModel
模式不太了解。您的类(class)StudentObservableCollection
应该是StudentViewModel
,并且应该仅具有学生属性。另外,您还需要一个类来管理StudentViewModel
。在此类中,您应该具有StudentsData
或ObservableCollection<StudentViewModel>
,在此类中,您可能还具有其他属性,例如SelectedStudent
类型的StudentViewModel
。就像我在原始答案中说的那样,如果应在应用程序中的多个 View 上使用学生集合,则可以在全局 View 模型中创建它。
关于c# - 将数据从数据类传递到 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20201982/