Фильтр Datagrid View из данных, заполненных из объекта в C# - PullRequest
0 голосов
/ 04 августа 2020
• 1000 Это мой код для заполнения datagridview. Любая помощь будет принята с благодарностью.
IList<ProductEntity> emp = HibernateDao.fetchDAta();

IList<ProductModel> products = new List<ProductModel>();

foreach(ProductEntity e in emp)
{
    dataGridView1.Rows.Add("" + e.id, e.barcode, e.product_name, e.product_desc, e.quantity + " " + e.units,""+e.buying_price,e.retail_selling_price,e.can_sell_whole_sale,e.whole_selling_price);
}

И это код, который пытался сделать фильтр, который вообще не работает

BindingSource bs=new BindingSource();

private void metroTextBox1_TextChanged(object sender, EventArgs e)
{


   if (metroTextBox1.Text == string.Empty)
    {
        bs.RemoveFilter();
    }
    else
    {
        bs.Filter = string.Format("product_name LIKE '*{0}*'", metroTextBox1.Text);
    }
 


}

и этот - это представление таблицы данных, разработанное дизайнером, которое мне нужно отфильтровать

1 Ответ

0 голосов
/ 05 августа 2020

Представьте себе что-то вроде этого:

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, вы можете подумать:

  1. Чтобы установить пакет nuget morelinq; в нем есть методы для преобразования списков объектов в таблицы данных, а таблицы данных полностью поддерживают фильтрацию, ИЛИ

  2. Для установки пакета 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
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...