当前位置:网站首页>C # implements WinForm DataGridView control to support overlay data binding
C # implements WinForm DataGridView control to support overlay data binding
2022-07-05 11:28:00 【Full stack programmer webmaster】
We all know WinForm DataGridView Control support data binding , The method is simple to use , Just put the DataSource Attribute to the corresponding data source , But note that the data source must support IListSource type , What we are talking about here is support , Not implementation , Because he can realize IListSource The type of , It can also be realized IList The type of , for example :List type ,DataTable Type, etc , Here is not a list , Today, I mainly realize the functions described in the title : Realization WinForm DataGridView Control supports overlay data binding , Or additional data function , What does that mean ? To put it bluntly, it supports multiple binding of data , The standard binding method only supports single binding , That is, each binding will clear the original data , Superimposed data binding can realize that each binding is in the form of attachment ( Original data retention ) Add to DataGridView Control , This enables paging loading , However, all loaded data can be displayed completely , This application scenario is in C/S End is very common ,B/S There are also ( for example QQ Load more buttons under space dynamics )
Here are two ways to implement additional data :
The first way , Use reflection to get attribute values and add data rows circularly
private static void AppendDataToGrid(DataGridView grid, IList<object> source)
{
int rowCount = grid.Rows.Count;
List<DataGridViewRow> rows = new List<DataGridViewRow>();
Type t = source[0].GetType();
int rowIndex = grid.Rows.Add();
var girdCells = grid.Rows[rowIndex].Cells;
//Common.ShowProcessing(" Loading data , Please wait a moment ...", Common.MainForm, (o) =>
//{
foreach (object item in source)
{
var row = new DataGridViewRow();
foreach (DataGridViewCell cell in girdCells)
{
var p = t.GetProperty(cell.OwningColumn.DataPropertyName);
object pValue = p.GetValue(item, null);
var newCell = (DataGridViewCell)cell.Clone();
newCell.Value = pValue;
row.Cells.Add(newCell);
}
rows.Add(row);
}
//});
grid.Rows.RemoveAt(rowIndex);
grid.Rows.AddRange(rows.ToArray());
}Every two ways , Merge data sources , Then rebind
protected void AppendDataToGrid<T,TResult>(DataGridView dataGridBase, IList<T> source,Func<T,TResult> orderBy) where T : class
{
//Stopwatch watch = new Stopwatch();
//watch.Start();
if (dataGridBase.Rows.Count > 0)
{
IEnumerable<T> bindsource = null;
Common.ShowProcessing(" Loading data , Please wait a moment ...", Common.MainForm, (o) =>
{
var oldSource = (IList<T>)dataGridBase.DataSource;
bindsource = source.Concat(oldSource).OrderBy(orderBy).ToList();
});
dataGridBase.DataSource = bindsource;
}
else
{
dataGridBase.DataSource = source;
}
//watch.Stop();
//MessageBox.Show(watch.ElapsedMilliseconds.ToString());
}In terms of code quantity, the above two methods , The second is relatively simple , The first method is more efficient than the second method , The reason is simple , The first kind of data processed every time is always the data of every page , The second kind of data processed each time is the combination of original data and existing data , As the amount of data increases , The slower the loading , You can also try , Of course, if you have other better methods, you can also share .
In order to embody object-oriented and reusability , I change the above method into an extension method , The complete code is as follows :
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data;
namespace Zwj.Demo
{
public interface IAppendDataAble<out TControl> where TControl : Control
{
}
public class DataGridView2 : DataGridView, IAppendDataAble<DataGridView>
{
}
public static class AppendDataAbleControlExtension
{
public static void AppendData(this DataGridView grid, dynamic dataSource)
{
if (!(grid is IAppendDataAble<DataGridView>))
{
throw new Exception(" The DataGridView Control is not implemented IAppendDataAble<DataGridView>, Cannot use this method !");
}
if (dataSource.GetType().IsValueType || dataSource == null)
{
grid.DataSource = null;
return;
}
Type interfaceType=dataSource.GetType().GetInterface("System.Collections.IList", true);
if (interfaceType!=null)
{List<object> list = new List<object>(); list.AddRange(dataSource); AppendDataToGrid(grid, list);
}
else if (dataSource is DataTable)
{
AppendDataToGrid(grid, dataSource as DataTable);
}
}
/// <summary>
/// Attach data to DataGridView( Support IList<T> Data source of type )
/// </summary>
/// <param name="grid"></param>
/// <param name="source"></param>
private static void AppendDataToGrid(DataGridView grid, IList<object> source)
{
int rowCount = grid.Rows.Count;
List<DataGridViewRow> rows = new List<DataGridViewRow>();
Type t = source[0].GetType();
int rowIndex = grid.Rows.Add();
var girdCells = grid.Rows[rowIndex].Cells;
//Common.ShowProcessing(" Loading data , Please wait a moment ...", Common.MainForm, (o) =>
//{
foreach (object item in source)
{
var row = new DataGridViewRow();
foreach (DataGridViewCell cell in girdCells)
{
var p = t.GetProperty(cell.OwningColumn.DataPropertyName);
object pValue = p.GetValue(item, null);
var newCell = (DataGridViewCell)cell.Clone();
newCell.Value = pValue;
row.Cells.Add(newCell);
}
rows.Add(row);
}
//});
grid.Rows.RemoveAt(rowIndex);
grid.Rows.AddRange(rows.ToArray());
}
/// <summary>
/// Attach data to DataGridView( Support DataTable Data source of type )
/// </summary>
/// <param name="grid"></param>
/// <param name="table"></param>
private static void AppendDataToGrid(DataGridView grid, DataTable table)
{
int rowCount = grid.Rows.Count;
List<DataGridViewRow> rows = new List<DataGridViewRow>();
int rowIndex = grid.Rows.Add();
var girdCells = grid.Rows[rowIndex].Cells;
//Common.ShowProcessing(" Loading data , Please wait a moment ...", Common.MainForm, (o) =>
//{
foreach (DataRow r in table.Rows)
{
var row = new DataGridViewRow();
foreach (DataGridViewCell cell in girdCells)
{
object pValue = r[cell.OwningColumn.DataPropertyName];
var newCell = (DataGridViewCell)cell.Clone();
newCell.Value = pValue;
row.Cells.Add(newCell);
}
rows.Add(row);
}
//});
grid.Rows.RemoveAt(rowIndex);
grid.Rows.AddRange(rows.ToArray());
}
}
}Explain the code a little , In order to avoid the abuse of extension methods , That is, ordinary without additional data DataGridView Impact , I define an interface to regulate it :IAppendDataAble<out TControl>, Of course, this interface applies to all controls , Then when extending the method AppendData Add judgment , If it's done IAppendDataAble Interface , It indicates that additional data function is required , Just do the following processing , Otherwise, the report will be wrong . I'm based here DataGridView To expand , You can also base on my definition DataGridView2 To expand , It's more convenient . in addition , I have implemented the above processing for two data source types , To meet most situations .
Method one of the methods commented out is the method I wrote to display the mask layer , If you need , You can check my blog :Winform The application implements a universal mask layer
How to use it is as follows :
1. add to DataGridView Control , And then DataGridView Change the type to DataGridView2 type , Of course, if you don't need extension constraints , Then there is no need to change DataGridView Control types .
2. Set up DataGridView Column , List the DataPropertyName Set to the name of the data field to be bound , This step is very important .
3. Then query the data and call the extension method :
//dataGridView2Demo by DataGridView2 type
//dataSource For the queried data
dataGridView2Demo.AppendData(dataSource);In order to improve the execution efficiency of the extension method , Reduce data source type judgment and conversion , We can also choose to directly divide the extension method into two extension methods , as follows :
public static class ControlExtension
{
/// <summary>
/// Attach data to DataGridView( Support IList<T> Data source of type )
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="grid"></param>
/// <param name="source"></param>
public static void AppendData<T>(this DataGridView grid, IList<T> source) where T : class
{
int rowCount = grid.Rows.Count;
List<DataGridViewRow> rows = new List<DataGridViewRow>();
Type t = typeof(T);
int rowIndex = grid.Rows.Add();
var girdCells = grid.Rows[rowIndex].Cells;
Common.ShowProcessing(" Loading data , Please wait a moment ...", Common.MainForm, (o) =>
{
foreach (object item in source)
{
var row = new DataGridViewRow();
foreach (DataGridViewCell cell in girdCells)
{
var p = t.GetProperty(cell.OwningColumn.DataPropertyName);
object pValue = p.GetValue(item, null);
var newCell = (DataGridViewCell)cell.Clone();
newCell.Value = pValue;
row.Cells.Add(newCell);
}
rows.Add(row);
}
});
grid.Rows.RemoveAt(rowIndex);
grid.Rows.AddRange(rows.ToArray());
}
/// <summary>
/// Attach data to DataGridView( Support DataTable Data source of type )
/// </summary>
/// <param name="grid"></param>
/// <param name="table"></param>
public static void AppendData(this DataGridView grid, DataTable table)
{
int rowCount = grid.Rows.Count;
List<DataGridViewRow> rows = new List<DataGridViewRow>();
int rowIndex = grid.Rows.Add();
var girdCells = grid.Rows[rowIndex].Cells;
Common.ShowProcessing(" Loading data , Please wait a moment ...", Common.MainForm, (o) =>
{
foreach (DataRow r in table.Rows)
{
var row = new DataGridViewRow();
foreach (DataGridViewCell cell in girdCells)
{
object pValue = r[cell.OwningColumn.DataPropertyName];
var newCell = (DataGridViewCell)cell.Clone();
newCell.Value = pValue;
row.Cells.Add(newCell);
}
rows.Add(row);
}
});
grid.Rows.RemoveAt(rowIndex);
grid.Rows.AddRange(rows.ToArray());
}
}Use method unchanged , As for which one to use, it depends on your preferences !
Publisher : Full stack programmer stack length , Reprint please indicate the source :https://javaforall.cn/109478.html Link to the original text :https://javaforall.cn
边栏推荐
- Cron expression (seven subexpressions)
- COMSOL -- establishment of geometric model -- establishment of two-dimensional graphics
- 2048游戏逻辑
- Lombok makes ⽤ @data and @builder's pit at the same time. Are you hit?
- [first release in the whole network] (tips for big tables) sometimes it takes only 1 minute for 2 hours of SQL operation
- 修复动漫1K变8K
- -26374 and -26377 errors during coneroller execution
- MySQL giant pit: update updates should be judged with caution by affecting the number of rows!!!
- Go language learning notes - first acquaintance with go language
- 【Oracle】使用DataGrip连接Oracle数据库
猜你喜欢

Pytorch training process was interrupted

DDR4的特性与电气参数

Oneforall installation and use

高校毕业求职难?“百日千万”网络招聘活动解决你的难题
![[JS] extract the scores in the string, calculate the average score after summarizing, compare with each score, and output](/img/96/b8585205b3faf503686c5bbdcecc53.png)
[JS] extract the scores in the string, calculate the average score after summarizing, compare with each score, and output

Modulenotfounderror: no module named 'scratch' ultimate solution
![[advertising system] incremental training & feature access / feature elimination](/img/14/ac596fa4d92e7b245e08cea014a4ab.png)
[advertising system] incremental training & feature access / feature elimination

DDRx寻址原理
![[office] eight usages of if function in Excel](/img/ce/ea481ab947b25937a28ab5540ce323.png)
[office] eight usages of if function in Excel

【爬虫】wasm遇到的bug
随机推荐
数据库三大范式
ZCMU--1390: 队列问题(1)
Risc-v-qemu-virt in FreeRTOS_ Scheduling opportunity of GCC
不要再说微服务可以解决一切问题了!
DDoS attack principle, the phenomenon of being attacked by DDoS
修复动漫1K变8K
[advertising system] incremental training & feature access / feature elimination
Basic part - basic project analysis
Startup process of uboot:
COMSOL--三维图形的建立
解决访问国外公共静态资源速度慢的问题
[SWT component] content scrolledcomposite
Go language learning notes - first acquaintance with go language
Intelligent metal detector based on openharmony
Three paradigms of database
TSQL – identity column, guid, sequence
Redis如何实现多可用区?
Guys, I tested three threads to write to three MySQL tables at the same time. Each thread writes 100000 pieces of data respectively, using F
SLAM 01. Modeling of human recognition Environment & path
IPv6与IPv4的区别 网信办等三部推进IPv6规模部署