添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

改变GridControl自定义column  Header背景颜色属性

在Form窗体上拖放了一个GridControl,尝试修改列头 column header 背景颜色. 但是修改AppearanceHeaderPanel 属性后,并没有效果出现, 我使用的是 Outlook 默认皮肤 。

后来发现原因是GridControl的Header使用了Devexpress皮肤中的图片作为背景。如果你想手动更改ColumnHeader的背景色,可以这样做:

1)设置 GridControl的LookAndFeel.UseDefaultLookAndFeel 属性为 False

2)设置 GridControl 的LookAndFeel.Style 属性为 Flat( UltraFlat 或 Style3D)

3)设置 GridColumn.AppearanceHeader.BackColor 为你需要的颜色。

使用SkinEditor创建自定义的皮肤,这个不难,因为是继承的Devexpress皮肤模板,在皮肤中移除列头的图片背景或者更换需要的图片背景。

http://www.360doc.com/content/11/0425/19/6832513_112260508.shtml

如果有其他地方皮肤需要自定义可以选择第二种方式。

实现 GridView.CustomDrawColumnHeader 事件

3、禁用右击标题列弹出右键菜单

设置Run Design->OptionsMenu->EnableColumnMenu 设置为:false

4、禁用列排序

AllowSort属性设为False

5、让各列头禁止移动

设置gridView1.OptionsCustomization.AllowColumnMoving = false;

6、禁止改变列宽/自适应列宽

(1)列表宽度自适应内容

gridview1.BestFitColumns();

(2)禁止各列头改变列宽

设置gridView1.OptionsCustomization.AllowColumnResizing = false;

(3)根据内容自动调整列宽

gridView_1.Columns["TestInfo"].BestFit();

1)如果是动态添加列,一定要在绑定数据源以后再设置,否则gridView_1.Columns[ " TestInfo "]为Null导致报错;

2)一定要在数据源改变后设置,否则无效。

(4)列宽填满表格

gv_Show.OptionsView.ColumnAutoWidth = true;

这样就不显示水平滚动条了。

7、设某一列文字和标题居中显示

gridView1.Columns[0].AppearanceHeader.TextOptions.HAlignment =DevExpress.Utils.HorzAlignment.Center;
gridView1.Columns[0].AppearanceCell.TextOptions.HAlignment =DevExpress.Utils.HorzAlignment.Center;

8、设置冻结列(左冻结)

gridView1.Columns[0].Fixed= DevExpress.XtraGrid.Columns.FixedStyle.Left;

https://www.cnblogs.com/starksoft/p/4936207.html

        private void gv_Step_CustomDrawCell(object sender, DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e)
            if (e.RowHandle == gv_Step.FocusedRowHandle)
                //e.Appearance.ForeColor = Color.Red;//字体颜色
                e.Appearance.BackColor = Color.Green;//行背景颜色

3、设置焦点行

gridView2.FocusedRowHandle = dtselected.Rows.Count - 1;

4、设置点击选择一行而不是一个单元格

this.gridView1.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
this.gridView1.OptionsSelection.EnableAppearanceFocusedCell = false;

5、设置单元格、列不可编辑

(1)整个表不能编辑

View->OptionsBehavior->Editable 设置为:false

(2)单元格不可编辑

  private void LinkGridView_ShowingEditor(object sender, CancelEventArgs e)
            if (LinkGridView.FocusedColumn.FieldName == "name1" || LinkGridView.FocusedColumn.FieldName == "name2")
                int row = this.LinkGridView.FocusedRowHandle;
                string ss = LinkGridView.GetRowCellDisplayText(row, LinkGridView.Columns["Xx"]);
                string ss2 = LinkGridView.GetRowCellDisplayText(row, LinkGridView.Columns["xX"]);
                if (ss.Contains("xx") || ss2.Contains("xxx"))
                    e.Cancel = true;//该行不可编辑

(3)单独设置某列编辑使能

gridView1.Columns["Col1"].OptionsColumn.AllowEdit = true;//设置列可以编辑

6、隐藏编辑单元格时右击弹出复制/粘贴等操作的英文菜单

例如该可编辑单元格的ColumnEdit属性绑定了一个RepositoryItemTextEdit,命名为tb_TaskName。

该菜单其实是在这个TextEdit上弹出的,所以要改变这个控件的右键事件:

        private void tb_TaskName_MouseDown(object sender, MouseEventArgs e)
            if (e.Button == MouseButtons.Right)
                ///用一个空的菜单取代原来的系统菜单
                ContextMenu emptyMenu = new ContextMenu();
                tb_TaskName.ContextMenu = emptyMenu;

7、选中某行

gridView1.SelectRow(i);

1、隐藏GroupPanel表头

设置Run Design->OptionsView->ShowGroupPanel 设置为:false

2、显示水平滚动条

设置this.gridView.OptionsView.ColumnAutoWidth = false;

3、定位到指定记录

定位到第一条数据/记录: 设置 this.gridView.MoveFirst()
定位到下一条数据/记录: 设置 this.gridView.MoveNext()
定位到最后一条数据/记录:设置 this.gridView.MoveLast()

4、读写拷贝权限设置

只读不可拷贝:
ColumnViewOptionsBehavior.Editable = False
只读可拷贝:
ColumnViewOptionsBehavior.Editable = True
OptionsColumn.AllowEdit = True
OptionsColumn.ReadOnly = True
可编辑:
ColumnViewOptionsBehavior.Editable = True
OptionsColumn.AllowEdit = True
OptionsColumn.ReadOnly = False

5、修改最上面的GroupPanel内容

gridView1.GroupPanelText="xxx";

      gridView1.RefreshData();

      gc.RefreshDataSource() 更新数据源

3、绑定的顺序很重要。尝试在更新数据源之前加上gc.DataSource = dt;

4、如果是绑定List,那么list里的类字段定义时必须按照get;set;形式来写

六、使用GridFormatRule规则改变行/单元格样式

1、用法示例

设置方法(官方):

(1)https://docs.devexpress.com/WindowsForms/DevExpress.XtraEditors.FormatConditionRuleExpression

(2)https://docs.devexpress.com/WindowsForms/114615/controls-and-libraries/data-grid/getting-started/walkthroughs/appearance-and-conditional-formatting/tutorial-custom-styles-for-rows-and-cells

直接代码调用:https://blog.csdn.net/duanzi_peng/article/details/78791513

        public static void SetPowerContrlRule(DevExpress.XtraGrid.Views.Grid.GridView gv_Show)
                DevExpress.XtraGrid.GridFormatRule gridFormatRule1 = new DevExpress.XtraGrid.GridFormatRule();
                DevExpress.XtraEditors.FormatConditionRuleValue formatConditionRuleValue1 = new DevExpress.XtraEditors.FormatConditionRuleValue();
                gridFormatRule1.ApplyToRow = true;
                gridFormatRule1.Column = gv_Show.Columns["DataType"];
                gridFormatRule1.Name = "Format0";
                formatConditionRuleValue1.Appearance.ForeColor = System.Drawing.Color.Red;
                formatConditionRuleValue1.Appearance.Options.UseForeColor = true;
                formatConditionRuleValue1.Condition = DevExpress.XtraEditors.FormatCondition.Expression;
                formatConditionRuleValue1.Expression = "[DataType] = 1";
                gridFormatRule1.Rule = formatConditionRuleValue1;
                gv_Show.FormatRules.Add(gridFormatRule1);
            catch (Exception ex)
                MessageBox.Show(ex.ToString());

2、当判断依据为字符时,要加引号

 Expression = "[结果] == '不合格'"

七、单元格绑定图片

https://www.cnblogs.com/wuhuacong/p/9145765.html

八、双击行事件

https://www.cnblogs.com/xiaofengfeng/archive/2011/09/15/2177625.html

九、从表格获取数据

1、得到当前选定记录某字段的值

sValue=Table.Rows[gridView1.FocusedRowHandle][FieldName].ToString();

2、得到单元格数据(0行0列)

string ss=gridView1.GetRowCellDisplayText(0,gridView1.Columns[0]);
string ss = gridView1.GetRowCellValue(0, gridView1.Columns[0]);

3、得到列标题的值

DevExpress.XtraGrid.Columns.GridColumn col = gridView1.Columns[0];第一个列标题

GridView添加事件:

        private void gv_1_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
            if (e.Info.IsRowIndicator && e.RowHandle > -1)
                e.Info.DisplayText = (e.RowHandle + 1).ToString();

同时设定宽度:

gv_Msg.IndicatorWidth = 30;

十一、选中行事件

选中事件有两个:
focusedRowChanged()
selectionChanged()
当选择模式为单行时,须使用focusedRowChanged()

十二、上移、下移

  DataTable dtPostgreSql = new DataTable();
  gridControl1.DataSource = dtPostgreSql;
if (gridView1.SelectedRowsCount < 1)
                MessageBox.Show("未选中任何行");
                return;
            if (gridView1.SelectedRowsCount == 1)
                int selectIndex = this.gridView1.GetDataSourceRowIndex(this.gridView1.FocusedRowHandle);
                if (selectIndex - 1 >= 0)
                    object[] ot = dtPostgreSql.Rows[selectIndex].ItemArray;
                    DataRow dr = dtPostgreSql.Rows[selectIndex];
                    dtPostgreSql.Rows.Remove(dr);
                    DataRow drs = dtPostgreSql.NewRow();
                    drs.ItemArray = ot;
                    dtPostgreSql.Rows.InsertAt(drs, selectIndex - 1);
                    gridView1.FocusedRowHandle = selectIndex - 1;
                    dtPostgreSql.AcceptChanges();
                    MessageBox.Show("已到第一行不能继续上移");
            if (gridView1.SelectedRowsCount > 1)
                int[] index = new int[gridView1.SelectedRowsCount];
                int[] rows = gridView1.GetSelectedRows();
                int j=0;
                if (rows[0] - 1 >= 0)
                    for (int i = rows[0]; i < rows[rows.Length - 1] + 1; i++)
                        object[] ot = dtPostgreSql.Rows[i].ItemArray;
                        DataRow dr = dtPostgreSql.Rows[i];
                        dtPostgreSql.Rows.Remove(dr);
                        DataRow drs = dtPostgreSql.NewRow();
                        drs.ItemArray = ot;
                        dtPostgreSql.Rows.InsertAt(drs, i - 1);
                        index[j] = i - 1;
                        j++;
                    gridView1.SelectRows(index[0], index[index.Length - 1]);
                    dtPostgreSql.AcceptChanges();
                }else
                    MessageBox.Show("已到第一行不能继续上移");
     if (gridView1.SelectedRowsCount < 1)
                MessageBox.Show("未选中任何行");
                return;
            if (gridView1.SelectedRowsCount >= 1)
                int[] index = new int[gridView1.SelectedRowsCount];
                int[] rows = gridView1.GetSelectedRows();
                int j = 0;
                if (rows[rows.Length - 1] <= gridView1.RowCount-2)
                    for (int i = rows[rows.Length - 1]; i > rows[0]- 1; i--)
                        object[] ot = dtPostgreSql.Rows[i].ItemArray;
                        DataRow dr = dtPostgreSql.Rows[i];
                        dtPostgreSql.Rows.Remove(dr);
                        DataRow drs = dtPostgreSql.NewRow();
                        drs.ItemArray = ot;
                        dtPostgreSql.Rows.InsertAt(drs, i +1);
                        index[j] = i +1;
                        j++;
                    gridView1.SelectRows(index[0], index[index.Length - 1]);
                    dtPostgreSql.AcceptChanges();
                    MessageBox.Show("已到最后一条记录不能继续下移");

参考:https://blog.csdn.net/fangyu723/article/details/104971670

 十三、添加勾选框

1、普通效果

GridControl控件要设置为不可编辑状态,在“OptionsBehavior”下将“Editable”的值改为false,否则左键单击不管用。

进入“Run Designer”添加三列,在添加该列时将其属性[ColumnEdit]从下拉框中选择“CheckEdit”,然后打开该属性的下来箭头,设置其“ValueChecked”和“ValueUnChecked”的类型及值,这里我用了int类型的1和0来作为状态的指示。

【注:最好还是不要用默认的Bool型的true和false,这样容易出现总是无法显示打钩选中的情况,但是用int型的就不会出现此情况;我找到问题所在了:因为我用了ToString函数,这时会自动把true或者false改变为大写的“True”或“False”,因此判断时就不正确】
选中GridControl的GridView,然后添加其事件“RowClick”,添加事件代码如下:

private void gridView1_RowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e)
            string midValueStr = gridView1.GetDataRow(e.RowHandle)["select"].ToString();
            if (midValueStr == "0" || midValueStr == "")
                gridView1.GetDataRow(e.RowHandle)["select"] = 1;
                gridView1.GetDataRow(e.RowHandle)["select"] = 0;

注:if条件中的空值判断,我的这一列是在数据库取出数据后新添加的,所以其值取出来是空的,而不是0.因此,该行未选中时可能有两种值即0和空。

出处:链接

2、实现单选、复选效果

https://blog.csdn.net/weixin_55972850/article/details/126052837

十四、单独修改某一单元格的值

gv.SetRowCellValue(gv.FocusedRowHandle, gv.Columns[colNames[j]], rowValues.ToArray()[i][j].ToString());

十五、添加右键菜单

1.从工具箱中拖拽一个标准控件ContextMenuStrip到窗体中;

2.点击控件右上方的小三角,添加成员子菜单MenuItem,注意顶端出现的名称;

3.在gdc(不是gdv)控件的ContextMenuStrip属性中选择刚才创建的控件contextPopMenu;

4.添加gdv控件的PopupMenuShowing事件,处理点击右键后,弹出菜单前的处理机制;

5.在PopupMenuShowing事件中可根据当前选中行状态,判断是否弹出菜单,如

 if (!btAlterFlt.Enabled) //编辑状态解钩弹出菜单和控件的关系,实现右键无操作
       gdcFlts.ContextMenuStrip = null;
      gdcFlts.ContextMenuStrip = contextPopMenu;
MenuItemEnterBuffer.Text = $"加入缓冲区 ({buffer.Count})"; //改写菜单项名称

6.在contextPopMenu控件的ItemClicked事件进行处理。

右键点击某菜单项后,gdv的焦点也会切换到当前行,可在此事件中通过FocusRowHandel获取。

参考:链接

十六、删除行

intiSelectRowCount = dgv.SelectedRowsCount;
if(iSelectRowCount > 0)
    dgv.DeleteSelectedRows();

十七、动态添加勾选列、下拉框列、文本列

 1         private void BindShowCol()
 3             int index = 0;
 4             DevExpress.XtraGrid.Columns.GridColumn col = null;
 6             //////////////添加勾选框
 7             col = new DevExpress.XtraGrid.Columns.GridColumn();
 8             col.FieldName = "Check";
 9             col.Caption = "选择";
11             col.Width = 40;
12             col.VisibleIndex = index++;
13             col.Visible = true;
14             DevExpress.XtraEditors.Repository.RepositoryItemCheckEdit ck = new DevExpress.XtraEditors.Repository.RepositoryItemCheckEdit();
15             ck.AutoHeight = false;
16             ck.Name = "ck";
17             ck.CheckedChanged += new System.EventHandler(ck_CheckedChanged);
18             col.ColumnEdit = ck;
19             gv_Show.Columns.Add(col);
21             //////////////添加下拉框
22             col = new DevExpress.XtraGrid.Columns.GridColumn();
23             col.FieldName = "Col1";
24             col.Caption = "Col1";
25             col.Width = 100;
26             col.VisibleIndex = index++;
27             col.Visible = true;
29             DevExpress.XtraEditors.Repository.RepositoryItemComboBox cb_Col1 = new DevExpress.XtraEditors.Repository.RepositoryItemComboBox();
30             cb_Col1.Items.AddRange(ComboItems);
31             cb_Col1.AllowNullInput = DevExpress.Utils.DefaultBoolean.False;
32             cb_Col1.SelectedIndexChanged += new EventHandler(cb_Col1_SelectedIndexChanged);
33             cb_Col1.Name = "cb_Col1";
35             col.ColumnEdit = cb_Col1;
36             gv_Show.Columns.Add(col);
38             //////////////添加文本框
39             col = new DevExpress.XtraGrid.Columns.GridColumn();
40             col.FieldName = "Col2";
41             col.Caption = "Col2";
42             col.Width = 100;
43             col.VisibleIndex = index++;
44             col.OptionsColumn.AllowEdit = false;//设置列不可以编辑
45             gv_Show.Columns.Add(col);
47             col = new DevExpress.XtraGrid.Columns.GridColumn();
48             col.FieldName = "Col3";
49             col.Caption = "Col3";
50             col.Width = 100 ;
51             col.VisibleIndex = index++;
52             col.OptionsColumn.AllowEdit = false;//设置列不可以编辑
53             gv_Show.Columns.Add(col);
55             ///设置表头居中,单元格内容居中
56             gv_Show.Appearance.HeaderPanel.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
57             gv_Show.Appearance.Row.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;

十八、根据点击的行号动态改变下拉框选项

 1         private void gv_Show_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
 3             int CurrentRow = gv_Show.FocusedRowHandle;
 4             if (CurrentRow < 0)
 6                 return;
 9             DevExpress.XtraEditors.Repository.RepositoryItemComboBox cb_Col1 = new DevExpress.XtraEditors.Repository.RepositoryItemComboBox();
10             if (CurrentRow == 1 || CurrentRow == 3)
11             {
12                 ComboItems = new string[2] { "1", "2" };
13             }
14             else
15             {
16                 ComboItems = new string[3] { "A", "B", "C" };
17             }
19             cb_Col1.Items.AddRange(ComboItems);
20             cb_Col1.AllowNullInput = DevExpress.Utils.DefaultBoolean.False;
21             cb_Col1.SelectedIndexChanged += new EventHandler(cb_Col1_SelectedIndexChanged);
22             cb_Col1.Name = "cb_Col1";
24             gv_Show.Columns["Col1"].ColumnEdit = cb_Col1;
25         }

注意:同时存在勾选框和下拉框时:

(1)如果通过CustomRowCellEditForEditing这个事件,使用e.RepositoryItem = cb_Col1来处理的话,会影响勾选列,无法实现目标效果。

(2)如果使用Click、MouseDown这些事件,事件触发在选项框弹出之后,也就是点击下拉框时显示的还是改变之前的内容,下一次点击才是更新的内容。

十九、单元格合并

1、纵向单元格合并

https://blog.csdn.net/GuangXing_HuangXuLin/article/details/117299587

 注意:设置了基偶数行变颜色会让单元格合并事件失效。

2、横向向单元格合并

试过这个:

https://blog.csdn.net/Learn_change_myself/article/details/107791117

内容显示是可以跨单元格的,但是合并单元格的边框线依旧显示。但暂时没找到能改进的方法。

待验证:https://blog.csdn.net/guo3165935/article/details/43561227

3、利用高级带区网格视图实现合并单元格

参考:https://www.cnblogs.com/strive-boy/p/16113369.html

上图例子效果:

要实现合并效果,需要在设计器选择视图AdvBandedGridView:

在CreateColumn()函数中添加代码:

            advBandedGridView1.SetColumnPosition(name, 0, 0);
            advBandedGridView1.SetColumnPosition(age, 1, 0);
            advBandedGridView1.SetColumnPosition(gender, 1, 1);
            advBandedGridView1.SetColumnPosition(school, 0, 0);
            advBandedGridView1.SetColumnPosition(classs, 0, 0);
            //AutoFillDown设置为 true。 列标头将被自动拉伸,来占用它下面的任何空白间隔。
            school.AutoFillDown = true;
            classs.AutoFillDown = true;
            //或者设置classs.RowCount = 2;
            // 要在带区之间移动列,则使用列的 BandedGridColumn.OwnerBand 属性
            //name.OwnerBand = gridBand1;
            //age.OwnerBand = gridBand1;
            //gender.OwnerBand = gridBand1;
            //school.OwnerBand = gridBand2;
            //classs.OwnerBand = gridBand2;
            // 仅当 BandedGridOptionsCustomization.AllowChangeColumnParent 选项被启用时,才可以在带区之间移动列。 否则,只能在父带区内移动列。 

可以按自己的需求添加外观属性设置:

        public void SetBrandGridContrlProperties(AdvBandedGridView gv_Show)
            gv_Show.Name = "gv_ShowRX";
            //禁用列编辑
            gv_Show.OptionsBehavior.ReadOnly = true;
            gv_Show.OptionsBehavior.Editable = false;
            //禁用列筛选
            gv_Show.OptionsCustomization.AllowFilter = false;
            //禁用列排序
            gv_Show.OptionsCustomization.AllowSort = false;
            gv_Show.OptionsDetail.EnableMasterViewMode = false;
            gv_Show.OptionsFilter.FilterEditorUseMenuForOperandsAndOperators = false;//隐藏GridControl的GroupPanel表头
            gv_Show.OptionsView.ShowGroupPanel = false;
            //禁用右击标题列弹出右键菜单
            gv_Show.OptionsMenu.EnableColumnMenu = false;
            gv_Show.Appearance.HeaderPanel.Options.UseTextOptions = true;
            gv_Show.Appearance.Row.Options.UseTextOptions = true;
            gv_Show.OptionsView.RowAutoHeight = true;
            gv_Show.ScrollStyle = DevExpress.XtraGrid.Views.Grid.ScrollStyleFlags.LiveHorzScroll;
            ///设置表头居中,单元格内容居中
            gv_Show.Appearance.HeaderPanel.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
            gv_Show.Appearance.Row.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;

二十、动态根据条件设置行样式

private void gridView6_RowStyle(object sender,DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs e)
      GridView View = sender as GridView;
      if (e.RowHandle >= 0)
          object needAlert =View.GetRowCellValue(e.RowHandle, View.Columns["needAlert"]);
          if (needAlert != null &needAlert != DBNull.Value && needAlert.ToString().Trim() !="0" & View.GetRowCellValue(e.RowHandle,View.Columns["Value"]) != DBNull.Value)
             decimal AverValue = Convert.ToDecimal(View.GetRowCellValue(e.RowHandle, View.Columns["Value"]));
              objectMinValue = View.GetRowCellValue(e.RowHandle,View.Columns["MinValue"]);
              objectMaxVlaue = View.GetRowCellValue(e.RowHandle,View.Columns["MaxValue"]);
              if(MinValue != DBNull.Value & MinValue != null & MaxVlaue.ToString() !="" & MaxVlaue != DBNull.Value && MaxVlaue != null &MaxVlaue.ToString() != "")
                 decimal gridColumn2 = Convert.ToDecimal(MinValue);
                 decimal gridColumn1 = Convert.ToDecimal(MaxVlaue);
                 if (gridColumn2 > AverValue || AverValue > gridColumn1)
                     e.Appearance.ForeColor = Color.Red;
                     e.Appearance.BackColor = Color.LightGray;

二十一、单元格加边框颜色

 private void Form1_Load(object sender, System.EventArgs e)
            new DevExpress.XtraGrid.Design.XViewsPrinting(gridControl1);
        private void gridView1_CustomDrawCell(object sender,
DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e)
            GridView view = sender as GridView;
            if (e.Column == view.FocusedColumn && e.RowHandle == view.FocusedRowHandle)
                CellDrawHelper.DoDefaultDrawCell(view, e);
                CellDrawHelper.DrawCellBorder(e);
                e.Handled = true;

CellDrawHelper.cs:

public static class CellDrawHelper
        public static void DrawCellBorder(DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e)
            Brush brush = Brushes.Black;
            e.Graphics.FillRectangle(brush, new Rectangle(e.Bounds.X - 1, e.Bounds.Y - 1, e.Bounds.Width
+ 2, 2));
            e.Graphics.FillRectangle(brush, new Rectangle(e.Bounds.Right - 1, e.Bounds.Y - 1, 2,
e.Bounds.Height + 2));
            e.Graphics.FillRectangle(brush, new Rectangle(e.Bounds.X - 1, e.Bounds.Bottom - 1,
e.Bounds.Width + 2, 2));
            e.Graphics.FillRectangle(brush, new Rectangle(e.Bounds.X - 1, e.Bounds.Y - 1, 2,
e.Bounds.Height + 2));
        public static void DoDefaultDrawCell(GridView view, RowCellCustomDrawEventArgs e)
            PropertyInfo pi;
            GridControl grid;
            GridViewInfo info;
            GridCellInfo cell;
            GridEditorContainerHelper helper;
            GridViewDrawArgs args;
            info = view.GetViewInfo() as GridViewInfo;
            cell = e.Cell as GridCellInfo;
            grid = view.GridControl;
            pi = grid.GetType().GetProperty("EditorHelper", BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.DeclaredOnly);
            helper = pi.GetValue(grid, null) as GridEditorContainerHelper;
            args = new GridViewDrawArgs(e.Cache, info, e.Bounds);
            e.Appearance.FillRectangle(e.Cache, e.Bounds);
            helper.DrawCellEdit(args, cell.Editor, cell.ViewInfo, e.Appearance,
cell.CellValueRect.Location);

二十二、改变指定行的颜色

需求:想做出按列表顺序执行的效果,执行到改行就变色,并且执行到下一行后上一行颜色不恢复。

试过用设置焦点行的方式实现,但行失去焦点后颜色就恢复了。最后还是通过根据字段内容改变行背景颜色:

绑定RowStyle事件:

gv_Step.RowStyle += new DevExpress.XtraGrid.Views.Grid.RowStyleEventHandler(gv_Step_RowStyle);

当字段Result为1时颜色为绿色,0时为默认控件颜色,TestProcess是行绑定的类:

        private void gv_Step_RowStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs e)
            int hand = e.RowHandle;
            if (hand < 0) return;
            TestProcess salesDocCount = gv_Step.GetRow(hand) as TestProcess;
            if (salesDocCount == null) return;
            if (salesDocCount.Result == "1")
                e.Appearance.BackColor = Color.Green;;
            }
else
            {
                e.Appearance.BackColor = Color.White;
            }

执行过程中设定焦点行,实现执行到改行就变色:

//设置焦点行
m_List[TestProcessIndex].Result = "1";//更改数据源
this.BeginInvoke(new Action(() => { gv_Step.FocusedRowHandle = TestProcessIndex;}));
TestProcessIndex++;//当前执行的行号

重复执行该列表的话要刷新数据源,并刷新控件,让颜色恢复到都没有执行时的颜色:

 for (int i = 0; i < m_List.Count; i++)
 {
      m_List[i].Result = "0";
 }

gv_Step.FocusedRowHandle = 0; gc_Step.BeginInit();//刷新控件,否则颜色不恢复 gc_Step.EndInit();

注:用这个方法在执行过程中点击其他行的话,颜色会乱(比如已变为绿色的行又恢复到原来的颜色)。直接禁用整个GridControl的话又无法拖动滑动条了,但也没找到禁止选择行的属性。可以在焦点改变事件中把当前焦点行设为刚刚设定的焦点TestProcessIndex,实现禁止选中行的需求:

        private void gv_Step_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
            gv_Step.FocusedRowHandle = TestProcessIndex;

这样颜色不会乱, 也能控制滑动条了。

根据相似的原理,该功能用添加规则方式也可以实现,参见本文第六大点。

参考:https://blog.csdn.net/weixin_43976890/article/details/107004102


二十三、按表格字段实现多层分组

        /// <summary>
        /// 添加列
        /// </summary>
        private void BindGroup()
            int index = 0;
            DevExpress.XtraGrid.Columns.GridColumn col = null;
            //第1列
            col = new DevExpress.XtraGrid.Columns.GridColumn();
            col.FieldName = string.Format("Col{0}", index);
            col.Caption = string.Format("Col{0}", index);
            col.Width = 100;
            col.VisibleIndex = index++;
            col.OptionsColumn.AllowEdit = false;//设置列不可以编辑
            //Group设置
            col.GroupIndex = 0;//列为第一组
            gv_Group.Columns.Add(col);
            //第2列
            col = new DevExpress.XtraGrid.Columns.GridColumn();
            col.FieldName = string.Format("Col{0}", index);
            col.Caption = string.Format("Col{0}", index);
            col.Width = 100;
            col.VisibleIndex = index++;
            col.OptionsColumn.AllowEdit = false;//设置列不可以编辑
            //Group设置
            col.SortOrder = DevExpress.Data.ColumnSortOrder.Ascending; //按升序排列
            gv_Group.Columns.Add(col);
            //第3列
            col = new DevExpress.XtraGrid.Columns.GridColumn();
            col.FieldName = string.Format("Col{0}", index);
            col.Caption = string.Format("Col{0}", index);
            col.Width = 100;
            col.VisibleIndex = index++;
            col.OptionsColumn.AllowEdit = false;//设置列不可以编辑
            //Group设置
            col.SummaryItem.DisplayFormat = "最大值:{0}"; //显示格式
            col.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Max;//统计出最大值
            gv_Group.Columns.Add(col);
            //第4列
            col = new DevExpress.XtraGrid.Columns.GridColumn();
            col.FieldName = string.Format("Col{0}", index);
            col.Caption = string.Format("Col{0}", index);
            col.Width = 100;
            col.VisibleIndex = index++;
            col.OptionsColumn.AllowEdit = false;//设置列不可以编辑
            //Group设置
            col.GroupIndex = 1;//列为第二组
            gv_Group.Columns.Add(col);
            //组名格式可由 GroupFormat设置
        /// <summary>
        /// 动态绑定数据
        /// </summary>
        private void BindGroupSource()
            for (int i = 0; i < 6; i++)
                DataGroup_DT.Columns.Add(string.Format("Col{0}", i), typeof(string));
            for (int i = 0; i < 10; i++)
                DataRow dr = DataGroup_DT.NewRow();
                if (i % 2 == 0)
                    dr["Col0"] = "A";
                    dr["Col0"] = "B";
                dr["Col1"] = 2 * (i + 1);
                dr["Col2"] = 3 * (i + 1); 
                if (i < 5)
                    dr["Col3"] = "aa";
                    dr["Col3"] = "bb";
                DataGroup_DT.Rows.Add(dr);
            gc_Group.DataSource = DataGroup_DT;
            gv_Group.ExpandAllGroups();//展开所有组
            //gv_Group.OptionsBehavior.Editable = true;
            //gv_Group.OptionsBehavior.ReadOnly = false;
            //汇总结果是显示在Footer面板中的,gridView中的Footer面板默认是不显示的,所以必须要先设置
            gv_Group.OptionsView.ShowFooter = true;//是否显示页脚
            //添加组计算
            //gv_Group.GroupSummary.Add(DevExpress.Data.SummaryItemType.Sum, "Col2", gv_Group.Columns["Col2"], "组计:{0}");
            //设置Col3为备注
            gv_Group.OptionsView.ShowPreview = true;//是否显示备注
            gv_Group.PreviewFieldName = "Col3";

参考:https://blog.csdn.net/qq_33459369/article/details/79992054

更简单的分组方法:

https://www.cnblogs.com/qingtian-jlj/p/6063597.html

关键代码:

        gv_Show.Columns["DirName"].GroupIndex = 0;//设置分组列(该值默认均为-1,即不分组)
        gv_Show.OptionsBehavior.AutoExpandAllGroups = true;//展开所有分组

会自动按指定的列名来分组显示。

二十四、实现主从表(数据源List嵌套)

    /// <summary>
    /// 书橱主表类
    /// </summary>
    public class bookcase
        public string id { get; set; }
        public string bcid { get; set; }
        public string name { get; set; }
        /// <summary>
        /// books
        /// </summary>
        public List<book> books1 { get; set; }
        public List<book> books2 { get; set; }
    /// <summary>
    /// 书本从表类
    /// </summary>
    public class book
        public string id { get; set; }
        //书橱id
        public string bookcase_bid { get; set; }
        public string bookName { get; set; }
        //书橱(主表)
        List<bookcase> bookcaseList = new List<bookcase>();
        public void BindData()
            List<string> ColNames = new List<string>() { "id", "bcid", "name", "id", "bookcase_bid", "bookName" };
            List<string> caption1 = new List<string>() { "书橱序号", "书橱ID", "书橱名称", "书本序号", "书本ID", "书本名称" };
            //DevExpress.XtraGrid.Columns.GridColumn col1 = null;
            int colIndex = 0;
            for (int i = 0; i < 3; i++)
                DevExpress.XtraGrid.Columns.GridColumn col1 = new DevExpress.XtraGrid.Columns.GridColumn();
                col1.FieldName = ColNames[i];
                col1.Caption = caption1[i];
                col1.Width = 100;
                col1.VisibleIndex = colIndex++;
                col1.OptionsColumn.AllowEdit = false;//设置列不可以编辑
                gridView1.Columns.Add(col1);
            for (int i = 3; i < ColNames.Count; i++)
                DevExpress.XtraGrid.Columns.GridColumn col1 = new DevExpress.XtraGrid.Columns.GridColumn();
                col1.FieldName = ColNames[i];
                col1.Caption = caption1[i];
                col1.Width = 100;
                col1.VisibleIndex = colIndex++;
                col1.OptionsColumn.AllowEdit = false;//设置列不可以编辑
                gridView2.Columns.Add(col1);
            for (int i = 3; i < ColNames.Count; i++)
                DevExpress.XtraGrid.Columns.GridColumn col1 = new DevExpress.XtraGrid.Columns.GridColumn();
                col1.FieldName = ColNames[i];
                col1.Caption = caption1[i];
                col1.Width = 100;
                col1.VisibleIndex = colIndex++;
                col1.OptionsColumn.AllowEdit = false;//设置列不可以编辑
                gridView3.Columns.Add(col1);
            gridControl1.DataSource = bookcaseList;
            //for (int i = 0; i < gridView1.Columns.Count; i++)
            //    col1.FieldName = ColNames[i];
            //    gridView1.Columns[i].Caption = caption1[i];
            //ExpandAllRows(gridView1);
            gridView2.ViewCaption = "书单1";
            gridView3.ViewCaption = "书单2";
            for (int i = 0; i < gridControl1.ViewCollection.Count; i++)
                DevExpress.XtraGrid.Views.Grid.GridView gv = (DevExpress.XtraGrid.Views.Grid.GridView)gridControl1.ViewCollection[i];
                SetGridContrl(gv);
                gv.OptionsSelection.MultiSelect = true;
                gv.OptionsSelection.MultiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.RowSelect;
                gv.OptionsSelection.InvertSelection = false;
                gv.OptionsSelection.EnableAppearanceFocusedCell = false;
                //ExpandAllRows(gv);
                gv.OptionsBehavior.AutoExpandAllGroups = true;//展开所有分组
            gridControl1.DoubleClick += new EventHandler((s, evn) => gv_DoubleClick(s, evn));
        //添加数据源
        private void btn_Refresh_Click(object sender, EventArgs e)
            //书橱顺序ID,书橱ID,顺序名称
            for (int i = 0; i < 3; i++)
                bookcase bkcase1 = new bookcase();
                bkcase1.id = i.ToString();
                bkcase1.bcid = i.ToString();
                bkcase1.name = "bkcase" + i.ToString();
                bkcase1.books1 = new List<book>();
                bkcase1.books2 = new List<book>();
                for (int j = 0; j < 4; j++)
                    book bk1 = new book();
                    bk1.id = j.ToString();
                    bk1.bookcase_bid = i.ToString();
                    bk1.bookName = "book1-" + j.ToString();
                    bkcase1.books1.Add(bk1);
                    book bk2 = new book();
                    bk2.id = j.ToString();
                    bk2.bookcase_bid = i.ToString();
                    bk2.bookName = "book2-" + j.ToString();
                    bkcase1.books2.Add(bk2);
                bookcaseList.Add(bkcase1);
            gridControl1.DataSource = null;
            gridControl1.DataSource = bookcaseList;
(gridControl1.MainView as GridView).CollapseAllDetails(); //要折叠主视图中的所有主控行
public void ExpandAllRows(GridView view)
    view.BeginUpdate();
        int dataRowCount = view.DataRowCount;
        for (int rHandle = 0; rHandle < dataRowCount; rHandle++)
            view.SetMasterRowExpanded(rHandle, true);
    finally
        view.EndUpdate();

 出处:Dev中GridControl构建主从表

2、点击从表获取选中行的数据

private void gridView1_MasterRowExpanded(object sender, CustomMasterRowEventArgs e) 
     GridView master = sender as GridView;
     GridView detail = master.GetDetailView(e.RowHandle, e.RelationIndex) as GridView;

参考链接:https://blog.csdn.net/guojlh/article/details/45726755

 二十五、添加按钮列

https://blog.csdn.net/fangyu723/article/details/106046457

            DevExpress.XtraGrid.Columns.GridColumn col = new DevExpress.XtraGrid.Columns.GridColumn();
            col.FieldName = "OnOff";
            col.Caption = "开关";
            col.Width = 10;
            col.VisibleIndex = index++;
            col.Visible = true;
            DevExpress.XtraEditors.Repository.RepositoryItemToggleSwitch ts = new DevExpress.XtraEditors.Repository.RepositoryItemToggleSwitch();
            ts.AutoHeight = true;
            ts.LookAndFeel.UseDefaultLookAndFeel = false;
            //ts.LookAndFeel.SkinMaskColor = Color.FromArgb(204, 0, 0);
            ts.Name = "ts";
            ts.Toggled += new EventHandler(ts_Toggled);
            col.ColumnEdit = ts;
            gv_Ctrl.Columns.Add(col);
            DT_Ctrl.Columns.Add(col.FieldName, typeof(bool));

实现事件:

        private void ts_Toggled(object sender, EventArgs e)
            DevExpress.XtraEditors.ToggleSwitch ts = sender as DevExpress.XtraEditors.ToggleSwitch;
            int CurrentRow = gv_Ctrl.FocusedRowHandle;
            if (CurrentRow < 0)
                return;

二十六、单元格编辑完毕事件

//gridcontrol输入验证
private void gdv_reguline_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e)
    int col =((DevExpress.XtraGrid.Views.Grid.GridView)sender).FocusedColumn.AbsoluteIndex;
    if (col == 4 || col == 5)
       object v = e.Value;
       int tm;
       if (v != null && (!Int32.TryParse(v.ToString(),out tm) || tm<0 )) //自定义验证逻辑
            e.Valid = false; //控制是否通过验证的开关
            e.ErrorText = "必须输入正整数!"; //提示的验证失败的原因

参考:https://blog.csdn.net/caoyanchao1/article/details/121440257

二十七、同步两个GridControl的滚动条

private void gridview1_TopRowChanged(object sender, EventArgs e)
    gridview2.TopRowIndex = (sender as GridView).TopRowIndex;