轉帖|使用教程|編輯:龔雪|2023-06-09 10:06:32.440|閱讀 343 次
概述:本文主要為大家介紹在在DevExpress中如何使用BandedGridView表格實現多行表頭處理,歡迎下載最新版體驗!
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
在之前的分享中介紹過實現多行表頭的處理,通過手工創建字段以及映射數據源字段屬性的方式實現,有些客戶反映是否可以通過代碼方式更方便的創建對應的處理操作,因此本篇隨筆繼續探討這個多行表頭的處理的操作,使用代碼的方式結合擴展函數處理,快速的實現GridControl的多行表頭的處理操作。
DevExpress擁有.NET開發需要的所有平臺控件,包含600多個UI控件、報表平臺、DevExpress Dashboard eXpressApp 框架、適用于 Visual Studio的CodeRush等一系列輔助工具。
DevExpress技術交流群8:523159565 歡迎一起進群討論
在之前的文章中總結了一些GridControl控件的一些操作,其中也提到了多行表頭綁定處理,如下界面所示。
有時候,我們為了一些特殊的需要,要對表頭進行特別的排版,使其支持多行表頭的效果,如上圖所示,這樣方便對各項內容進行歸類顯示,易于閱讀,在DevExpress中應該如何實現這個效果呢?
①先在設計模式將普通的GridView轉換為BandedGridView或者AdvBandedGridView,這樣才能支持這種多行表頭的做法,如下所示。
②定義一些字段,用來顯示其中的內容,如下圖所示。
③定義一些Band列,設置相關的屬性,并把設計界面中的字段列表拖動到對應過的Band列上面,這樣就構成了一個Band列和字段內容的對應關系。
完成上面的綁定關系后,記得設置GridView控件的屬性,使其不要顯示原本的ColumnHeader等內容。
設置好這些內容,才能合理、完美顯示出多行表頭的信息。
上面的操作,適合于新手的一些簡單的字段綁定處理,有時候我們為了方便,可能更傾向于使用代碼的方式快速構建多行表頭的操作。
我們通過查看代碼,可以了解GridBand對象是一個嵌套的關系,它類似樹形結構,可以有很多層的子集合,也就是嵌套的頭部條,它結合字段列對象GridColumn就形成了BandedGridColumn的信息。
我們需要知道GridBand只是一個頭部的條狀列信息,一般用來覆蓋GridColumn的默認列頭信息,因此需要設置一定的樣式來禁用顯示默認的GridColumn的頭部信息。
view.OptionsView.ShowColumnHeaders = false; //因為有Band列了,所以把ColumnHeader隱藏
因此我們創建一個擴展的靜態類文件,并加入設置BandedGridView樣式的處理擴展方法,把相關的樣式統一處理,如下所示。
/// <summary>
/// GridView及其RepositoryItem編輯控件的擴展類
/// </summary>
public static class Grid_Extension
{
/// <summary>
/// 設置BandedGridView的樣式
/// </summary>
/// <param name="view"></param>
public static void SetBandedViewStyle(this BandedGridView view)
{
view.BeginUpdate(); //開始視圖的編輯,防止觸發其他事件
view.Bands.Clear();
//修改附加選項
view.OptionsView.ShowColumnHeaders = false; //因為有Band列了,所以把ColumnHeader隱藏
view.OptionsView.ShowGroupPanel = false; //如果沒必要分組,就把它去掉
view.OptionsView.EnableAppearanceEvenRow = false; //是否啟用偶數行外觀
view.OptionsView.EnableAppearanceOddRow = true; //是否啟用奇數行外觀
view.OptionsView.ShowFilterPanelMode = ShowFilterPanelMode.Never; //是否顯示過濾面板
view.OptionsCustomization.AllowColumnMoving = false; //是否允許移動列
view.OptionsCustomization.AllowColumnResizing = false; //是否允許調整列寬
view.OptionsCustomization.AllowGroup = false; //是否允許分組
view.OptionsCustomization.AllowFilter = false; //是否允許過濾
view.OptionsCustomization.AllowSort = true; //是否允許排序
view.OptionsSelection.EnableAppearanceFocusedCell = true; //是否焦點顯示選中的單元格
view.EndUpdate(); //結束視圖的編輯
}
由于GridBand可能是嵌套的多層表頭,因此為了方便,可以單獨設置一個擴展方法創建GridBand,這樣有助于引用對象。
/// <summary>
/// 創建綁定Banded列
/// </summary>
/// <param name="view"></param>
/// <param name="caption"></param>
/// <param name="width"></param>
/// <param name="fixedStyle"></param>
/// <param name="visible">是否可見</param>
/// <returns></returns>
public static GridBand CreateBand(this BandedGridView view, string caption, int width = 80, FixedStyle fixedStyle = FixedStyle.None, bool visible = true)
{
//使用多語言處理標題
caption = JsonLanguage.Default.GetString(caption);
var band = new GridBand
{
Caption = caption,
Width = width,
Fixed = fixedStyle,
Visible = visible,
};
view.Bands.Add(band);
band.VisibleIndex = view.Bands.Count;
band.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
return band;
}
這樣我們就可以傳遞GridBand對象來構建多層級的字段列信息了,利用擴展函數,我們可以方便的實現創建綁定列信息。
/// <summary>
/// 根據指定的GridBand父級對象,構建BandedGridColumn列對象
/// </summary>
/// <param name="view"></param>
/// <param name="band"></param>
/// <param name="fieldName"></param>
/// <param name="caption"></param>
/// <param name="allowEdit"></param>
/// <param name="allowMerge"></param>
/// <returns></returns>
public static BandedGridColumn CreateBandColumn(this BandedGridView view, GridBand band, string fieldName, string caption, bool allowEdit = true, DefaultBoolean allowMerge = DefaultBoolean.False)
{
//使用多語言處理標題
caption = JsonLanguage.Default.GetString(caption);
var gridColumn = new BandedGridColumn()
{
FieldName = fieldName,
Caption = caption,
UnboundType = UnboundColumnType.Bound,
Visible = true
};
band.AppearanceHeader.BackColor = Color.LightGreen;
var newBand = band.Children.AddBand(caption);
newBand.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; //文本居中
newBand.Columns.Add(gridColumn);
gridColumn.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
gridColumn.AppearanceCell.TextOptions.VAlignment = VertAlignment.Center;
gridColumn.OptionsColumn.AllowEdit = allowEdit;
if (!allowEdit)
{
gridColumn.AppearanceHeader.ForeColor = Color.Gray;
}
bool allowCellMerge = !view.OptionsView.AllowCellMerge && allowMerge == DefaultBoolean.True;
if (allowCellMerge)
{
view.OptionsView.AllowCellMerge = true;
}
gridColumn.OptionsColumn.AllowMerge = allowMerge;
return gridColumn;
}
而如果一般的列,沒有多層嵌套的GridBand,也就是只有一層的表頭,我們也需要根據字段信息進行構建一個GridBandColumn來顯示信息,如下所示。
/// <summary>
/// 根據字段信息,構建BandedGridColumn列對象
/// </summary>
/// <param name="view">視圖對象</param>
/// <param name="fieldName">字段名稱</param>
/// <param name="caption">顯示名稱</param>
/// <param name="width">列寬度</param>
/// <param name="fixedStyle">固定顯示模式</param>
/// <param name="visible">是否可見</param>
/// <param name="allowEdit">是否可編輯</param>
/// <param name="allowMerge">是否可合并</param>
/// <param name="unboundColumnType">綁定類型,默認為UnboundColumnType.Bound</param>
/// <returns></returns>
public static BandedGridColumn CreateBandColumn(this BandedGridView view, string fieldName, string caption, int width = 80, FixedStyle fixedStyle = FixedStyle.None, bool visible = true, bool allowEdit = true, DefaultBoolean allowMerge = DefaultBoolean.False, UnboundColumnType unboundColumnType = UnboundColumnType.Bound)
{
//使用多語言處理標題
caption = JsonLanguage.Default.GetString(caption);
var gridColumn = new BandedGridColumn()
{
FieldName = fieldName,
Caption = caption,
Width = width,
UnboundType = unboundColumnType,
};
var band = view.CreateBand(caption, width, fixedStyle);
band.Visible = visible;
band.Columns.Add(gridColumn);
//view.Columns[fieldName].OwnerBand = band;
gridColumn.AbsoluteIndex = view.Columns.Count;
gridColumn.Visible = visible;//是否可見
if (visible)
{
gridColumn.VisibleIndex = view.Columns.Count;
}
gridColumn.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
gridColumn.AppearanceCell.TextOptions.VAlignment = VertAlignment.Center;
gridColumn.OptionsColumn.AllowEdit = allowEdit;
if (!allowEdit)
{
gridColumn.AppearanceHeader.ForeColor = Color.Gray;
}
bool allowCellMerge = !view.OptionsView.AllowCellMerge && allowMerge == DefaultBoolean.True;
if (allowCellMerge)
{
view.OptionsView.AllowCellMerge = true;
}
gridColumn.OptionsColumn.AllowMerge = allowMerge;
gridColumn.Fixed = fixedStyle;
return gridColumn;
}
有了這些擴展函數的鋪墊,我們在實際界面中展示多層級的多行表頭就會變得很容易了。為了方便介紹,我創建一個簡單的窗體用來展示多行表頭的代碼綁定處理。
創建一個默認的窗體,放置GridControl,并把默認的GridView視圖,轉換為BandedGridView視圖對象,如下所示。
為了綁定一些字段信息供顯示、編輯處理,我們創建了一個表格,包含信息:Id,姓名,外科皮膚科_診斷,外科皮膚科_結論,神經精神科_診斷,神經精神科_結論,內科_診斷,內科_結論,眼科_診斷,眼科_結論,檢查時間,備注 等字段內容,如下代碼所示。
var table = DataTableHelper.CreateTable("Id|int,姓名,外科皮膚科_診斷,外科皮膚科_結論,神經精神科_診斷,神經精神科_結論,內科_診斷,內科_結論,眼科_診斷,眼科_結論,檢查時間,備注");
//準備飛行員體檢測試數據
for (int i =1; i <= 50;i++)
{
var dr = table.NewRow();
dr["Id"] = i;
dr["姓名"] = $"某某{i}";
dr["外科皮膚科_診斷"] = "健康";
dr["外科皮膚科_結論"] = "合格";
dr["神經精神科_診斷"] = "健康";
dr["神經精神科_結論"] = "合格";
dr["內科_診斷"] = "健康";
dr["內科_結論"] = "合格";
dr["眼科_診斷"] = "健康";
dr["眼科_結論"] = "合格";
dr["檢查時間"] = DateTime.Now;
dr["備注"] = "";
table.Rows.Add(dr);
}
首先需要創建GridView的初始化信息,如綁定那些字段列,結合多表頭的處理方式,如下代碼所示。
/// <summary>
/// 初始化列表
/// </summary>
private void InitGridView()
{
var grid = this.gridControl1;
var grv = this.gridControl1.MainView as BandedGridView;
grid.ContextMenuStrip = this.contextMenuStrip1;//右鍵菜單
//初始化GridView樣式,并設置相關的BandedGridView樣式
grv.InitGridView(GridType.EditOnly, false, EditorShowMode.MouseDownFocused, "");
grv.SetBandedViewStyle();
//創建顯示的列:
//Id,姓名,外科皮膚科_診斷,外科皮膚科_結論,神經精神科_診斷,神經精神科_結論,內科_診斷,內科_結論,眼科_診斷,眼科_結論,檢查時間,備注
grv.Columns.Clear();
grv.CreateBandColumn("Id", "Id", 80, FixedStyle.Left, true, false);
grv.CreateBandColumn("姓名", "客戶名稱", 80, FixedStyle.Left, true, false);
var band1 = grv.CreateBand("外科皮膚科", 120);
grv.CreateBandColumn(band1, "外科皮膚科_診斷", "診斷");
grv.CreateBandColumn(band1, "外科皮膚科_結論", "結論");
var band2 = grv.CreateBand("神經精神科", 120);
grv.CreateBandColumn(band2, "神經精神科_診斷", "診斷");
grv.CreateBandColumn(band2, "神經精神科_結論", "結論");
var band3 = grv.CreateBand("內科", 120);
grv.CreateBandColumn(band3, "內科_診斷", "診斷");
grv.CreateBandColumn(band3, "內科_結論", "結論");
var band4 = grv.CreateBand("眼科", 120);
grv.CreateBandColumn(band4, "眼科_診斷", "診斷");
grv.CreateBandColumn(band4, "眼科_結論", "結論");
var colCheckTime = grv.CreateBandColumn("檢查時間", "檢查時間").CreateDateEdit();//可修改
colCheckTime.EditMask = "yyyy-MM-dd";
colCheckTime.DisplayFormat.FormatString = "yyyy-MM-dd";
colCheckTime.EditFormat.FormatString = "yyyy-MM-dd";
colCheckTime.CustomDisplayText += (s, e) =>
{
if (e.Value != null && e.Value.ToString() != "")
{
if (Convert.ToDateTime(e.Value) <= Convert.ToDateTime("1900-1-1"))
{
e.DisplayText = "";
}
else
{
e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd");
}
}
};
//可修改
grv.CreateBandColumn("備注", "備注", 200);
//設置部分字段不可修改
var editFields = "外科皮膚科_診斷,外科皮膚科_結論,神經精神科_診斷,神經精神科_結論,內科_診斷,內科_結論,眼科_診斷,眼科_結論,檢查時間,備注";
grv.SetColumnsReadOnly("*", false);
grv.SetColumnsReadOnly(editFields, true);
//檢查輸入
grv.ValidateRow += (s, e) =>
{
//校驗一些不能為空的字段
//var result = grid.ValidateRowNull(e, new string[]
//{
// "產品編碼",
// "產品名稱"
//});
};
//值更改觸發
grv.CellValueChanged += (s, e) =>
{
//根據數量計算金額
//if (e.Column.FieldName == "Quantity" && e.Value != null)
//{
// var Price = string.Concat(grv.GetFocusedRowCellValue("Price")).ToDecimal();
// var Quantity = string.Concat(e.Value).ToDecimal();
// grv.SetFocusedRowCellValue("Amount", Price * Quantity);
//}
};
//單元格樣式
grv.RowCellStyle += (s, e) =>
{
//設置特殊顏色標志
if (editFields.Contains(e.Column.FieldName))
{
e.Appearance.BackColor = Color.Azure;
e.Appearance.ForeColor = Color.Blue;
}
};
}
初始化BandedGridView信息后,如需綁定數據,那么還需要對GridControl的數據源進行綁定才能進行編輯或者顯示,如下所示的代碼操作。
/// <summary>
/// 綁定數據列表
/// </summary>
private void BindData()
{
var table = DataTableHelper.CreateTable("Id|int,姓名,外科皮膚科_診斷,外科皮膚科_結論,神經精神科_診斷,神經精神科_結論,內科_診斷,內科_結論,眼科_診斷,眼科_結論,檢查時間,備注");
//準備飛行員體檢測試數據
for (int i =1; i <= 50;i++)
{
var dr = table.NewRow();
dr["Id"] = i;
dr["姓名"] = $"某某{i}";
dr["外科皮膚科_診斷"] = "健康";
dr["外科皮膚科_結論"] = "合格";
dr["神經精神科_診斷"] = "健康";
dr["神經精神科_結論"] = "合格";
dr["內科_診斷"] = "健康";
dr["內科_結論"] = "合格";
dr["眼科_診斷"] = "健康";
dr["眼科_結論"] = "合格";
dr["檢查時間"] = DateTime.Now;
dr["備注"] = "";
table.Rows.Add(dr);
}
//綁定數據源
var grv = this.bandedGridView1;
grv.GridControl.DataSource = table;
grv.RefreshData();
}
最后,我們把它放在開發框架(如有Winform界面部分的SqlSugar開發框架、Winform開發框架)的綜合演示案例里面,供參考使用。界面效果如下所示。
對比手工的效果:
實現功能差不多,通過代碼方式,相對更加靈活一些。
以上就是綜合介紹了手工處理和代碼處理兩種方式構建多行表頭的處理操作,通過使用擴展函數方式,可以更快捷、更靈活的創建多表頭的處理和數據的綁定展示,可以有效的減少我們在多表頭上的操作摸索時間。
本文轉載自:
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉載自: