[英]WPF: Databinding to a DataGrid
这是我在这个论坛上的第一篇文章,尽管我是一个长期的潜伏者。 我已经开始学习WPF大约两个月了,我正在尝试创建一个仅用于培训目的的应用程序。
我有一个后端数据库,该数据库已使用EF6 ORM添加到我的应用程序中。 在我的应用程序中,我有一个`ComboBox,需要由数据库表中的一列填充。 我可以使用绑定到列表来完成。
我遇到麻烦的部分是DataGrid
。 需要根据ComboBox
选择的Item
填充DataGrid
的列。
我的数据库:
如您所见,学校有几个系,每个系都有一个HOD和一个学生实力。
我的应用程序:
ComboBox
将填充学校名称。 选择学校名称后,将填充DataGrid
。 DataGrid
将为学校的每个部门提供每一行。 因此,我需要将相应的列与相应学校的部门绑定。 我得到了。 但是,然后我想将用户输入的注释保存在Feedback TextBox
。
我不明白如何创建一个类,以便可以将DataGrid
绑定到它的对象。 是否可以将DataGrid
绑定到对象,然后将列分别绑定到另一个对象?
编辑
除了从数据库创建的实体之外,我还有两个类:
class Feedback : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _school;
public string School
{
get
{
return _school;
}
set
{
_school = value;
OnPropertyChanged("School");
}
}
private ObservableCollection<FeedbackLine> _feedbackLines;
public ObservableCollection<FeedbackLine> FeedbackLines
{
get
{
return _feedbackLines;
}
set
{
_feedbackLines = value;
OnPropertyChanged("FeedbackLines");
}
}
public Feedback(string school)
{
//Insert some Linq Query to populate the FeedbackLines
//something like
//var FeedbackLines = Context.Schools.Where(c => c.SchoolName == school)
// .Select(c => new {Department = c.AvailableDepts.Dept, etc etc}.ToList();
//but then what?
}
private void OnPropertyChanged(string v)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(v));
}
}
这应该绑定到数据网格。 而FeedbackLine是:
public class FeedbackLine: INotifyPropertyChanged
{
private string _dept;
public string Department
{
get { return _dept; }
set { _dept = value;
OnPropertyChanged("Department");
}
}
private string _HOD;
public string HOD
{
get { return _HOD; }
set { _HOD = value;
OnPropertyChanged("HOD");
}
}
private int _strength;
public int Strength
{
get { return _strength; }
set { _strength = value;
OnPropertyChanged("Strength");
}
}
private bool _isSelected;
public bool Selected
{
get { return _isSelected; }
set { _isSelected = value;
OnPropertyChanged("Selected");
}
}
private string _comment;
public string Comment
{
get { return _comment; }
set { _comment = value;
OnPropertyChanged("Comment");
}
}
private void OnPropertyChanged(string v)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(v));
}
public event PropertyChangedEventHandler PropertyChanged;
}
我在ViewModel上没有什么进展。 问题是,我对LINQ不太满意。 而且有太多的类和对象,我不知道该绑定哪个类和对象。 我能得到的唯一模糊的想法是,我必须使用LINQ来使用选定的School
来查询数据库,然后使用该表来填充FeedbackLines
。
编辑2:对于感兴趣的任何人,这是我在WPF中的模型图 : 模型图
编辑3:我认为我对ViewModel感到困惑。 屏幕上显示的数据不一定是要保存的数据。 例如,我不想保存未选择的行。 我的Feedback
类尝试显示并保存数据。 问题就在这里。 不能将DataGrid
绑定到对象,而将其列绑定到其他对象? 例如,如果我选择对部门使用组合Combobox
。 然后,我需要使用ItemsSource
来显示项目,但只需要保存SelectedItem
。 我找不到将这两个问题分开的方法。
我会更改您的Feedback构造函数
public Feedback(string school, List<FeedbackLine> feedbackLines)
{
School = school;
FeedbackLines = new ObservableColleytion<FeedbackLine>(feedbackLines);
}
如果您的数据视图模型没有与数据库的连接,则它是一种更好的体系结构。 您可以将选择放在单独的类中。
如果您需要有关LINQ语句的帮助,我可以为您提供帮助。
在您的Feedback构造函数中,您编写了
//but then what?
收到数据后,您可以创建FeedbackLines实例,以将它们添加到上面显示的新构造函数中。
完成此操作后,您的viewmodel(即视图的DataContext)需要一个
public void ObservableCollection<Feedback> Feedbacks
使用INotifyPropertyChanged就像在其他视图模型中一样。
在您的xaml中,您可以在学校中找到ComboBox。 给该组合框起一个名字,例如SchoolsComboBox。 在您的DataGrid中编写以下行
Source={Binding ElementName=SchoolsComboBox, Path=SelectedItem.FeedbackLines}
/ edit用于添加LINQ您创建了一个匿名类型。 只需创建一个FeedbackLine,就可以了。
var feedbackLines = Context.Schools.Where(c => c.SchoolName == school)
.Select(c => new FeedbackLine
{
Department = c.AvailableDepts.Dept,
HOD = c.AvailableDepts.HeadOfDept,
Strength = c.AvailableDepts.StudentStrength}
.ToList()
你可以做这样的事情。 我敢肯定它可以写得更好,但它可以工作。
在您的ViewModel中,制作3个实现INotifyPropertyChanged的属性
一个用于您的集合,它将绑定到您的ComboBox(将其设置为ObservableCollection),一个用于您的ComboBox的SelectedItem(将其绑定到comboBox中的SelectedItem),另一个用于将ObservableCollection绑定到DataGrid)
例如,您在XAML中:
<Grid>
<ComboBox ItemsSource="{Binding Products}"
SelectedItem="{Binding SelectedProduct}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="200"
Margin="20"
IsSynchronizedWithCurrentItem="True" />
<DataGrid ItemsSource="{Binding SelectedOne}"
HorizontalAlignment="Right "
VerticalAlignment="Center"
Width="300"
IsSynchronizedWithCurrentItem="True">
</DataGrid>
在您的ViewModel中,您可以拥有类似的内容。
public ObservableCollection<Product> Products
{
get { return _products; }
set
{
if (value != _products)
{
_products = value;
OnPropertyChanged();
}
}
}
private ObservableCollection<Product> _selectedOne;
public ObservableCollection<Product> SelectedOne
{
get { return _selectedOne; }
set {
_selectedOne = value;
OnPropertyChanged();
}
}
public int SelectedProductId
{
get { return _selectedProductId; }
set
{
if (value != _selectedProductId)
{
_selectedProductId = value;
OnPropertyChanged();
}
}
}
public Product SelectedProduct
{
get { return _selectedProduct; }
set
{
if (value ! = _selectedProduct)
{
_selectedProduct = value;
// clear your list of selected objects and then add just selected one
// or you dont clear it, and items will be added in DataGrid when selected in ComboBox
SelectedOne.Clear();
SelectedOne.Add(_selectedProduct);
OnPropertyChanged();
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
通过代码填充产品,可以通过从ComboBox中选择Item来填充DataGrid。
您可以进入ViewModel构造函数并进行类似的操作。
public MainWindowViewModel()
{
if (!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
using (YourDbContext context = new YourDbContext ())
{
var productList = new ObservableCollection<Product>(context.Products);
productList.ToList()
Products = productsList;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.