1

I'm currently making an app in C# which make use of LinkLabels. I have a function that add a new link for each element in a certain array. However, it happens that the array have more than 32 links, and when that happens, I receive an OverflowException:

System.OverflowException: Overflow error. at System.Drawing.StringFormat.SetMeasurableCharacterRanges(CharacterRange[] ranges) at System.Windows.Forms.LinkLabel.CreateStringFormat() at System.Windows.Forms.LinkLabel.EnsureRun(Graphics g) at System.Windows.Forms.LinkLabel.OnPaint(PaintEventArgs e) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.Label.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Is there a way to override the SetMeasurableCharacterRanges function. So that it doesn't throw that error when having more than 32 character ranges? Here is a sample of my code:

int LengthCounter = 0;
llbl.Links.Clear();
string[] props = AList.ToArray();

llbl.Text = string.Join(", ", props);
foreach (var Prop in props)
{
    llbl.Links.Add(LengthCounter, Prop.Length, string.Format("{0}{1}", prefix, Sanitize(Prop)));
    LengthCounter += Prop.Length + 2;
}
Kai Thoma
  • 512
  • 4
  • 14
Binyuan Sun
  • 146
  • 1
  • 9

1 Answers1

2

SetMeasurableCharacterRanges is implemented like this:

/// <summary>Specifies an array of <see cref="T:System.Drawing.CharacterRange" /> structures that represent the ranges of characters measured by a call to the <see cref="M:System.Drawing.Graphics.MeasureCharacterRanges(System.String,System.Drawing.Font,System.Drawing.RectangleF,System.Drawing.StringFormat)" /> method.</summary>
/// <param name="ranges">An array of <see cref="T:System.Drawing.CharacterRange" /> structures that specifies the ranges of characters measured by a call to the <see cref="M:System.Drawing.Graphics.MeasureCharacterRanges(System.String,System.Drawing.Font,System.Drawing.RectangleF,System.Drawing.StringFormat)" /> method.</param>
/// <exception cref="T:System.OverflowException">More than 32 character ranges are set.</exception>
public void SetMeasurableCharacterRanges( CharacterRange[] ranges )
{
    int num = SafeNativeMethods.Gdip.GdipSetStringFormatMeasurableCharacterRanges( new HandleRef( this, this.nativeFormat ), ranges.Length, ranges );
    if( num != 0 )
        throw SafeNativeMethods.Gdip.StatusException( num );
}

The class StringFormat is sealed and the method SetMeasurableCharacterRanges is not virtual, so you cannot override it. And internally it does an API call to gdiplus.dll.

What you can try is to inherit a custom LinkLabel from LinkLabel and override OnPaint()-method and do drawing complety by your own. (Things would be easier if method CreateStringFormat() was not internal.)

Or you just use multiple LinkLabels on a FlowLayoutPanel with only one link per label:

for( int i = 0; i < AList.Count; i++ )
{
    string prop = AList[i];
    LinkLabel llbl = new LinkLabel()
    {
        AutoSize = true,
        Margin = new Padding( 0 ),
        Name = "llbl" + i,
        Text = prop + ", "
    };
    llbl.Links.Add( 0, prop.Length, string.Format( "{0}{1}", prefix, Sanitize( prop ) ) );

    flowLayoutPanel1.Controls.Add( llbl );
}
Kai Thoma
  • 512
  • 4
  • 14