[英]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.