DevExpress 如何获取父 GridView 列以显示子 GridView 列的总和
DevExpress how to get parent GridView column to show a sum of a child GridView's column
我有一个模型,里面有一个模型列表(简化):
public class GridItemModel {
public int ID { get; set; }
public string Name { get; set; }
public List<GridItemInventoryModel> Inventory { get; set; }
}
public class GridItemInventoryModel {
public int Quantity { get; set; }
}
我像这样将我的数据绑定到网格视图(gridItems
是 GridItemModel 的列表):
gridItems = dal.GetInventoryGrid().ToList();
gridInventory.DataSource = gridItems;
gridInventory
是 DevXpress GridControl。
我已经从 gridview 中实现了这些方法:
private void gridView1_MasterRowGetChildList(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetChildListEventArgs e) {
GridItemModel i = (GridItemModel)gridView1.GetRow(e.RowHandle);
e.ChildList = new BindingSource(i, "Inventory");
}
private void gridView1_MasterRowGetRelationName(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetRelationNameEventArgs e) {
e.RelationName = "Inventory";
}
private void gridView1_MasterRowGetRelationCount(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetRelationCountEventArgs e) {
e.RelationCount = 1;
}
private void gridView1_MasterRowEmpty(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowEmptyEventArgs e) {
GridItemModel i = (GridItemModel)gridView1.GetRow(e.RowHandle);
e.IsEmpty = i == null;
}
这让我的网格看起来像这样:
当使用各种过滤器时,子视图中的一些项目被隐藏,我需要末尾列的数量来反映仅可见子记录的总和。
到目前为止,我已经覆盖了 gridView1_CustomUnboundColumnData
,如下所述:
http://www.wenda.io/questions/5156824/how-to-make-the-sum-of-each-detail-gridview-and-populated-in-the-footer-of-maste.html
但我没有 DataRows,它们只能转换为 GridItemModel。
而且我可以访问我在网格中的项目:
GridView view = sender as GridView;
if (e.Column.FieldName != "colCalcQty") return;
if (!e.IsGetData) return;
var list = (view.DataSource as IList);
var item = (list[e.ListSourceRowIndex] as GridItemModel);
但 item.Inventory 始终显示所有库存模型,而不是过滤器未删除的模型。
我可以分别通过 gridView1 和 gridView2 访问父网格和子网格。
如何使用我的设置从可见的子视图数量字段创建汇总列?
编辑:
我用几种不同的方式过滤我的视图,首先我在我的网格上启用了 ShowAutoFilterRow 但这只会过滤父记录。
然后我在表单的其他地方有一个组合框,它在选定的索引更改事件上调用此代码:
InventoryLibrary.DataTransferObjects.SimpleLocationModel location = ((ComboBoxEdit)cbeLocationsFilter).SelectedItem as InventoryLibrary.DataTransferObjects.SimpleLocationModel;
InventoryLibrary.DataTransferObjects.SimpleLocationModel subLocation = ((ComboBoxEdit)cbeSubLocationsFilter).SelectedItem as InventoryLibrary.DataTransferObjects.SimpleLocationModel;
string itemFilterString = "";
string locationFilterString = "";
if (location != null) {
itemFilterString += String.Format("[LocationNames] LIKE '%{0}%'", location.Name);
locationFilterString += String.Format("[LocationAndSublocation] LIKE '%{0}%'", location.Name);
}
if (subLocation != null) {
if (location != null) itemFilterString += " AND ";
itemFilterString += String.Format("[LocationNames] LIKE '%{0}%'", subLocation.Name);
if (location != null) locationFilterString += " AND ";
locationFilterString += String.Format("[LocationAndSublocation] LIKE '%{0}%'", subLocation.Name);
}
gridView1.ActiveFilterString = itemFilterString;
gridView2.ActiveFilterString = locationFilterString;
这是在 gridView2.ActiveFilterString
应用了过滤字符串时过滤详细信息视图的内容。
您需要获取当前行的 DetailView
和所有 DetailView
筛选行的总数量。要获得 DetailView
,您可以使用 GridView.GetDetailView
方法,而要获得过滤的行,您可以使用未记录的 GridView.DataController.GetAllFilteredAndSortedRows
方法。如果 DetailView
为空,那么您需要获取 «DevExpress 过滤器引擎» 并将其与您的 GridItemModel.Inventory
列表一起使用。您可以从 DevExpress
控件获取此引擎,例如:
- 网格控件
- PivotGridControl
- 过滤器控件
- e.t.c.
这里是 gridView1_CustomUnboundColumnData
事件和 GridControl
作为 «DevExpress 过滤器引擎» 的示例。对于此示例,您需要添加额外的 GridControl
0 并向此控件添加 GridView
1。
if (!e.IsGetData || e.Column.FieldName != "colCalcQty")
return;
var rowHandle = gridView1.GetRowHandle(e.ListSourceRowIndex);
var view = gridView1.GetDetailView(rowHandle, 0);
int quantity = 0;
if (view == null)
{
var gridItem = (GridItemModel)e.Row;
gridControl2.DataSource = gridItem.Inventory;
gridControl2.RefreshDataSource();
gridView3.ActiveFilterString = gridView2.ActiveFilterString;
view = gridView3;
}
foreach (var row in view.DataController.GetAllFilteredAndSortedRows())
{
var gridItemInventory = (GridItemInventoryModel)row;
quantity += gridItemInventory.Quantity;
}
e.Value = quantity;
您还需要在将过滤器设置为 DetailView
后刷新 MainView
:
gridView2.ActiveFilterString = "Some filter criteria";
gridView1.RefreshData();
0 - 例如 gridControl2
。
1 - 例如 gridView3
。
我有一个模型,里面有一个模型列表(简化):
public class GridItemModel {
public int ID { get; set; }
public string Name { get; set; }
public List<GridItemInventoryModel> Inventory { get; set; }
}
public class GridItemInventoryModel {
public int Quantity { get; set; }
}
我像这样将我的数据绑定到网格视图(gridItems
是 GridItemModel 的列表):
gridItems = dal.GetInventoryGrid().ToList();
gridInventory.DataSource = gridItems;
gridInventory
是 DevXpress GridControl。
我已经从 gridview 中实现了这些方法:
private void gridView1_MasterRowGetChildList(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetChildListEventArgs e) {
GridItemModel i = (GridItemModel)gridView1.GetRow(e.RowHandle);
e.ChildList = new BindingSource(i, "Inventory");
}
private void gridView1_MasterRowGetRelationName(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetRelationNameEventArgs e) {
e.RelationName = "Inventory";
}
private void gridView1_MasterRowGetRelationCount(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetRelationCountEventArgs e) {
e.RelationCount = 1;
}
private void gridView1_MasterRowEmpty(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowEmptyEventArgs e) {
GridItemModel i = (GridItemModel)gridView1.GetRow(e.RowHandle);
e.IsEmpty = i == null;
}
这让我的网格看起来像这样:
当使用各种过滤器时,子视图中的一些项目被隐藏,我需要末尾列的数量来反映仅可见子记录的总和。
到目前为止,我已经覆盖了 gridView1_CustomUnboundColumnData
,如下所述:
http://www.wenda.io/questions/5156824/how-to-make-the-sum-of-each-detail-gridview-and-populated-in-the-footer-of-maste.html
但我没有 DataRows,它们只能转换为 GridItemModel。
而且我可以访问我在网格中的项目:
GridView view = sender as GridView;
if (e.Column.FieldName != "colCalcQty") return;
if (!e.IsGetData) return;
var list = (view.DataSource as IList);
var item = (list[e.ListSourceRowIndex] as GridItemModel);
但 item.Inventory 始终显示所有库存模型,而不是过滤器未删除的模型。
我可以分别通过 gridView1 和 gridView2 访问父网格和子网格。
如何使用我的设置从可见的子视图数量字段创建汇总列?
编辑: 我用几种不同的方式过滤我的视图,首先我在我的网格上启用了 ShowAutoFilterRow 但这只会过滤父记录。
然后我在表单的其他地方有一个组合框,它在选定的索引更改事件上调用此代码:
InventoryLibrary.DataTransferObjects.SimpleLocationModel location = ((ComboBoxEdit)cbeLocationsFilter).SelectedItem as InventoryLibrary.DataTransferObjects.SimpleLocationModel;
InventoryLibrary.DataTransferObjects.SimpleLocationModel subLocation = ((ComboBoxEdit)cbeSubLocationsFilter).SelectedItem as InventoryLibrary.DataTransferObjects.SimpleLocationModel;
string itemFilterString = "";
string locationFilterString = "";
if (location != null) {
itemFilterString += String.Format("[LocationNames] LIKE '%{0}%'", location.Name);
locationFilterString += String.Format("[LocationAndSublocation] LIKE '%{0}%'", location.Name);
}
if (subLocation != null) {
if (location != null) itemFilterString += " AND ";
itemFilterString += String.Format("[LocationNames] LIKE '%{0}%'", subLocation.Name);
if (location != null) locationFilterString += " AND ";
locationFilterString += String.Format("[LocationAndSublocation] LIKE '%{0}%'", subLocation.Name);
}
gridView1.ActiveFilterString = itemFilterString;
gridView2.ActiveFilterString = locationFilterString;
这是在 gridView2.ActiveFilterString
应用了过滤字符串时过滤详细信息视图的内容。
您需要获取当前行的 DetailView
和所有 DetailView
筛选行的总数量。要获得 DetailView
,您可以使用 GridView.GetDetailView
方法,而要获得过滤的行,您可以使用未记录的 GridView.DataController.GetAllFilteredAndSortedRows
方法。如果 DetailView
为空,那么您需要获取 «DevExpress 过滤器引擎» 并将其与您的 GridItemModel.Inventory
列表一起使用。您可以从 DevExpress
控件获取此引擎,例如:
- 网格控件
- PivotGridControl
- 过滤器控件
- e.t.c.
这里是 gridView1_CustomUnboundColumnData
事件和 GridControl
作为 «DevExpress 过滤器引擎» 的示例。对于此示例,您需要添加额外的 GridControl
0 并向此控件添加 GridView
1。
if (!e.IsGetData || e.Column.FieldName != "colCalcQty")
return;
var rowHandle = gridView1.GetRowHandle(e.ListSourceRowIndex);
var view = gridView1.GetDetailView(rowHandle, 0);
int quantity = 0;
if (view == null)
{
var gridItem = (GridItemModel)e.Row;
gridControl2.DataSource = gridItem.Inventory;
gridControl2.RefreshDataSource();
gridView3.ActiveFilterString = gridView2.ActiveFilterString;
view = gridView3;
}
foreach (var row in view.DataController.GetAllFilteredAndSortedRows())
{
var gridItemInventory = (GridItemInventoryModel)row;
quantity += gridItemInventory.Quantity;
}
e.Value = quantity;
您还需要在将过滤器设置为 DetailView
后刷新 MainView
:
gridView2.ActiveFilterString = "Some filter criteria";
gridView1.RefreshData();
0 - 例如 gridControl2
。
1 - 例如 gridView3
。