Click here to Skip to main content
11,644,731 members (67,514 online)
Click here to Skip to main content

Formatting the Datarow based on a single cell value and Custom Table Styles.

, 28 Apr 2003 105.3K 1.8K 24
Rate this:
Please Sign up or sign in to vote.
An article that demonstrates row formatting and adding custom styles to the designer.

Sample Image - article1.jpg

Introduction

In this article I want to show you how to change the format of a single DataRow in the grid, based on the value of a single cell in that row.

Also, I will attempt to explain the process of adding custom styles to the Styles collection of your Datagrid collection editor, so that you can use them in the DataGrid at design time.

You can look at http://www.syncfusion.com/FAQ/WinForms/FAQ_c44c.asp#q1020q for more information on this topic.

Using the code

To control the formatting of a single row, based on the value of a cell, you have to do the following:

  1. Derive from the DataGridTextBoxColumn.
    public class FormattedTextBoxColumn : DataGridTextBoxColumn 
    { 
        public CellPaint _handle ; 
        public CellPaint PaintHandle 
        { 
            get 
            { 
                return _handle ; 
            } 
            set 
            { 
                _handle = value; 
            } 
        } 
        ...; 
        ...;
    }
    
    
  2. Override the 4 paint methods of the DataGridTextBox column.
    protected override void Paint(Graphics g,Rectangle Bounds,
                                  CurrencyManager Source,int RowNum,
                                  Brush BackBrush ,Brush ForeBrush ,
                                  bool AlignToRight)
    {
       Object data = ( Object ) GetColumnValueAtRow(Source, RowNum);    
       String strData ; 
       strData = data.ToString() ; 
    
       FormatEventArgs e = new FormatEventArgs(RowNum) ;
     
       if( _handle != null) 
        _handle(new object(),ref e) ; 
            
       g.FillRectangle(e.BackBrush, Bounds.X, 
            Bounds.Y, Bounds.Width, Bounds.Height);
                
       FontStyle fs = FontStyle.Regular ; 
       if( e.strikeThrough == true ) 
       { 
         fs = FontStyle.Strikeout ; 
       }
       System.Drawing.Font font = new 
               Font(System.Drawing.FontFamily.GenericSansSerif, 
               (float)8.25 ,fs);
       g.DrawString( strData ,font ,Brushes.Green ,
               Bounds.X ,Bounds.Y );
    
    }
  3. Define a delegate, to be called from the paint functions ( The ones you override )
    public delegate void CellPaint(object o, ref FormatEventArgs e);
  4. Define a class, which derives from EventArgs, call this FormatEventArgs, and which will be used to pass information back to the delegate.
    public class FormatEventArgs : EventArgs  { 
     ... ; 
     ... ; 
    }

To add the custom style to the designer, you need to:

  1. Create a custom Datagrid, which derives from the DataGrid ( user defined control )
    public class CustomDataGrid : DataGrid { 
      ....
    }
    1. Hide the data member, GridTableStylesCollection of the DataGrid like this:
      [Editor(typeof(CustomTableStylesCollectionEditor), 
                    typeof(UITypeEditor))]
      public new GridTableStylesCollection TableStyles
      {
         get{return base.TableStyles;}
      }

      This is the data member which returns the Table Style collection in your designer. Hide it, so that you can return your own type.

    2. Create an internal class, which derives from the CollectionEditor, and override the function CreateNewItemTypes, which will now return your custom styles.
      private class CustomTableStylesCollectionEditor : 
                                                CollectionEditor
      {
        public CustomTableStylesCollectionEditor
                             (Type type):base(type)
        {
        }
              
        //Over ride the function which will return 
        //the STYLES collection 
      
        protected override System.Type[] CreateNewItemTypes()
        {
          // refer to POINT 2
          return new Type[] {typeof(CustomStylesCollection)}; 
        } 
      }
  2. Create a custom DataGridTableStyle, which is derived from the DataGridTableStyle.
    public class CustomStylesCollection : DataGridTableStyle
    {
        ... ; 
        ... ;
    }
    1. Now, hide the data member GridColumnStylesCollection, this member shows the default ColumnStyles available at design time.
      Editor(typeof(CustomColumnStylesCollectionEditor), 
                       typeof(UITypeEditor))]
      public new GridColumnStylesCollection GridColumnStyles
      {
        get {return base.GridColumnStyles;}
      }

      and,

      protected override DataGridColumnStyle 
            CreateGridColumn(PropertyDescriptor prop, bool isDefault)
      {
          return base.CreateGridColumn(prop, isDefault);
      }
    2. Create an internal class which derives from the CollectionEditor, and override the function CreateNewItemTypes, which will now return your custom styles.
      private class CustomColumnStylesCollectionEditor : 
                                      CollectionEditor
      {
        public CustomColumnStylesCollectionEditor(Type type) : 
                                           base(type)
        {
        }
      
        protected override System.Type[] CreateNewItemTypes()
        {
         return new Type[] 
         {    
           typeof(FormattedTextBoxColumn), // Your Custom Style 
           typeof(DataGridTextBoxColumn),  // Default Style
           typeof(DataGridBoolColumn)      // Default Style
         }; 
        } 
      }

Once you build the project, the CustomDataGrid, should be available in your Toolbox.

In your Form application, drop this CustomDataGrid. Then use the designer to add column styles to the DataGrid.

I attempted to expose the PaintHandler, in the properties box, but for some reason, it won't let me hook the delegate there.

If some one has any ideas to how I could do it, please let me know.

For now, manually hook the delegate like this:

formattedTextBoxColumn1.PaintHandle += new CellPaint(PaintHandler) ;

And, define the function PaintHandler, which will allow customized handling of your formats.

public void PaintHandler( object o, ref FormatEventArgs e) 
{ 
  try 
  { 
    FormatEventArgs E = (FormatEventArgs) e ; 
    int rowNum = E.RowNum ; 
        DataRow dr = ds.Tables["table"].Rows[rowNum] ; 
                 
    if( dr[0].ToString() == "X" || dr[0].ToString() == "x") 
    {
       E.BackBrush = Brushes.Beige; 
       E.strikeThrough = true ; 
    }
    else 
    {
      E.BackBrush = Brushes.White ; 
    }
                
                
  }
  catch( System.SystemException ) 
  { 
  } 
}

You would need to declare all the column styles for the DataGrid of type FormattedTextBoxColumn, and hook each style to the function.

I hope this helps.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Sameer Khan
Architect
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
Generalworks great Pin
strother26-Feb-09 10:38
memberstrother26-Feb-09 10:38 
Questionoriginal code? Pin
coolest_dude18-Apr-06 9:38
membercoolest_dude18-Apr-06 9:38 
GeneralCustomDataGrid not available in Toolbox Pin
daniel_at_mcgarry.com3-Jan-06 10:59
memberdaniel_at_mcgarry.com3-Jan-06 10:59 
GeneralMaster - Detail - no default key inserted Pin
ChristianL200413-Jan-05 1:26
memberChristianL200413-Jan-05 1:26 
QuestionSorry to be dumb but how do I use this? Pin
skintstudent22-Apr-04 5:07
memberskintstudent22-Apr-04 5:07 
AnswerRe: Sorry to be dumb but how do I use this? Pin
Sameer Khan22-Apr-04 11:36
memberSameer Khan22-Apr-04 11:36 
GeneralRe: Sorry to be dumb but how do I use this? Pin
skintstudent28-Apr-04 3:21
memberskintstudent28-Apr-04 3:21 
GeneralRe: Sorry to be dumb but how do I use this? Pin
skintstudent28-Apr-04 22:28
memberskintstudent28-Apr-04 22:28 
QuestionHow to change column caption font in datagrid Pin
Anonymous26-Mar-04 9:27
sussAnonymous26-Mar-04 9:27 
GeneralSelecting complete row Pin
Joerg Eichhorn20-Jan-04 6:52
memberJoerg Eichhorn20-Jan-04 6:52 
GeneralRe: Selecting complete row Pin
Sameer Khan20-Jan-04 14:33
memberSameer Khan20-Jan-04 14:33 
GeneralRe: Selecting complete row Pin
Joerg Eichhorn21-Jan-04 0:33
memberJoerg Eichhorn21-Jan-04 0:33 
GeneralRe: Selecting complete row Pin
student_rhr13-Jan-06 7:19
memberstudent_rhr13-Jan-06 7:19 
GeneralUsing this grid and colors in vb Pin
poojamin18-Jul-03 11:49
memberpoojamin18-Jul-03 11:49 
GeneralRe: Using this grid and colors in vb Pin
Sameer Khan21-Jul-03 19:37
memberSameer Khan21-Jul-03 19:37 
GeneralRe: Using this grid and colors in vb Pin
poojamin22-Jul-03 13:41
memberpoojamin22-Jul-03 13:41 
GeneralFormatting incorrect when columns are sorted Pin
M.Lansdaal30-Apr-03 9:52
memberM.Lansdaal30-Apr-03 9:52 
GeneralRe: Formatting incorrect when columns are sorted Pin
Sameer Khan30-Apr-03 12:34
memberSameer Khan30-Apr-03 12:34 
GeneralRe: Formatting incorrect when columns are sorted Pin
M.Lansdaal11-Aug-03 7:14
memberM.Lansdaal11-Aug-03 7:14 
Sameer - Sorry for not responding earlier. Thanks for the suggestion. The mapping using the datarowview in the paint handler does solve the indexing problem when the view is sorted. You do have to make sure that the datagrid source is a dataview and not a datatable (my first mistake). Also, instead of caching the dataview (mCurrView), I did the following:


DataGrid dg = this.DataGridTableStyle.DataGrid;
System.Windows.Forms.Form usingForm = dg.FindForm();

//Highlight the entire row or just a cell?
if( ((PassFailDataGrid)dg).HighlightEntireRow ) //My custom property
{
//Get the actual row that the cell being painted belongs to. This is complicated due
// to the fact that the user can click on the column header and change the row
// indexes
CurrencyManager cm = (CurrencyManager)usingForm.BindingContext[dg.DataSource, dg.DataMember];
DataView dv = (DataView)cm.List;
DataRowView drv = dv[rowNum];
DataRow dr = drv.Row;

//Find the column index that contains the status information
int statusColumn = dr.Table.Columns[ ((PassFailDataGrid)dg).StatusColumnName ].Ordinal;

//Get the status cell out of the row
statusCell = dr[ statusColumn ];
}
else
{
//Get the cell direct
statusCell = this.GetColumnValueAtRow(source, rowNum);
}

GeneralRe: Formatting incorrect when columns are sorted Pin
Sameer Khan31-Jul-03 11:40
memberSameer Khan31-Jul-03 11:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150731.1 | Last Updated 29 Apr 2003
Article Copyright 2003 by Sameer Khan
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid