DevExpress WPF Grid Custom Control - CodeProject

:

Introduction

This will help in writing a common code for events like PreviewKeyUp, KeyUp and setting other properties for TableView.

Background

In WPF, there can be a case where there are shortcut keys provided to perform functions like copy a row, copy a column, enter a new row, etc. In such a case, it will be better if we write the code at one common place.

Using the Code

This can help you in creating a custom gridcontrol with a custom tableview which can be used in the XAML.

First, let us start with GridControl.

The gridcontrol class will look like follows:

public class CustomGridControl : GridControl                                                            
{                                                                                                          
     public CustomGridControl()
     {
        this.PreviewKeyUp += CustomGridControl_PreviewKeyUp;
        this.KeyUp += CustomGridControl_KeyUp;
        this.CreateDefaultView();
     }

     void CustomGridControl_KeyUp(object sender, KeyEventArgs e)
     {
        GridControl gridControl = sender as GridControl; 
        TableView focusedView = (TableView)gridControl.View.FocusedView; 
        if (focusedView.IsEditing) return;
        if (e.Key == Key.Enter && gridControl.CurrentItem == 
		gridControl.DataController.GetAllFilteredAndSortedRows().OfType<object>().Last())   
          {                
                focusedView.FocusedRowHandle = GridControl.NewItemRowHandle; 
                gridControl.CurrentColumn = gridControl.Columns[0];        
                focusedView.ShowEditor();         
           }
      }

      private void CustomGridControl_PreviewKeyUp(object sender, KeyEventArgs keyEventArgs)  
      {      
          if (keyEventArgs.Key == Key.Escape)   
          {        
              this.View.CancelRowEdit();  
           }   
       }     
 
       protected override DataViewBase CreateDefaultView() 
       {            return new TableViewEx();        }    
}

Here in CreateDefaultView(), TableViewEx is the name of the custom tableview class, which is as follows:

public class TableViewEx : TableView
{
      public TableViewEx()
      {
           //Set table view properties here. 
           //These can also be set in Resource Dictionary of your application.
           ShowGroupPanel = false;
           ShowTotalSummary = true;
           AllowChangeColumnParent = true;
           AllowChangeBandParent = true;
           ShowAutoFilterRow = true;
           ShowGroupPanel = false;
           AutoWidth = true;
           PreviewKeyUp += OnPreviewKeyUp;
           ShowSearchPanelMode = ShowSearchPanelMode.Always;
       }

       private void OnPreviewKeyUp(object sender, KeyEventArgs keyEventArgs)
       {
           TableView TableView = sender as TableView;
           GridControl gridControl = TableView.Grid;
           IList source = gridControl.ItemsSource as IList;
           int selectedRowIndex = TableView.FocusedRowHandle;
           switch (keyEventArgs.Key)
           {
                case Key.F6: //(This will copy the above columns value to the current 
                             //focused column on pressing F6)
                object focusedAbove = gridControl.GetCellValue
                	(selectedRowIndex - 1, TableView.FocusedColumn.FieldName);
                object focused = gridControl.GetCellValue
                	(selectedRowIndex, TableView.FocusedColumn.FieldName);
                gridControl.SetCellValue(gridControl.GetRowListIndex(selectedRowIndex), 
                	TableView.FocusedColumn.FieldName, focusedAbove);
                gridControl.RefreshRow(selectedRowIndex);
                gridControl.View.MoveNextCell();
                gridControl.View.MovePrevCell();
                gridControl.View.UpdateLayout();
                break;

                case Key.F7: //(This will copy the above row to the focused row)
                int pasteIndex = gridControl.GetListIndexByRowHandle(selectedRowIndex);
                int copyIndex = pasteIndex - 1;
                source[pasteIndex] = source[copyIndex];
                gridControl.RefreshRow(pasteIndex);
                gridControl.View.MoveNextCell();
                gridControl.View.MovePrevCell();
                gridControl.View.UpdateLayout();
                break;
           }
     }
}

Calling in XAML:

<local:CustomGridControl ItemsSource="{Binding list}" >
     <local:CustomGridControl.Columns>
                <dxg:GridColumn FieldName="Id"/>  
                <dxg:GridColumn FieldName="Text" />
                <dxg:GridColumn FieldName="Number" />
     </local:CustomGridControl.Columns>
     <local:CustomGridControl.View>
              <local:TableViewEx></local:TableViewEx>
     </local:CustomGridControl.View>
</local:CustomGridControl>

Here, we can also override the events. We just have to simply write them in xaml.cs and the custom event will not fire. In case we need the common code to execute, we do not need to write the event in xaml.cs.

Points of Interest

By writing this, we just have to call this in our XAML and the grid behaviour will support the common functionalities. This will also save time and repetitive code on each screen.