C# 在 DatagridView 中显示数据?
C# Showing Data in DatagridView?
这是我的表 1
当我点击最后一行时,它在第二个网格控件上显示数据,现在我想在下面的表格中显示这些数据(表格 2(带有橙色的购买表格)) datagridview 我该怎么做这个。
table.Columns.Add("Item Name", Type.GetType("System.String"));
table.Columns.Add("Main Qty", Type.GetType("System.Decimal"));
table.Columns.Add("Price", Type.GetType("System.Decimal"));
table.Columns.Add("Per", Type.GetType("System.String"));
table.Columns.Add("Basic Amount", Type.GetType("System.Decimal"));
table.Columns.Add("Dis Amount", Type.GetType("System.Decimal"));
table.Columns.Add("Dis Percentage", Type.GetType("System.Decimal"));
table.Columns.Add("Tax Amount", Type.GetType("System.Decimal"));
table.Columns.Add("Net Value", Type.GetType("System.Decimal"));
dataGridView1.DataSource = table;
以上是(form 2)的Form Load
下面是Form 1的RowClick
private void gridView1_RowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e)
{
try
{
FRM_Purchase frm = new FRM_Purchase();
var ctx = new BizPlusEntities();
int GettingIdForShowing = (int)gridView1.GetRowCellValue(e.RowHandle, "PurchaseID");
var GettinginToDatabase = ctx.Purchases.Where(x => x.PurchaseID == GettingIdForShowing).ToList();
foreach (var item in GettinginToDatabase)
{
frm.txtPartyName.Text = item.PartyName;
frm.txtDate.Text = item.Date.ToString();
frm.txtTerms.Text = item.Terms;
frm.txtSeries.Text = item.Series;
frm.txtDueDate.Text = item.DueDate.ToString();
frm.txtPinvoice.Text = item.Pinvoice.ToString();
UniqueIdentifier = item.UniquePurchaseNumber;
string SelectingUniqueIdentfier = ctx.Purchases.SingleOrDefault(x => x.PurchaseID == item.PurchaseID)?.UniquePurchaseNumber ?? "Nulled";
var GettingInItems = ctx.ItemPurchaseDatas.Where(x => x.UniquePurchaseNumber == SelectingUniqueIdentfier).ToList();
foreach (var Sam in GettingInItems)
{
TItemName = Sam.ItemName;
TMainQty = Sam.MainQty ?? 0;
TPrice = Sam.Price ?? 0;
TPer = Sam.Per;
TBasicAmount = Sam.BasicAmount ?? 0;
TDisAmt = Sam.DisAmount ?? 0;
TDisP = Sam.DecimalPercentage ?? 0;
TTaxAmount = Sam.Gst ?? 0;
TTotalAmount = Sam.TotalAmount ?? 0;
}
frm.Show();
}
}
catch (Exception)
{
throw;
}
}
问题是当我在 Form1 上执行 frm.Table.Rows.Add(TItem,TMainQty...)
它显示输入数组比此 table 中的列数长
当我创建一个新列时,它说该列已经存在。
我的建议是将数据与数据显示方式分开。除此之外,这使得对数据处理进行单元测试变得更加容易,它使数据显示者可以自由更改数据的显示方式。
在 WPF 中,这种模型和视图的分离几乎是强制性的,在 Winforms 中,你真的必须注意,否则你将数据处理与显示方式混合在一起,很难改变这一点。
在您的情况下:Form1 是否应该关心数据在 Form2 中的显示方式,是否应该知道 Form2 使用 DataGridView?还是Form1只关心Form2显示什么数据,而不关心格式是什么?
与 Form2 的正确接口应该是,其他 Form 告诉应该显示什么数据,如果数据可以更改,其他 Form 之后可以询问数据的值。像这样:
private void ShowForm2()
{
var dataToShow = this.FetchDataToShow();
using (var dlg = new Form2())
{
dlg.Data = dataToShow;
var dlgResult = dlg.ShowDialog(this);
if (dlgResult == DialogResult.OK)
{
var dataToProcess = dlg.Data;
this.ProcessData(dataToProcess);
}
}
}
这样,您只需告诉 Form2 显示什么数据,其他表单并不真正关心 Form2 如何显示其数据。这使 Form2 可以自由更改数据的显示方式。此表单的每个用户都将拥有相同的人机界面。
顺便说一下:您是否注意到我还把 Form1 从哪里获取 Form2 的数据以及它存储结果的地方分开了?此程序也不关心数据在Form1中的显示方式,让您可以自由更改Form1,而不必更改此程序。
使用数据绑定
使用 DataBinding 处理 DataGridView 中的行通常比直接访问 DataGridView 的行和单元格更容易。
要使用数据绑定,您的列需要知道您的 Class 中的哪个 属性 应该显示在此列中。这通常在 visual studio 设计器中完成。
在您的情况下,Form2 的 DataGridView 似乎需要显示 ItemPurchaseDatas
:DataGridView 中的每一行都会显示一个 ItemPurchaseData
的多个属性。使用 visual studio 设计器您将添加列,并且在每一列中您 select 需要在该列中显示的 属性 的名称:
DataGridView dataGridView1 = new DataGridView();
DataGridViewColumn columnName = new DataGridViewColumn();
columName.HeaderText = "Item Name";
columName.DataPropertyName = nameof(ItemPurchaseData.Name);
...
DataGridViewColumn columnPrice = new DataGridViewColumn();
columnPrice.HeaderText = "Price";
columnPrice.DataPropertyName = nameof(ItemPurchaseData.Price);
...
我们早些时候看到对话框有一个 属性 数据,其中包含要显示的数据。
表单需要一种方法来提取必须在 DataGridView 中显示的 ItemPurchaseDatas:
public IEnumerable<ItemPurchaseData> GetInitialItemPurchaseDatas()
{
// TODO: use property Data to extract the ItemPurchaseDatas that must be shown
// in the DataGridView
}
现在你要做的就是在FormLoad的事件处理程序上,获取数据并将其放入dataGridView1的DataSource中:
private void OnFormLoading(object sender, ...)
{
List<ItemPurchaseData> itemPurchaseDatas = GetInitialItemPurchaseDatas().ToList();
this.dataGridView1.DataSource = itemPurchaseDatas;
}
这足以显示数据。但是,它将是只读的:操作员所做的任何更改:编辑、添加行、删除行等,都不会反映在 itemPurchaseDatas 中。如果你想要那样,你需要一个实现 IBindingList 的对象,比如 BindingList<T>
.
如果您想知道操作员所做的更改,通常明智的做法是添加以下方法:
private BindingList<ItemPurchaseData> DisplayedData
{
get => (BindingList<ItemPurchaseData>)this.dataGridView1.DataSource;
set => this.dataGridView1.DataSource = value;
}
现在,操作员对显示数据所做的每项更改:添加/删除行、更改单元格等都会反映在 属性 DisplayedData 中。同样,数据的显示与数据本身是分开的:如果操作员更改了数据显示方式的外观,则对行进行排序、重新排列列对 DisplayedData 没有影响。
如果您经常需要处理 SelectedRows,请考虑添加以下属性:
private ItemPurchaseData CurrentItemPurchaseData =>
(ItemPurchaseData)this.dataGridView1.CurrentRow?.DataBoundItem;
private IEnumerable<ItemPurchaseData> SelectedItemPurchaseData =>
this.dataGridView1.DataSource.SelectedRows.Cast<DataGridViewRow>()
.Select(row => row.DataBoundItem)
.Cast<ItemPurchaseData>();
用法:加载表单时在 DataGridView 中显示数据,按下按钮后处理编辑的数据:
private void OnFormLoading(object sender, ...)
{
IEnumerable<ItemPurchaseData> itemPurchaseDatas = GetInitialItemPurchaseDatas();
this.DisplayedData = new BindingList<ItemPurchaseData>(itemPurchaseDatas.ToList());
}
private void OnButtonOk_Clicked(object sender, ...)
{
ICollection<ItemPurchaseData> editedData = this.DisplayedData;
// if needed: check which items are changed
this.ProcessChangedData(editedData);
}
再次说明:由于视图和模型的分离,视图中的代码是一行的
如果只想显示数据,那就是
这是我的表 1
当我点击最后一行时,它在第二个网格控件上显示数据,现在我想在下面的表格中显示这些数据(表格 2(带有橙色的购买表格)) datagridview 我该怎么做这个。
table.Columns.Add("Item Name", Type.GetType("System.String"));
table.Columns.Add("Main Qty", Type.GetType("System.Decimal"));
table.Columns.Add("Price", Type.GetType("System.Decimal"));
table.Columns.Add("Per", Type.GetType("System.String"));
table.Columns.Add("Basic Amount", Type.GetType("System.Decimal"));
table.Columns.Add("Dis Amount", Type.GetType("System.Decimal"));
table.Columns.Add("Dis Percentage", Type.GetType("System.Decimal"));
table.Columns.Add("Tax Amount", Type.GetType("System.Decimal"));
table.Columns.Add("Net Value", Type.GetType("System.Decimal"));
dataGridView1.DataSource = table;
以上是(form 2)的Form Load
下面是Form 1的RowClick
private void gridView1_RowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e)
{
try
{
FRM_Purchase frm = new FRM_Purchase();
var ctx = new BizPlusEntities();
int GettingIdForShowing = (int)gridView1.GetRowCellValue(e.RowHandle, "PurchaseID");
var GettinginToDatabase = ctx.Purchases.Where(x => x.PurchaseID == GettingIdForShowing).ToList();
foreach (var item in GettinginToDatabase)
{
frm.txtPartyName.Text = item.PartyName;
frm.txtDate.Text = item.Date.ToString();
frm.txtTerms.Text = item.Terms;
frm.txtSeries.Text = item.Series;
frm.txtDueDate.Text = item.DueDate.ToString();
frm.txtPinvoice.Text = item.Pinvoice.ToString();
UniqueIdentifier = item.UniquePurchaseNumber;
string SelectingUniqueIdentfier = ctx.Purchases.SingleOrDefault(x => x.PurchaseID == item.PurchaseID)?.UniquePurchaseNumber ?? "Nulled";
var GettingInItems = ctx.ItemPurchaseDatas.Where(x => x.UniquePurchaseNumber == SelectingUniqueIdentfier).ToList();
foreach (var Sam in GettingInItems)
{
TItemName = Sam.ItemName;
TMainQty = Sam.MainQty ?? 0;
TPrice = Sam.Price ?? 0;
TPer = Sam.Per;
TBasicAmount = Sam.BasicAmount ?? 0;
TDisAmt = Sam.DisAmount ?? 0;
TDisP = Sam.DecimalPercentage ?? 0;
TTaxAmount = Sam.Gst ?? 0;
TTotalAmount = Sam.TotalAmount ?? 0;
}
frm.Show();
}
}
catch (Exception)
{
throw;
}
}
问题是当我在 Form1 上执行 frm.Table.Rows.Add(TItem,TMainQty...) 它显示输入数组比此 table 中的列数长 当我创建一个新列时,它说该列已经存在。
我的建议是将数据与数据显示方式分开。除此之外,这使得对数据处理进行单元测试变得更加容易,它使数据显示者可以自由更改数据的显示方式。
在 WPF 中,这种模型和视图的分离几乎是强制性的,在 Winforms 中,你真的必须注意,否则你将数据处理与显示方式混合在一起,很难改变这一点。
在您的情况下:Form1 是否应该关心数据在 Form2 中的显示方式,是否应该知道 Form2 使用 DataGridView?还是Form1只关心Form2显示什么数据,而不关心格式是什么?
与 Form2 的正确接口应该是,其他 Form 告诉应该显示什么数据,如果数据可以更改,其他 Form 之后可以询问数据的值。像这样:
private void ShowForm2()
{
var dataToShow = this.FetchDataToShow();
using (var dlg = new Form2())
{
dlg.Data = dataToShow;
var dlgResult = dlg.ShowDialog(this);
if (dlgResult == DialogResult.OK)
{
var dataToProcess = dlg.Data;
this.ProcessData(dataToProcess);
}
}
}
这样,您只需告诉 Form2 显示什么数据,其他表单并不真正关心 Form2 如何显示其数据。这使 Form2 可以自由更改数据的显示方式。此表单的每个用户都将拥有相同的人机界面。
顺便说一下:您是否注意到我还把 Form1 从哪里获取 Form2 的数据以及它存储结果的地方分开了?此程序也不关心数据在Form1中的显示方式,让您可以自由更改Form1,而不必更改此程序。
使用数据绑定
使用 DataBinding 处理 DataGridView 中的行通常比直接访问 DataGridView 的行和单元格更容易。
要使用数据绑定,您的列需要知道您的 Class 中的哪个 属性 应该显示在此列中。这通常在 visual studio 设计器中完成。
在您的情况下,Form2 的 DataGridView 似乎需要显示 ItemPurchaseDatas
:DataGridView 中的每一行都会显示一个 ItemPurchaseData
的多个属性。使用 visual studio 设计器您将添加列,并且在每一列中您 select 需要在该列中显示的 属性 的名称:
DataGridView dataGridView1 = new DataGridView();
DataGridViewColumn columnName = new DataGridViewColumn();
columName.HeaderText = "Item Name";
columName.DataPropertyName = nameof(ItemPurchaseData.Name);
...
DataGridViewColumn columnPrice = new DataGridViewColumn();
columnPrice.HeaderText = "Price";
columnPrice.DataPropertyName = nameof(ItemPurchaseData.Price);
...
我们早些时候看到对话框有一个 属性 数据,其中包含要显示的数据。 表单需要一种方法来提取必须在 DataGridView 中显示的 ItemPurchaseDatas:
public IEnumerable<ItemPurchaseData> GetInitialItemPurchaseDatas()
{
// TODO: use property Data to extract the ItemPurchaseDatas that must be shown
// in the DataGridView
}
现在你要做的就是在FormLoad的事件处理程序上,获取数据并将其放入dataGridView1的DataSource中:
private void OnFormLoading(object sender, ...)
{
List<ItemPurchaseData> itemPurchaseDatas = GetInitialItemPurchaseDatas().ToList();
this.dataGridView1.DataSource = itemPurchaseDatas;
}
这足以显示数据。但是,它将是只读的:操作员所做的任何更改:编辑、添加行、删除行等,都不会反映在 itemPurchaseDatas 中。如果你想要那样,你需要一个实现 IBindingList 的对象,比如 BindingList<T>
.
如果您想知道操作员所做的更改,通常明智的做法是添加以下方法:
private BindingList<ItemPurchaseData> DisplayedData
{
get => (BindingList<ItemPurchaseData>)this.dataGridView1.DataSource;
set => this.dataGridView1.DataSource = value;
}
现在,操作员对显示数据所做的每项更改:添加/删除行、更改单元格等都会反映在 属性 DisplayedData 中。同样,数据的显示与数据本身是分开的:如果操作员更改了数据显示方式的外观,则对行进行排序、重新排列列对 DisplayedData 没有影响。
如果您经常需要处理 SelectedRows,请考虑添加以下属性:
private ItemPurchaseData CurrentItemPurchaseData =>
(ItemPurchaseData)this.dataGridView1.CurrentRow?.DataBoundItem;
private IEnumerable<ItemPurchaseData> SelectedItemPurchaseData =>
this.dataGridView1.DataSource.SelectedRows.Cast<DataGridViewRow>()
.Select(row => row.DataBoundItem)
.Cast<ItemPurchaseData>();
用法:加载表单时在 DataGridView 中显示数据,按下按钮后处理编辑的数据:
private void OnFormLoading(object sender, ...)
{
IEnumerable<ItemPurchaseData> itemPurchaseDatas = GetInitialItemPurchaseDatas();
this.DisplayedData = new BindingList<ItemPurchaseData>(itemPurchaseDatas.ToList());
}
private void OnButtonOk_Clicked(object sender, ...)
{
ICollection<ItemPurchaseData> editedData = this.DisplayedData;
// if needed: check which items are changed
this.ProcessChangedData(editedData);
}
再次说明:由于视图和模型的分离,视图中的代码是一行的
如果只想显示数据,那就是