Category / Section
How to right align the text according to the font in WinForms GridControl?
4 mins read
Text alignment
In the Grid, the degree of the 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
C#
public class MeasureStringTextBoxCellModel : GridTextBoxCellModel { public MeasureStringTextBoxCellModel(GridModel grid) : base(grid) { } public override GridCellRendererBase CreateRenderer(GridControlBase control) { return new MeasureStringTextBoxCellRenderer(control, this); } }
VB
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
C#
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); } } }
VB
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
C#
//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));
VB
'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: Setup for Antialias.
C#
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; } }
VB
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 desire operation
C#
//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(); }
VB
'Default GDI+ drawing is performed in the radiobutton click. Private Me.radioButton1.Click += New System.EventHandler(AddressOf Me.radioButton1_Click) Private Sub radioButton1_Click(ByVal sender As Object, ByVal 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. Private Me.radioButton2.Click += New System.EventHandler(AddressOf Me.radioButton2_Click) Private Sub radioButton2_Click(ByVal sender As Object, ByVal 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. Private Me.radioButton3.Click += New System.EventHandler(AddressOf Me.radioButton3_Click) Private Sub radioButton3_Click(ByVal sender As Object, ByVal 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 Sub
The following screenshot displays the Grid with right alignment.
Figure 1: Right Text Align for different texts
Samples: