自定义GridControl编辑器
本文版权归博主 惊梦无痕 所有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作。原文地址
鉴于网上的针对GridControl的一些代码比较凌乱,且功能分散,故将整理过的代码分享出来。
本代码用的DevExpress版本号:17.2.6.0,旧的版本可能有些地方会有些微的变化。
目前该自定义编辑器中集成了一些比较实用的功能,希望对使用或正在学习DevExpress的同学有所帮助。
等下次有时间再把其他的一些自定义通用控件也发出来。
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Windows.Forms; 7 using Comteck.Winforms.Controls.Components; 8 using Comteck.Winforms.Utils; 9 using DevExpress.Data.Filtering; 10 using DevExpress.Utils; 11 using DevExpress.Utils.Serializing; 12 using DevExpress.XtraEditors; 13 using DevExpress.XtraGrid; 14 using DevExpress.XtraGrid.Columns; 15 using DevExpress.XtraGrid.Registrator; 16 using DevExpress.XtraGrid.Views.Base; 17 using DevExpress.XtraGrid.Views.Base.Handler; 18 using DevExpress.XtraGrid.Views.Base.ViewInfo; 19 using DevExpress.XtraGrid.Views.Grid; 20 using DevExpress.XtraGrid.Views.Grid.Drawing; 21 using DevExpress.XtraGrid.Views.Grid.ViewInfo; 22 23 namespace Comteck.Winforms.Controls { 24 #region MyGridControl 25 26 /// <summary> 27 /// A grid view is represented by several classes. 28 /// Please make sure that you inherit the appropriate class to implement a specific functionality: 29 /// GridView - a central grid view class, which manages columns, view infos, a painter, mouse and keyboard handlers. 30 /// GridHandler - processes the mouse and keyboard. 31 /// GridViewInfo - calculates view information for drawing a grid view on screen. 32 /// GridViewPrintInfo - calculates the information necessary to print a grid view. 33 /// 34 /// Assume, you have created a GridView descendant and want to use your class with the GridControl at design time. 35 /// You should do the following to register it: 36 /// 1. Create a Registrator class (please see GridInfoRegistrator in ViewRegistrator.cs). 37 /// Please note: you will need to be careful when overriding the ViewName property, 38 /// because it is used to identify the view within the GridControl's descendant. 39 /// Please make certain that you are using the same view name both in the registrator's ViewName property 40 /// and within the GridControl's CreateDefaultView overridden method. 41 /// 2. Inherit the GridControl class and override the RegisterAvailableViewsCore 42 /// method (it was the RegisterAvailableViews method in XtraGrid 2). 43 /// 3. If you want the GridControl to create an instance of your GridView by default, 44 /// you should override the GridControl.CreateDefaultView method. 45 /// 46 /// 创建自定义的MyGridControl 47 /// <para>https://www.devexpress.com/Support/Center/Search/List/1?searchString=treelist</para> 48 /// <para>http://www.dxper.net/thread-555-1-1.html</para> 49 /// </summary> 50 [ToolboxItem(true)] 51 public class MyGridControl : GridControl { 52 /// <summary> 53 /// Create a new MyGridControl object 54 /// </summary> 55 public MyGridControl() 56 : base() { 57 // 使用内置的分页 58 this.CustomInit(); 59 } 60 61 /// <summary> 62 /// 创建初始化的GridView视图(请参照第3点) 63 /// </summary> 64 /// <returns></returns> 65 protected override BaseView CreateDefaultView() { 66 return base.CreateView("MyGridView"); 67 } 68 69 /// <summary> 70 /// 向容器中注册所有的控件 71 /// </summary> 72 /// <param name="collection"></param> 73 protected override void RegisterAvailableViewsCore(InfoCollection collection) { 74 base.RegisterAvailableViewsCore(collection); 75 collection.Add(new MyGridViewInfoRegistrator()); 76 collection.Add(new MyBandedGridInfoRegistrator()); 77 } 78 79 /// <summary> 80 /// 初始化内置的分页,如果要使用增、删、改功能,则把下面的代码注释即可 81 /// </summary> 82 private void InitNagigator() { 83 this.EmbeddedNavigator.TextStringFormat = "记录 {0} / {1}"; 84 this.EmbeddedNavigator.Buttons.Append.Visible = false; 85 this.EmbeddedNavigator.Buttons.Remove.Visible = false; 86 this.EmbeddedNavigator.Buttons.Edit.Visible = false; 87 this.EmbeddedNavigator.Buttons.EndEdit.Visible = false; 88 this.EmbeddedNavigator.Buttons.CancelEdit.Visible = false; 89 } 90 91 private void CustomInit() { 92 this.InitNagigator(); 93 } 94 } 95 96 #endregion 97 98 #region 创建自定义的GridView 99 100 /// <summary> 101 /// 创建自定义的GridView 102 /// </summary> 103 public class MyGridView : GridView { 104 /// <summary> 105 /// DevExpress选择列的默认fieldname 106 /// </summary> 107 public const string DEVEXPRESS_SELECTION_NAME = "DX$CheckboxSelectorColumn"; 108 /// <summary> 109 /// 当光标在末行最后一个指定字段时继续回车的跳转方式 110 /// </summary> 111 public enum EnumForwardType { 112 [Description("跳转到首行首列")] 113 Circle = 0, 114 [Description("停止跳转,直接返回")] 115 Stop = 1, 116 [Description("新增一行,光标定位到新行指定列")] 117 NewRow = 2, 118 } 119 120 /// <summary> 121 /// Default View Name 122 /// </summary> 123 protected override string ViewName => "MyGridView"; 124 125 public delegate void AddNewLineDelegate(); 126 /// <summary> 127 /// 新增行自定义事件 128 /// </summary> 129 public AddNewLineDelegate AddNewLineEventHandler; 130 131 #region 自定义属性 132 133 // 134 // 摘要: 135 // 当 GridView 没有数据时是否显示提示,提示的值由 EmptyForegroundText 属性设置 136 [DefaultValue(false),] 137 [DXCategory("自定义属性")] 138 [Description("当 GridView 没有数据时是否显示提示,提示的值由 EmptyForegroundText 属性设置")] 139 [XtraSerializableProperty] 140 public virtual bool EnableShowEmptyForeground { get; set; } 141 // 142 // 摘要: 143 // 当 GridView 没有数据时的默认提示. 144 [DefaultValue(typeof(string), "")] 145 [DXCategory("自定义属性")] 146 [Description("当 GridView 没有数据时显示的值,默认显示\"没有查询到你所想要的数据!\"")] 147 [XtraSerializableProperty] 148 public virtual string EmptyForegroundText { get; set; } 149 // 150 // 摘要: 151 // GridView 回车时按指定字段跳转到相应的单元格. 152 // 调用方法如:new List<string>() { "SKUCODE", "PRICE", "DESCRIPTION" }; 153 [DefaultValue(typeof(List<string>), "")] 154 [DXCategory("自定义属性")] 155 [Description("指定可以跳转的列(FieldName),回车时按值先后顺序跳转")] 156 [XtraSerializableProperty] 157 [TypeConverter(typeof(CollectionConverter))] 158 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 159 [Browsable(false)] 160 public virtual List<string> ForwardColumnList { get; set; } 161 // 162 // 摘要: 163 // 当光标在末行最后一个指定字段时继续回车的跳转方式. 164 [DefaultValue(typeof(EnumForwardType), "Circle")] 165 [DXCategory("自定义属性")] 166 [Description("当光标在末行最后一个指定字段时继续回车的跳转方式")] 167 [XtraSerializableProperty] 168 public virtual EnumForwardType ForwardType { get; set; } = EnumForwardType.Circle; 169 // 170 // 摘要: 171 // 当末行最后一列回车新增行时,指定光标在新行定位的列(FieldName). 172 [DefaultValue(typeof(string), "")] 173 [DXCategory("自定义属性")] 174 [Description("当末行最后一列回车新增行时,指定光标在新行定位的列(FieldName),默认为新增行首个可编辑列")] 175 [XtraSerializableProperty] 176 public virtual string LocatedColumn { get; set; } 177 178 #endregion 179 180 #region 构造函数 181 182 /// <summary> 183 /// 默认构造 184 /// </summary> 185 public MyGridView() { 186 this.OptionsFilter.ColumnFilterPopupMode = DevExpress.XtraGrid.Columns.ColumnFilterPopupMode.Classic; 187 } 188 189 /// <summary> 190 /// 含参构造 191 /// </summary> 192 /// <param name="grid"></param> 193 public MyGridView(GridControl ownerGrid) 194 : base(ownerGrid) { 195 this.OptionsFilter.ColumnFilterPopupMode = DevExpress.XtraGrid.Columns.ColumnFilterPopupMode.Classic; 196 } 197 198 #endregion 199 200 #region 自定义方法 201 202 /// <summary> 203 /// 初始化,设置默认值 204 /// </summary> 205 public void Initialize() { 206 // 设置为多选 207 this.OptionsSelection.MultiSelect = true; 208 // 自带勾选列的宽度 209 this.OptionsSelection.CheckBoxSelectorColumnWidth = 35; 210 // 选中序号列是否勾选 211 this.OptionsSelection.UseIndicatorForSelection = false; 212 // 隐藏提示 213 this.OptionsView.ShowGroupPanel = false; 214 // 是否自适应列宽度 215 this.OptionsView.ColumnAutoWidth = false; 216 // 是否启用偶数行外观 217 this.OptionsView.EnableAppearanceEvenRow = true; 218 // 是否启用奇数行外观 219 this.OptionsView.EnableAppearanceOddRow = true; 220 // 是否显示过滤面板 221 this.OptionsView.ShowFilterPanelMode = ShowFilterPanelMode.Never; 222 // 是否显示子报表 223 this.OptionsDetail.EnableMasterViewMode = false; 224 // 筛选模式 225 this.OptionsFilter.ColumnFilterPopupMode = DevExpress.XtraGrid.Columns.ColumnFilterPopupMode.Classic; 226 // 编辑模式 227 this.OptionsBehavior.EditorShowMode = EditorShowMode.MouseUp; 228 // 打印效果 229 this.OptionsPrint.AutoWidth = false; 230 // 字段标题居中 231 this.Appearance.HeaderPanel.TextOptions.HAlignment = HorzAlignment.Center; 232 // 选中行颜色 233 this.SetAppearanceColor(); 234 // 是否回车后光标移到下一个单元格 235 this.OptionsNavigation.EnterMoveNextColumn = true; 236 // 是否允许移动列 237 this.OptionsCustomization.AllowColumnMoving = false; 238 // 默认选中第一行 239 this.FocusedRowHandle = 0; 240 // 设置行号宽度 241 this.IndicatorWidth = 28; 242 } 243 244 /// <summary> 245 /// 设置单元格是否可编辑 246 /// </summary> 247 /// <param name="editableColumnsList">当GridView可编辑时,指定可以编辑的列(FieldName).</param> 248 public void SetEditableColumns(List<string> editableColumnsList) { 249 if (this.OptionsBehavior.Editable && editableColumnsList != null && editableColumnsList.Count > 0) { 250 foreach (GridColumn col in this.Columns) { 251 if (editableColumnsList.Exists(x => x == col.FieldName)) { 252 // 设置标题字体色 253 col.AppearanceHeader.ForeColor = Color.Blue; 254 col.OptionsColumn.AllowEdit = true; 255 } else { 256 // 设置标题字体色 257 col.AppearanceHeader.ForeColor = Color.Black; 258 col.OptionsColumn.AllowEdit = false; 259 } 260 } 261 } 262 } 263 264 /// <summary> 265 /// 判断是否为表格最后一列可编辑列 266 /// </summary> 267 /// <param name="view"></param> 268 /// <param name="focusedColumn"></param> 269 /// <returns></returns> 270 private bool IsLastEditableColumn(GridColumn focusedColumn) { 271 var index = this.VisibleColumns.IndexOf(focusedColumn); 272 273 for (int i = this.VisibleColumns.Count - 1; i >= 0; i--) { 274 GridColumn column = this.VisibleColumns[i]; 275 // 忽略不可编辑Column 276 if (!column.OptionsColumn.AllowEdit) continue; 277 // 当前列如果是最后一列可编辑列,则返回True,否则返回False 278 return index == i; 279 } 280 // 如果都不可编辑,则返回False 281 return false; 282 } 283 284 /// <summary> 285 /// 添加新行 286 /// </summary> 287 private void AddNewLine() { 288 var list = this.GridControl.DataSource; 289 // 获取当前实例的 Type 290 var t = this.DataSource.GetType(); 291 // 动态创建实例 292 var obj = Activator.CreateInstance(t.GetGenericArguments()[0]); 293 // 调用公用方法 Add 294 var method = t.GetMethod("Add"); 295 // 将构建好的实例添加到数据源中 296 method.Invoke(list, new object[] { obj }); 297 // 刷新数据源 298 this.RefreshData(); 299 } 300 301 /// <summary> 302 /// 获取GridView过滤或排序后的数据集 303 /// </summary> 304 /// <typeparam name="T">泛型对象</typeparam> 305 /// <returns></returns> 306 public IEnumerable<T> GetFilteredDataSource<T>() where T : class { 307 var list = new List<T>(); 308 for (int i = 0; i < this.RowCount; i++) { 309 if (this.IsGroupRow(i)) continue; 310 311 var entity = this.GetRow(i) as T; 312 if (entity == null) continue; 313 314 list.Add(entity); 315 } 316 return list; 317 } 318 319 /// <summary> 320 /// 获取GridView的选中行数据集(数据源是 DataTable) 321 /// </summary> 322 /// <returns></returns> 323 public DataTable GetSelectedDataRows() { 324 var dt = (this.DataSource as DataView).Table.Clone(); 325 var rowIds = this.GetSelectedRows(); 326 327 foreach (var id in rowIds) { 328 var row = (this.GetRow(id) as DataRowView).Row; 329 if (row == null) continue; 330 331 dt.Rows.Add(row.ItemArray); 332 } 333 return dt; 334 } 335 336 #endregion 337 338 /// <summary> 339 /// 在初始化后注册一些事件 340 /// </summary> 341 public override void EndInit() { 342 base.EndInit(); 343 344 // 针对MyGridLookUpEdit的情况 345 if (string.IsNullOrWhiteSpace(this.GridControl?.Name)) return; 346 347 // 设置行号 348 this.CustomDrawRowIndicator += new RowIndicatorCustomDrawEventHandler(MyGridView_CustomDrawRowIndicator); 349 // 设置行号宽度 350 this.RowCountChanged += new EventHandler(MyGridView_RowCountChanged); 351 // 在查询得到0条记录时显示自定义的字符提示/显示 352 this.CustomDrawEmptyForeground += new CustomDrawEventHandler(MyGridView_CustomDrawEmptyForeground); 353 // 回车跳转单元格(配合 ForwardColumnList 使用) 354 this.KeyDown += new KeyEventHandler(MyGridView_KeyDown); 355 } 356 357 /// <summary> 358 /// 设置自动行号 359 /// </summary> 360 /// <param name="sender"></param> 361 /// <param name="e"></param> 362 private void MyGridView_CustomDrawRowIndicator(object sender, RowIndicatorCustomDrawEventArgs e) { 363 if (e.Info.IsRowIndicator && e.RowHandle >= 0) { 364 e.Info.DisplayText = (e.RowHandle + 1).ToString(); 365 } 366 } 367 368 /// <summary> 369 /// 行号宽度随行数的变化而变化 370 /// </summary> 371 /// <param name="sender"></param> 372 /// <param name="e"></param> 373 private void MyGridView_RowCountChanged(object sender, EventArgs e) { 374 // 根据总行数设置行号宽度 375 this.IndicatorWidth = 28 + (this.RowCount.ToString().Length - 1) * 10; 376 } 377 378 /// <summary> 379 /// 在查询得到0条记录时显示自定义的字符提示/显示 380 /// </summary> 381 /// <param name="sender"></param> 382 /// <param name="e"></param> 383 private void MyGridView_CustomDrawEmptyForeground(object sender, CustomDrawEventArgs e) { 384 if (!this.EnableShowEmptyForeground) return; 385 386 string showText = string.IsNullOrWhiteSpace(this.EmptyForegroundText) ? "没有查询到你所想要的数据!" : this.EmptyForegroundText; 387 388 //方法一(此方法为GridView设置了数据源绑定时,可用) 389 try { 390 var bindingSource = this.DataSource as BindingSource; 391 if (bindingSource.Count == 0) { 392 var str = showText; 393 var f = new Font("宋体", 10, FontStyle.Bold); 394 var r = new Rectangle(e.Bounds.Top + 5, e.Bounds.Left + 5, e.Bounds.Right - 5, e.Bounds.Height - 5); 395 e.Graphics.DrawString(str, f, Brushes.Black, r); 396 } 397 } catch { 398 //方法二(此方法为GridView没有设置数据源绑定时使用,一般使用此种方法) 399 if (this.RowCount == 0) { 400 var str = showText; 401 var f = new Font("宋体", 10, FontStyle.Bold); 402 var r = new Rectangle(e.Bounds.Left + 5, e.Bounds.Top + 5, e.Bounds.Width - 5, e.Bounds.Height - 5); 403 e.Graphics.DrawString(str, f, Brushes.Black, r); 404 } 405 } 406 } 407 408 #region 单元格回车事件 409 410 /// <summary> 411 /// 默认情况下,回车或Tab按可编辑列跳转 412 /// </summary> 413 /// <param name="sender"></param> 414 /// <param name="e"></param> 415 private void OnDefaultKeyDown(object sender, KeyEventArgs e) { 416 if (!((e.KeyCode == Keys.Enter && this.OptionsNavigation.EnterMoveNextColumn) || e.KeyCode == Keys.Tab)) return; 417 418 GridColumn column = null; 419 var index = this.VisibleColumns.IndexOf(this.FocusedColumn); 420 421 // 光标是否在最后一列可编辑列 422 if (IsLastEditableColumn(this.FocusedColumn)) { 423 #region 判断是否到达末行 424 425 if (this.FocusedRowHandle >= this.RowCount - 1) { 426 // 此处可选择跳转到首行或者直接返回或者新增行 427 switch (this.ForwardType) { 428 case EnumForwardType.Circle: // 首行首列 429 this.MoveFirst(); 430 for (int i = 0; i < this.VisibleColumns.Count; i++) { 431 column = this.VisibleColumns[i]; 432 // 忽略不可编辑Column 433 if (!column.OptionsColumn.AllowEdit) continue; 434 // 当前列可编辑,则光标定位到该列 435 this.FocusedColumn = column; 436 return; 437 } 438 break; 439 case EnumForwardType.Stop: // 停止跳转,直接返回 440 e.Handled = true; 441 break; 442 case EnumForwardType.NewRow: // 新增行,并跳转到新行首列 443 if (this.AddNewLineEventHandler == null) 444 AddNewLine(); 445 else 446 AddNewLineEventHandler(); 447 448 this.MoveNext(); 449 // 没有指定定位字段 450 if (string.IsNullOrWhiteSpace(this.LocatedColumn)) { 451 for (int i = 0; i < this.VisibleColumns.Count; i++) { 452 column = this.VisibleColumns[i]; 453 // 忽略不可编辑Column 454 if (!column.OptionsColumn.AllowEdit) continue; 455 // 当前列可编辑,则光标定位到该列 456 this.FocusedColumn = column; 457 return; 458 } 459 } else { 460 this.FocusedColumn = this.Columns[this.LocatedColumn]; 461 } 462 break; 463 } 464 return; 465 } 466 467 #endregion 468 469 this.MoveNext(); 470 for (int i = 0; i < this.VisibleColumns.Count; i++) { 471 column = this.VisibleColumns[i]; 472 // 忽略不可编辑Column 473 if (!column.OptionsColumn.AllowEdit) continue; 474 // 如果是系统自带的编辑列,则直接跳过 475 if (column.FieldName == DEVEXPRESS_SELECTION_NAME) continue; 476 477 // 当前列可编辑,则光标定位到该列 478 this.FocusedColumn = column; 479 return; 480 } 481 } else { 482 // 从当前定位列跳转到下一可编辑列 483 for (int i = index + 1; i < this.VisibleColumns.Count; i++) { 484 column = this.VisibleColumns[i]; 485 // 忽略不可编辑Column 486 if (!column.OptionsColumn.AllowEdit) continue; 487 // 如果是系统自带的编辑列,则直接跳过 488 if (column.FieldName == DEVEXPRESS_SELECTION_NAME) continue; 489 490 // 当前列可编辑,则光标定位到该列 491 this.FocusedColumn = column; 492 return; 493 } 494 495 // 如果光标在不可编辑列 496 for (int i = 0; i <= index; i++) { 497 column = this.VisibleColumns[i]; 498 // 忽略不可编辑Column 499 if (!column.OptionsColumn.AllowEdit) continue; 500 // 如果是系统自带的编辑列,则直接跳过 501 if (column.FieldName == DEVEXPRESS_SELECTION_NAME) continue; 502 503 // 当前列可编辑,则光标定位到该列 504 this.FocusedColumn = column; 505 return; 506 } 507 } 508 } 509 510 /// <summary> 511 /// 自定义跳转,按指定列字段跳转 512 /// </summary> 513 /// <param name="sender"></param> 514 /// <param name="e"></param> 515 private void OnCustomerKeyDown(object sender, KeyEventArgs e) { 516 if (!((e.KeyCode == Keys.Enter && this.OptionsNavigation.EnterMoveNextColumn) || e.KeyCode == Keys.Tab)) return; 517 518 var fieldName = this.FocusedColumn.FieldName; 519 520 if (this.ForwardColumnList.Contains(fieldName)) { 521 var index = this.ForwardColumnList.IndexOf(fieldName); 522 523 // 光标不在当前行指定列集合的最后一列 524 if (index != this.ForwardColumnList.Count - 1) { 525 this.FocusedColumn = this.Columns[this.ForwardColumnList[index + 1]]; 526 } else // 光标定位当前行指定列集合的最后一列 527 { 528 #region 判断是否到达末行 529 530 if (this.FocusedRowHandle >= this.RowCount - 1) { 531 // 此处可选择跳转到首行或者直接返回或者新增行 532 switch (this.ForwardType) { 533 case EnumForwardType.Circle: // 首行首列 534 this.MoveFirst(); 535 this.FocusedColumn = this.Columns[this.ForwardColumnList[0]]; 536 break; 537 case EnumForwardType.Stop: // 停止跳转,直接返回 538 e.Handled = true; 539 break; 540 case EnumForwardType.NewRow: // 新增行,并跳转到新行首列 541 if (this.AddNewLineEventHandler == null) 542 AddNewLine(); 543 else 544 AddNewLineEventHandler(); 545 546 fieldName = string.IsNullOrWhiteSpace(this.LocatedColumn) ? this.ForwardColumnList[0] : this.LocatedColumn; 547 548 this.MoveNext(); 549 this.FocusedColumn = this.Columns[fieldName]; 550 break; 551 } 552 return; 553 } 554 555 #endregion 556 557 this.MoveNext(); 558 this.FocusedColumn = this.Columns[this.ForwardColumnList[0]]; 559 } 560 } else { 561 this.FocusedColumn = this.Columns[this.ForwardColumnList[0]]; 562 } 563 } 564 565 /// <summary> 566 /// 回车跳转单元格 567 /// </summary> 568 /// <param name="sender"></param> 569 /// <param name="e"></param> 570 private void MyGridView_KeyDown(object sender, KeyEventArgs e) { 571 if (!((e.KeyCode == Keys.Enter && this.OptionsNavigation.EnterMoveNextColumn) || e.KeyCode == Keys.Tab)) return; 572 573 if (this.ValidateEditor() == false) { 574 return; 575 } 576 577 // 未设置,则按默认规则跳转 578 if (this.ForwardColumnList == null || this.ForwardColumnList.Count == 0) { 579 OnDefaultKeyDown(sender, e); 580 } else { 581 OnCustomerKeyDown(sender, e); 582 } 583 } 584 585 #endregion 586 587 #region GridLookUpEdit 模糊匹配 588 589 /// <summary> 590 /// SetGridControlAccessMethod,主要是了MyGridLookUpEdit用 591 /// </summary> 592 /// <param name="newControl"></param> 593 protected internal virtual void SetGridControlAccessMethod(GridControl newControl) { 594 SetGridControl(newControl); 595 } 596 597 /// <summary> 598 /// GridLookUpEdit的模糊匹配 599 /// </summary> 600 /// <param name="text"></param> 601 /// <param name="displayMember"></param> 602 /// <returns></returns> 603 protected override string OnCreateLookupDisplayFilter(string text, string displayMember) { 604 var subStringOperators = new List<CriteriaOperator>(); 605 foreach (var sString in text.Split(' ')) { 606 var columnsOperators = new List<CriteriaOperator>(); 607 608 foreach (GridColumn col in this.Columns) { 609 columnsOperators.Add(new FunctionOperator(FunctionOperatorType.Contains, new OperandProperty(col.FieldName), sString)); 610 } 611 612 subStringOperators.Add(new GroupOperator(GroupOperatorType.Or, columnsOperators)); 613 } 614 615 return new GroupOperator(GroupOperatorType.And, subStringOperators).ToString(); 616 } 617 618 /// <summary> 619 /// 模糊匹配的字符串 620 /// </summary> 621 protected virtual internal string GetExtraFilterText => base.ExtraFilterText; 622 623 #endregion 624 625 #region 重写属性 626 627 /// <summary> 628 /// 629 /// </summary> 630 /// <returns></returns> 631 protected override ColumnViewOptionsView CreateOptionsView() { 632 return new CustomGridOptionsView(); 633 } 634 635 #endregion 636 } 637 638 #endregion 639 640 #region MyGridHandler processes the mouse and keyboard. 641 642 /// <summary> 643 /// processes the mouse and keyboard. 644 /// </summary> 645 public class MyGridHandler : DevExpress.XtraGrid.Views.Grid.Handler.GridHandler { 646 /// <summary> 647 /// Constructor 648 /// </summary> 649 /// <param name="gridView"></param> 650 public MyGridHandler(GridView gridView) 651 : base(gridView) { 652 } 653 654 /// <summary> 655 /// 重写事件 OnKeyDown 656 /// </summary> 657 /// <param name="e"></param> 658 protected override void OnKeyDown(KeyEventArgs e) { 659 try { 660 base.OnKeyDown(e); 661 } catch { } 662 663 // Ctrl + C 复制单元格 664 if (e.Control & e.KeyCode == Keys.C) { 665 try { 666 Clipboard.SetDataObject(this.View.GetFocusedRowCellDisplayText(this.View.FocusedColumn)); 667 e.Handled = true; 668 } catch { } 669 } 670 } 671 } 672 673 #endregion 674 675 #region MyGridViewInfoRegistrator 676 677 /// <summary> 678 /// GridInfoRegistrator,注册MyGridView 679 /// </summary> 680 public class MyGridViewInfoRegistrator : GridInfoRegistrator { 681 protected const string MyGridViewName = "MyGridView"; 682 683 /// <summary> 684 /// Default View Name 685 /// </summary> 686 public override string ViewName => MyGridViewName; 687 688 /// <summary> 689 /// 创建GridView 690 /// </summary> 691 /// <param name="grid"></param> 692 /// <returns></returns> 693 public override BaseView CreateView(GridControl grid) { 694 // 主要为了GridLookUpEdit用 695 var view = new MyGridView(); 696 view.SetGridControlAccessMethod(grid); 697 view.Initialize(); 698 return view; 699 } 700 701 /// <summary> 702 /// CreateViewInfo 703 /// </summary> 704 /// <param name="view"></param> 705 /// <returns></returns> 706 public override BaseViewInfo CreateViewInfo(BaseView view) { 707 return new MyGridViewInfo(view as MyGridView); 708 } 709 710 /// <summary> 711 /// 创建自定义的事件 712 /// </summary> 713 /// <param name="view"></param> 714 /// <returns></returns> 715 public override BaseViewHandler CreateHandler(BaseView view) { 716 return new MyGridHandler(view as MyGridView); 717 } 718 719 /// <summary> 720 /// 创建自定义的绘画 721 /// </summary> 722 /// <param name="view"></param> 723 /// <returns></returns> 724 public override BaseViewPainter CreatePainter(BaseView view) { 725 return new MyGridPainter(view as GridView); 726 } 727 } 728 729 #endregion 730 731 #region MyGridViewInfo calculates view information for drawing a grid view on screen. 732 733 /// <summary> 734 /// calculates view information for drawing a grid view on screen. 735 /// </summary> 736 public class MyGridViewInfo : GridViewInfo { 737 /// <summary> 738 /// Constructor 739 /// </summary> 740 /// <param name="gridView"></param> 741 public MyGridViewInfo(GridView gridView) 742 : base(gridView) { } 743 } 744 745 #endregion 746 747 #region GridPainter 748 749 /// <summary> 750 /// 自定义画笔 751 /// </summary> 752 public class MyGridPainter : GridPainter { 753 /// <summary> 754 /// Constructor 755 /// </summary> 756 /// <param name="view"></param> 757 public MyGridPainter(GridView view) : base(view) { } 758 759 /// <summary> 760 /// 创建视图 761 /// </summary> 762 public virtual new MyGridView View => (MyGridView)base.View; 763 764 /// <summary> 765 /// 绘制行信息,主要为了MyGridLookUpEdit 766 /// </summary> 767 /// <param name="e"></param> 768 /// <param name="cell"></param> 769 protected override void DrawRowCell(GridViewDrawArgs e, GridCellInfo cell) { 770 cell.ViewInfo.MatchedStringUseContains = true; 771 // 匹配表达式 772 cell.ViewInfo.MatchedString = this.View.GetExtraFilterText; 773 // 单元格状态 774 cell.State = GridRowCellState.Dirty; 775 // 更新行 776 e.ViewInfo.UpdateCellAppearance(cell); 777 // Draw 778 base.DrawRowCell(e, cell); 779 } 780 } 781 782 #endregion 783 }