LinkLabel 中的链接超过 32 个?

More than 32 links in LinkLabel?

我目前正在使用 LinkLabels 用 C# 开发一个应用程序。我有一个函数可以为特定数组中的每个元素添加一个新的 link 。但是,碰巧数组有超过 32 links,当这种情况发生时,我收到一个 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)

有没有办法覆盖 SetMeasurableCharacterRanges 函数。以便在超过 32 个字符范围时不会抛出该错误? 这是我的代码示例:

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;
}

SetMeasurableCharacterRanges是这样实现的:

/// <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 );
}

class StringFormat 是密封的,方法 SetMeasurableCharacterRanges 不是虚拟的,因此您 无法覆盖 它。在内部它对 gdiplus.dll.

进行 API 调用

您可以尝试从 LinkLabel 继承 自定义 LinkLabel 并覆盖 OnPaint() 方法,然后自己完成绘图。 (如果方法 CreateStringFormat() 不是内部方法,事情会更容易。)

或者您只是在 FlowLayoutPanel 上使用 多个 LinkLabels,每个标签只有一个 link:

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 );
}