How to right align the text according to the font in WinForms GridControl?
Text alignment
In the WinForms GridControl,
the degree of alignment varies from font to font. You can derive your
own cell model and override the CellRenderer's OnDraw method.
In the override, the text rectangle is adjusted to appropriately align the
text. To right-align the Grid, you need to follow the steps
given:
Step 1: Create CellModel
public class MeasureStringTextBoxCellModel : GridTextBoxCellModel
{
public MeasureStringTextBoxCellModel(GridModel grid)
: base(grid)
{
}
public override GridCellRendererBase CreateRenderer(GridControlBase control)
{
return new MeasureStringTextBoxCellRenderer(control, this);
}
}Public Class MeasureStringTextBoxCellModel Inherits GridTextBoxCellModel
Public Sub New(ByVal grid As GridModel) MyBase.New(grid)
End Sub
Public Overrides Function CreateRenderer(ByVal control As GridControlBase) As GridCellRendererBase
Return New MeasureStringTextBoxCellRenderer(control, Me)
End Function
End Class Step 2: Create CellRenderer
public class MeasureStringTextBoxCellRenderer : GridTextBoxCellRenderer
{
public MeasureStringTextBoxCellRenderer(GridControlBase grid, GridCellModelBase cellModel)
: base(grid, cellModel)
{
}
protected override void OnDraw(Graphics g, Rectangle clientRectangle, int rowIndex, int colIndex, GridStyleInfo style)
{
if (Grid.CurrentCell.HasCurrentCellAt(rowIndex, colIndex) && CurrentCell.IsEditing && !Grid.PrintingMode)
{
base.OnDraw(g, clientRectangle, rowIndex, colIndex, style);
}
else
{
string displayText = style.FormattedText;
if (displayText.Length > 0)
{
Font font = style.GdipFont;
Rectangle textRectangle = RemoveMargins(clientRectangle, style);
if(style.HorizontalAlignment == GridHorizontalAlignment.Right)
{
int stringWidth = MeasureDisplayStringWidth(g, displayText, font);
stringWidth = Math.Min(stringWidth, textRectangle.Width);
textRectangle = new Rectangle(textRectangle.Right - stringWidth, textRectangle.Y, stringWidth, textRectangle.Height);
style.HorizontalAlignment = GridHorizontalAlignment.Left;
}
Color textColor = Grid.PrintingMode && Grid.Model.Properties.BlackWhite ? Color.Black : style.TextColor;
using (SolidBrush br = new SolidBrush(textColor))
{
g.DrawString(displayText, font, br, textRectangle, StringFormat.GenericTypographic);
}
}
}
}
//code from http://www.codeproject.com/cs/media/measurestring.asp
//Gets the measure of the Display string.
static public int MeasureDisplayStringWidth(Graphics graphics, string text, Font font)
{
RectangleF rect = RectangleF.Empty;
using(StringFormat format = new System.Drawing.StringFormat())
{
rect = new System.Drawing.RectangleF(0, 0, 1000, 1000);
CharacterRange[] ranges = {new System.Drawing.CharacterRange(0, text.Length)};
Region[] regions = new System.Drawing.Region[1];
format.SetMeasurableCharacterRanges(ranges);
regions = graphics.MeasureCharacterRanges(text, font, rect, format);
rect = regions[0].GetBounds(graphics);
}
return (int)(rect.Right + 1.0f);
}
}
}Public Class MeasureStringTextBoxCellRenderer Inherits GridTextBoxCellRenderer
Public Sub New(ByVal grid As GridControlBase, ByVal cellModel As GridCellModelBase)
MyBase.New(grid, cellModel)
End Sub
Protected Overrides Sub OnDraw(ByVal g As Graphics, ByVal clientRectangle As Rectangle, ByVal rowIndex As Integer, ByVal colIndex As Integer, ByVal style As GridStyleInfo)
If Grid.CurrentCell.HasCurrentCellAt(rowIndex, colIndex) AndAlso CurrentCell.IsEditing AndAlso (Not Grid.PrintingMode) Then
MyBase.OnDraw(g, clientRectangle, rowIndex, colIndex, style)
Else
Dim displayText As String = style.FormattedText
If displayText.Length > 0 Then
Dim font As Font = style.GdipFont
Dim textRectangle As Rectangle = RemoveMargins(clientRectangle, style)
If style.HorizontalAlignment = GridHorizontalAlignment.Right Then
Dim stringWidth As Integer = MeasureDisplayStringWidth(g, displayText, font)
stringWidth = Math.Min(stringWidth, textRectangle.Width)
textRectangle = New Rectangle(textRectangle.Right - stringWidth, textRectangle.Y, stringWidth, textRectangle.Height)
style.HorizontalAlignment = GridHorizontalAlignment.Left
End If
Dim textColor As Color = If(Grid.PrintingMode AndAlso Grid.Model.Properties.BlackWhite, Color.Black, style.TextColor)
Using br As New SolidBrush(textColor)
g.DrawString(displayText, font, br, textRectangle, StringFormat.GenericTypographic)
End Using
End If
End If
End Sub
'code from http://www.codeproject.com/cs/media/measurestring.asp
‘Gets the measure of the Display string.
Public Shared Function MeasureDisplayStringWidth(ByVal graphics As Graphics, ByVal text As String, ByVal font As Font) As Integer
Dim rect As RectangleF = RectangleF.Empty
Using format As StringFormat = New System.Drawing.StringFormat()
rect = New System.Drawing.RectangleF(0, 0, 1000, 1000)
Dim ranges() As CharacterRange = {New System.Drawing.CharacterRange(0, text.Length)}
Dim regions() As Region = New System.Drawing.Region(0){}
format.SetMeasurableCharacterRanges(ranges)
regions = graphics.MeasureCharacterRanges(text, font, rect, format)
rect = regions(0).GetBounds(graphics)
End Using
Return CInt(Fix(rect.Right + 1.0f))
End Function
End Class Step 3: Add CellModel to the Grid
//Sets the grid up.
GridBaseStyle baseStyle = new GridBaseStyle("rightaligned", false);
baseStyle.StyleInfo.BackColor = Color.Chocolate;
baseStyle.StyleInfo.HorizontalAlignment = GridHorizontalAlignment.Right;
this.gridControl1.BaseStylesMap.AddRange(new GridBaseStyle[]{baseStyle});
this.gridControl1[2,2].BaseStyle = "rightaligned";
this.gridControl1[2,2].Text = "date";
this.gridControl1[3,2].BaseStyle = "rightaligned";
this.gridControl1[3,2].Text = "january 1, 2004";
this.gridControl1[4,2].BaseStyle = "rightaligned";
this.gridControl1[4,2].Text = "10";
this.gridControl1.ColWidths[2] = 100;
//Sets up the code for the Antialias workaround.
this.gridControl1.Model.PrepareGraphics += new Syncfusion.Drawing.GraphicsEventHandler(gridControl1_PrepareGraphics);
//Creates the custom celltype for that workaround.
this.gridControl1.CellModels.Add("msTextBox", new MeasureStringTextBoxCellModel(this.gridControl1.Model));'Sets the grid up.
Dim baseStyle As New GridBaseStyle("rightaligned", False)
baseStyle.StyleInfo.BackColor = Color.Chocolate
baseStyle.StyleInfo.HorizontalAlignment = GridHorizontalAlignment.Right
Me.gridControl1.BaseStylesMap.AddRange(New GridBaseStyle(){baseStyle})
Me.gridControl1(2,2).BaseStyle = "rightaligned"
Me.gridControl1(2,2).Text = "date"
Me.gridControl1(3,2).BaseStyle = "rightaligned"
Me.gridControl1(3,2).Text = "january 1, 2004"
Me.gridControl1(4,2).BaseStyle = "rightaligned"
Me.gridControl1(4,2).Text = "10"
Me.gridControl1.ColWidths(2) = 100
'Sets code up for the Antialias workaround.
AddHandler gridControl1.Model.PrepareGraphics, AddressOf gridControl1_PrepareGraphics
'Creates the custom celltype for that workaround.
Me.gridControl1.CellModels.Add("msTextBox", New MeasureStringTextBoxCellModel(Me.gridControl1.Model))Step 4: Set up for Antialias.
private void gridControl1_PrepareGraphics(object sender, Syncfusion.Drawing.GraphicsEventArgs e)
{
if(antiAliasWorkAround)
{
//e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
}
}Private Sub gridControl1_PrepareGraphics(ByVal sender As Object, ByVal e As Syncfusion.Drawing.GraphicsEventArgs)
If antiAliasWorkAround Then
'e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias
End If
End Sub Step 5: Events to perform the desired operation
//Default GDI+ drawing is performed in the radiobutton click.
this.radioButton1.Click += new System.EventHandler(this.radioButton1_Click);
private void radioButton1_Click(object sender, System.EventArgs e)
{
this.radioButton1.Checked = true;
this.radioButton2.Checked = false;
this.radioButton3.Checked = false;
antiAliasWorkAround = false;
this.gridControl1.BaseStylesMap["rightaligned"].StyleInfo.CellType = "TextBox";
this.gridControl1.Refresh();
}
//Antialias work around is performed in the radiobutton click.
this.radioButton2.Click += new System.EventHandler(this.radioButton2_Click);
private void radioButton2_Click(object sender, System.EventArgs e)
{
this.radioButton1.Checked = false;
this.radioButton2.Checked = true;
this.radioButton3.Checked = false;
antiAliasWorkAround = true;
this.gridControl1.BaseStylesMap["rightaligned"].StyleInfo.CellType = "TextBox";
this.gridControl1.Refresh();
}
//Custom celltype operation is performed in this radiobutton click.
this.radioButton3.Click += new System.EventHandler(this.radioButton3_Click);
private void radioButton3_Click(object sender, System.EventArgs e)
{
this.radioButton1.Checked = false;
this.radioButton2.Checked = false;
this.radioButton3.Checked = true;
antiAliasWorkAround = false;
this.gridControl1.BaseStylesMap["rightaligned"].StyleInfo.CellType = "msTextBox";
this.gridControl1.Refresh();
}'Default GDI+ drawing is performed in the radiobutton click.
AddHandler Me.radioButton1.Click, AddressOf Me.radioButton1_Click
Private Sub radioButton1_Click(sender As Object, e As System.EventArgs)
Me.radioButton1.Checked = True
Me.radioButton2.Checked = False
Me.radioButton3.Checked = False
antiAliasWorkAround = False
Me.gridControl1.BaseStylesMap("rightaligned").StyleInfo.CellType = "TextBox"
Me.gridControl1.Refresh()
End Sub
'Antialias work around is performed in the radiobutton click.
AddHandler Me.radioButton2.Click, AddressOf Me.radioButton2_Click
Private Sub radioButton2_Click(sender As Object, e As System.EventArgs)
Me.radioButton1.Checked = False
Me.radioButton2.Checked = True
Me.radioButton3.Checked = False
antiAliasWorkAround = True
Me.gridControl1.BaseStylesMap("rightaligned").StyleInfo.CellType = "TextBox"
Me.gridControl1.Refresh()
End Sub
'Custom celltype operation is performed in this radiobutton click.
AddHandler Me.radioButton3.Click, AddressOf Me.radioButton3_Click
Private Sub radioButton3_Click(sender As Object, e As System.EventArgs)
Me.radioButton1.Checked = False
Me.radioButton2.Checked = False
Me.radioButton3.Checked = True
antiAliasWorkAround = False
Me.gridControl1.BaseStylesMap("rightaligned").StyleInfo.CellType = "msTextBox"
Me.gridControl1.Refresh()
End SubThe following screenshot displays the Grid with right alignment.

Figure 1: Right Text Align for different texts
Samples: