LinkLabel precisando de mais espaço do que TextRenderer.MeasureText diz
-
11-09-2019 - |
Pergunta
Se eu der TextRenderer.MeasureText algum texto para medir e largura de usá-lo voltará a altura necessária para exibir o texto.
private static int CalculateHeight(string text, Font font, int width)
{
Size size = TextRenderer.MeasureText(text, font, new Size(width, Int32.MaxValue), TextFormatFlags.NoClipping | TextFormatFlags.WordBreak);
return size.Height;
}
Se eu der esse texto, largura e altura para um LinkLabel ele iria mostrar o texto na largura e altura fornecidos com nada cortado.
No entanto, se eu colocar um link para a coleção LinkLabel.Links, o LinkLabel vai desenhar o texto com o que parece ser um pouco mais espaçamento entre os personagens e, por vezes, isso fará com que o fim do texto a ser cortada. Existe uma maneira de evitar isso? Eu tentei adicionar preenchimento quando há um link, mas não há nenhuma maneira confiável para saber exatamente quanto mais espaço será necessário. Existem outras maneiras de fazer isso?
Solução
Você deve usar Control.GetPreferredSize método para calcular a largura ou altura necessária para o controle (LinkLabel no seu caso). Você não deve usar MeasureText para tais fins, explicação mais detalhada pode encontrar aqui (Precisão dos resultados TextRenderer.MeasureText.)
Outras dicas
Se um LinkLabel
contém mais de um link, ou há partes do texto que são, nem em um link, em seguida, utiliza o controlo Graphics.DrawString/MeasureString
vez de TextRenderer.DrawText/MeasureText
. Você pode facilmente vê-lo em ação, a maior diferença na renderização é com o pequeno L letra:
linkLabel1.Text = new string('l', 100); // 100 x small L
linkLabel1.LinkArea = new LinkArea(0, 50);
linkLabel2.Text = new string('l', 100); // 100 x small L
TextRenderer.MeasureText é um wrapper gerenciado para a DrawTextEx API . O valor retornado vem do struct lprc. Você pode querer olhar para essa API para mais detalhes.
Eu acho que você poderia remover o estilo que faz com que seja sublinhado. linkLabel.Styles.Add("text-decoration", "none");
mas então é claro que ele não iria olhar como um link. : - /
Outra solução seria adicionar o preenchimento se eu acho.
int heightBefore = linkLabel.Height;
int fontHeight = CalculateHeight(linkLabel.Text, linkLabel.Font, linkLabel.Width);
int paddingHeight = heightBefore - fontHeight;
linkLabel.Font = otherFont;
linkLabel.Height = CalculateHeight(linkLabel.Text, otherFont, linkLabel.Width);
linkLabel.Height += paddingHeight;
Não o mais bonito de soluções, mas eu acho que ele funciona.