Xceed Grid for WinForms v4.3 Documentation
CellViewerManagers

Welcome to Xceed Grid for WinForms v4.3 > Basic Concepts > CellEditorManagers and CellViewerManagers > CellViewerManagers

The CellViewerManager class allows for any control to be used as a viewer to display the content of a cell as well as allows custom painting of a cell's background and foreground. 

Custom CellViewerManagers can be created by deriving from the CellViewerManager class, by handling various events of the CellViewerManager class, or by wrapping a control within an instance of the CellViewerManager class. By default, Xceed Grid for WinForms offers the following predefined CellViewerManagers: the CheckBoxViewer which can be used to view the content of cells which have a boolean value, the ImageViewer which can be used to display an image in a cell, the TextViewer which can be used to view the content of cells as text, the ComboBoxViewer which can be used to display the content of cells which have an ID/Value mapping, the DateViewer which can be used to view the content of cells which have a DateTime datatype, and the NumericViewer which can be used to view the content of cells which have a numeric datatype. 

The following table provides a list of the available CellViewerManagers as well as the datatype for which they are created by default. 

CellViewerManagers Datatype Description
CellViewerManager (none) Allows for any control to be used as a viewer to display the content of a cell as well as allows custom painting of a cell's background and foreground.
CheckBoxViewer Boolean Represents a viewer that is used to view the content of cells which have a boolean value.
ComboBoxViewer (none) Represents a viewer that can be used to display the content of cells which have an ID/Value mapping.
DateViewer DateTime Represents a viewer that can be used to view the content of cells which have a DateTime datatype.
ImageViewer Image Represents a viewer that is used to display an image in a cell.
NumericViewer Numeric Represents a cell viewer that can be used to view the content of cells which have a numeric data type.
TextViewer (none) Represents a viewer that is used to view the content of cells as text.

Using CellViewerManagers

The default CellViewerManagers that are created can be removed or replaced with one of the above mentioned predefined CellViewerManagers or with a custom CellViewerManager by setting the CellViewerManager property of either or a column or a specific cell.

VB.NET Copy Code
GridControl1.Columns( "Phone" ).CellViewerManager = New TextViewer( "( ### ) ###-####" )                   
C# Copy Code
gridControl1.Columns[ "Phone" ].CellViewerManager = new TextViewer( "( ### ) ###-####" );                   

Custom CellViewerManagers can be created by either wrapping a control in a CellViewerManager, by using a CellViewerManager to provide custom painting for a cell's background and/or foreground, or by deriving from the CellViewerManager (TrackBarViewer | BooleanImageTextViewer). 

The GridControl class exposes the CellViewerManagerMapping property which contain a list of the CellViewerManagers which are created by default for specified datatypes. Values contained in this collection can be modified, added, or removed to change the CellViewerManager which is created by default for all columns of the specified datatype.

Wrapping a control in a CellViewerManager

Controls can be wrapped in a CellViewerManager by either deriving from the CellViewerManager class, or by using the constructor that accepts a control and a string as a parameter. This section only deals with wrapping a control through the appropriate constructor. For information on how to derive from the CellViewerManager, refer to the CellViewerManager and CellEditorManager extensions topic. 

When wrapping a control in a CellViewerManager, the control used to view a cell's content as well as the property used to set the control's value must be specified. Both of these values must be passed at the construction of the CellViewerManager and can be retrieved (not set) through the Control and PropertyName properties. 

The appearance of the control that is used to view a cell's content can either be set directly on the instance of the control that is being passed to the CellViewerManager constructor, or it can be done in the SettingControlAppearance event. If modifications need to be made to the control according to the cell's content, then its appearance should be set in the SettingControlAppearance event. If the appearance of the control is the same regardless of the cell's content, then its appearance should be defined directly on the instance of the control.

VB.NET
Copy Code
Dim bar As New TrackBar()
Dim manager As New CellViewerManager(bar, "Value")

' Because these variables affect all instances, there is no need for this to be done
' in the SettingControlAppearance event. If these values were to be applied differently
' depending on a cell value, then they should be done in the SettingControlAppearance event.
bar.Minimum = minValue
bar.Maximum = maxValue
bar.TickStyle = TickStyle.None
bar.AutoSize = False

gridControl1.Columns( "Freight" ).CellViewerManager = manager 
C#
Copy Code
TrackBar bar = new TrackBar();
CellViewerManager manager = new CellViewerManager( bar, "Value" );

// Because these variables affect all instances, there is no need for this to be done
// in the SettingControlAppearance event. If these values were to be applied differently
// depending on a cell value, then they should be done in the SettingControlAppearance event.
bar.Minimum = minValue;
bar.Maximum = maxValue;
bar.TickStyle = TickStyle.None;
bar.AutoSize = false;

gridControl1.Columns[ "Freight" ].CellViewerManager = manager;

By default, the value will be assigned to the wrapped control via the property name that was specified when the CellViewerManager was constructed; however, there are some cases where modifications need to be made before the value can be assigned to the wrapped control. These modifications can be done via the SettingControlValue event. For example, to continue the above example, we will prevent null values from being assigned to the underlying control:

VB.NET
Copy Code
' Subscribe to the SettingControlValue event to prevent null values from being
' assigned to the underlying control.
AddHandler manager.SettingControlValue, AddressOf Me.manager_SettingControlValue

Private Sub manager_SettingControlValue( ByVal sender As Object, ByVal e As CellViewerEventArgs )
  If( ( Not e.Cell.Value Is Nothing ) And _
      ( Not e.Cell.Value Is DBNull.Value ) And _
      ( Not e.Cell.Value Is e.Cell.NullValue ) ) Then     
    CType( e.Control, TrackBar ).Value = CInt( Convert.ChangeType( e.Cell.Value, GetType( Integer ) ) )   
  Else     
    CType( e.Control, TrackBar ).Value = 0   
  End If
End Sub
C#
Copy Code
// Subscribe to the SettingControlValue event to prevent null values from
// being assigned to the underlying control.
manager.SettingControlValue += new CellViewerEventHandler( manager_SettingControlValue );

private void manager_SettingControlValue( object sender, CellViewerEventArgs e )
{
  If( ( e.Cell.Value != null) &&
      ( e.Cell.Value != DBNull.Value ) &&
      ( e.Cell.Value != e.Cell.NullValue ) )
  {    
    ( ( TrackBar )e.Control ).Value = ( int )Convert.ChangeType( e.Cell.Value,
                                     typeof( Integer ) ) )   
  {
  else      
  {
     ( TrackBar )e.Control ).Value = 0   
  }
}

Custom painting via a CellViewerManager

A CellViewerManager, in addition to displaying a cell's content through a wrapped control, allows for a cell's value to be displayed through custom painting.

This section will deal with custom painting via the GetImage and GetText methods as well as through the Paint event. For information on how to derive from the CellViewerManager class to provide custom painting, refer to the CellViewerManager and CellEditorManager extensions topic. 

In its simplest form, a CellViewerManager paints an image or text (or both) representing the underlying cell's value. The image that is displayed can be retrieved through the GetImage method and specified via the QueryImage event, while the text can be retrieved through the GetText method and specified via the QueryText event. 

By default, a CellViewerManager will not display an image even if one is specified during the QueryImage event. In order for an image to be displayed, the ImageArea property must be set to either Xceed.Grid.ImageArea.Left, Right, or AllContent. The size of the image, if one is displayed, can be determined via the ImageSize property while its preservation of its aspect ratio is determined through the PreserveImageAspectRatio property. The padding surrounding the image and the text can be specified via the ImagePadding and TextPadding properties respectively. 

For example, we will create a custom CellViewerManager that displays the boolean content of a cell as an image and as a "Processed/Delayed" text:

VB.NET
Copy Code
Dim manager As New CellViewerManager()

AddHandler manager.QueryImage, AddressOf Me.manager_QueryImage
AddHandler manager.QueryText, AddressOf Me.manager_QueryText

manager.ImageArea = Xceed.Grid.ImageArea.Left
manager.ImagePadding = New Xceed.UI.Margins( 2 )
manager.TextPadding = New Xceed.UI.Margins( 2 )

gridControl1.Columns( "Order_Processed" ).CellViewerManager = manager

Private Sub manager_QueryText( ByVal sender As Object, ByVal e As QueryViewerTextEventArgs )
  e.Text = IIf( CBool( Convert.ChangeType( e.Value, GetType( Boolean ) ) ), "Processed", "Delayed" )
End Sub

Private Sub manager_QueryImage( ByVal sender As Object, ByVal e As QueryViewerImageEventArgs )
   e.Image = IIf( CBool( Convert.ChangeType( e.Value, GetType( Boolean ) ) ), _
                    New Bitmap( "processed.gif" ), New Bitmap( "delayed.gif" ) )
End Sub
C#
Copy Code
CellViewerManager manager = new CellViewerManager();

manager.QueryImage += new QueryViewerImageEventHandler( manager_QueryImage );
manager.QueryText += new QueryViewerTextEventHandler( manager_QueryText );

manager.ImageArea = Xceed.Grid.ImageArea.Left;
manager.ImagePadding = new Xceed.UI.Margins( 2 );
manager.TextPadding = new Xceed.UI.Margins( 2 );

gridControl1.Columns[ "Order_Processed" ].CellViewerManager = manager;

void manager_QueryText( object sender, QueryViewerTextEventArgs e )
{
   e.Text = ( bool )Convert.ChangeType( e.Value, typeof( bool ) ) ? "Processed" : "Delayed";
}
void manager_QueryImage( object sender, QueryViewerImageEventArgs e )
{
   e.Image = ( bool )Convert.ChangeType( e.Value, typeof( bool ) ) ? new Bitmap  ( "processed.gif" ) : new Bitmap( "delayed.gif" ) );
}
In some cases, it might be more desirable to override the cell's foreground. In this case, the CellViewerManager's Paint event can be handle to custom paint the underlying cell's value. For example, if the cell contains an integer column containing representing a sales rank, than value could be replaced with an equivalent number of images.
VB.NET
Copy Code
Dim manager As New CellViewerManager()

AddHandler manager.Paint, AddressOf Me.manager_Paint

gridControl1.Columns( "Rank" ).CellViewerManager = manager

Private Sub manager_Paint( ByVal sender As Object, ByVal e As CellViewerPaintEventArgs )Dim brush As New System.Drawing.SolidBrush( e.Cell.BackColor )

e.Graphics.FillRectangle( brush, e.DisplayRectangle )
   brush.Dispose()
   Dim image As Bitmap = New Bitmap( "star.gif" )
   Dim quantity As Single = CSng( Convert.ChangeType( e.Cell.Value, GetType( Single ) ) )w
   Dim x As Integer = e.DisplayRectangle.X
   Dim y As Integer = e.DisplayRectangle.Y + ( ( e.DisplayRectangle.Height - image.Height) / 2 )
   Dim i As Integer

   For i = 1 To quantity Step 1
      e.Graphics.DrawImage( image, x, y )
      x += image.Width
   Next i
End Sub
C#
Copy Code
CellViewerManager manager = new CellViewerManager();

manager.Paint += new CellViewerPaintEventHandler( manager_Paint );

gridControl1.Columns[ "Rank" ].CellViewerManager = manager;

void manager_Paint( object sender, CellViewerPaintEventArgs e )
{
   using( System.Drawing.Brush brush = new System.Drawing.SolidBrush( e.Cell.BackColor ) )
   {
      e.Graphics.FillRectangle( brush, e.DisplayRectangle );
   }
   Bitmap image = new Bitmap( "star.gif" );

   float quantity = ( float )Convert.ChangeType( e.Cell.Value, typeof( float ) );
   int x = e.DisplayRectangle.X;
   int y = e.DisplayRectangle.Y + ( ( e.DisplayRectangle.Height - image.Height ) / 2 );
   for( int i = 1; i <= quantity; i++ )
   {
      e.Graphics.DrawImage( image, x, y );
      x += image.Width;
   }
}
A complete list of the public properties, methods, and events that are available on the CellViewerManager class is available here.

CellViewerManagers and reporting

When generating a report using the reporting capabilities of Xceed Grid for WinForms, CellViewerManagers will only be reproduced in the report if the GetImage and/or GetText methods return the image or text that is to be displayed (GetImageCore and/or GetTextCore have been overridden). In the case where the GetImageCore and/or GetTextCore methods have not been overridden to return the desired image and/or text, the string representation of the underlying cell's content will be displayed in the report.