Представьте себе что-то вроде этого:
IList<ProductEntity> emp = HibernateDao.fetchDAta();
//seems no-op, did you miss a mapping call? : IList<ProductModel> products = new List<ProductModel>();
BindingSource bs = new BindingSource();
bs.DataSource = emp; //emp will need to be a bindable list; does fetchData do a ToList() ?
bs.Filter = "[product_name] = 'cornflakes'";
dataGridView1.Columns.Clear();
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = bs;
Вы не можете заставить DataGridView отображать два свойства в одном столбце, поэтому с типом e.quantity + " " + e.units
ничего не получится. Вам нужно будет добавить свойство (не поле) в ProductModel, которое возвращает эти два значения в виде одной строки
Привязка данных не является сложной задачей. В некотором смысле вы уже делаете часть этого. Этот l oop, который у вас был, повторял модель данных и запихивал все в сетку - привязка данных сделает это за вас, если вы просто установите источник данных сетки на список, который поддерживает привязку, тогда сетка создаст одну строку для каждого списка item (и в режиме автогенерирования столбцов он будет создавать один столбец на каждое простое свойство, которое он находит). Более хитрый аспект привязки заключается в том, что когда вы меняете модель (и вы должны изменять данные, изменяя модель, а не программно изменяя ячейки сетки), сетка обновляется, чтобы отразить изменения
Это помогает достичь разделение проблем, которые представляет модель / представление / контроллер
Изменить:
Если HibernateDao.fetchDAta()
возвращает что-то, что не реализует интерфейс IBindingListView, вы можете подумать:
Чтобы установить пакет nuget morelinq
; в нем есть методы для преобразования списков объектов в таблицы данных, а таблицы данных полностью поддерживают фильтрацию, ИЛИ
Для установки пакета nuget System.Linq.Dynamic
; он может позволить вам запрашивать вещи с помощью linq, записывая строковые выражения
Создайте новый проект и полностью замените содержимое Form1.vb этой демонстрацией:
Imports System.Linq.Dynamic
Imports MoreLinq
Public Class Form1
Class Person
Property Name As String
Property Age As Integer
End Class
Private dgvDL As New DataGridView
Private dgvBLV As New DataGridView
Private tb As New TextBox
Private people As List(Of Person)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim names() = {"John", "James"}
people = names.Select(Function(x) New Person With {.Name = x, .Age = x.Length * 7}).ToList()
'dynamic linq dgv
dgvDL.DataSource = people
Me.Controls.Add(dgvDL)
'morelinq DGV
Dim bs As New BindingSource
bs.DataSource = people.ToDataTable()
dgvBLV.DataSource = bs
Me.Controls.Add(dgvBLV)
'irrelevant UI code
AddHandler tb.TextChanged, AddressOf TextChange
Me.Controls.Add(tb)
dgvBLV.Location = New Point(dgvDL.Right, dgvDL.Top) 'place adjacent to above grid
tb.Location = New Point(dgvDL.Left, dgvDL.Height)
End Sub
Private Sub TextChange(sender As Object, e As EventArgs)
If (tb.Text = "") Then
dgvDL.DataSource = people 'filter DL grid
DirectCast(dgvBLV.DataSource, BindingSource).RemoveFilter() 'filter BLV grid
Else
dgvDL.DataSource = people.Where("Name == @0", tb.Text).ToList() 'filter DL grid
DirectCast(dgvBLV.DataSource, BindingSource).Filter = $"[Name] = '{tb.Text}'" 'filter BLV grid
End If
End Sub
End Class
Обратите внимание: если вы готовы фильтровать вещи с помощью LINQ, который не использует встроенный строковый фильтр, вам не нужны эти вспомогательные библиотеки; вы можете просто использовать обычный LINQ - см. в методе TextChange
, я говорю .Where("Name == @0", tb.Text)
- поскольку Name
здесь жестко запрограммирован, это также может быть .Where(Function(x) x.Name = tb.Text)
. Dynami c LINQ действительно делает вашу жизнь немного проще, если вы также создаете левую часть
-
Редактировать
C# версию, а не версию огромный отход от VB. Не уверен, почему мой мозг соскользнул в VB. NET, но я оставил VB выше, чтобы вы могли сравнить с этим, как «вот как читать VB». В наши дни эти два языка почти одинаковы, но для пары ключевых слов и точек с запятой, и всегда полезно знать, как читать другие варианты. NET:
using System.Linq.Dynamic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System;
using System.Collections.Generic;
using MoreLinq;
namespace WindowsFormsApp1
{
public partial class Form1: Form
{
public Form1()
{
base.Load += Form1_Load;
}
public partial class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
private DataGridView dgvDL = new DataGridView();
private DataGridView dgvBLV = new DataGridView();
private TextBox tb = new TextBox();
private List<Person> people;
private void Form1_Load(object sender, EventArgs e)
{
var names = new string[] { "John", "James" };
people = names.Select(x => new Person() { Name = x, Age = x.Length * 7 }).ToList();
// dynamic linq dgv
dgvDL.DataSource = people;
this.Controls.Add(dgvDL);
// morelinq DGV
var bs = new BindingSource();
bs.DataSource = people.ToDataTable();
dgvBLV.DataSource = bs;
this.Controls.Add(dgvBLV);
// irrelevant UI code
this.tb.TextChanged += TextChange;
this.Controls.Add(tb);
dgvBLV.Location = new Point(dgvDL.Right, dgvDL.Top); // place adjacent to above grid
tb.Location = new Point(dgvDL.Left, dgvDL.Height);
}
private void TextChange(object sender, EventArgs e)
{
if (tb.Text == "")
{
dgvDL.DataSource = people; // filter DL grid
((BindingSource)dgvBLV.DataSource).RemoveFilter(); // filter BLV grid
}
else
{
dgvDL.DataSource = people.Where("Name == @0", tb.Text).ToList(); // filter DL grid
((BindingSource)dgvBLV.DataSource).Filter = $"[Name] = '{tb.Text}'";
} // filter BLV grid
}
}
}