Как я могу определить, сколько строки будет соответствовать определенной ширине? - PullRequest
4 голосов
/ 19 апреля 2011

Привет У меня проблема с настройкой длины текста, чтобы он соответствовал длине формы. В моей форме я поместил ярлык, который отвечает за отображение некоторого длинного текста. Однако текст может быть настолько длинным, что не будет соответствовать форме. Вот почему я хочу сократить этот текст и добавить ... в конце.

Проблема в том, что я не знаю, как эффективно рассчитать подстроку максимальной длины, которая бы подходила по форме. До сих пор мне удавалось только проверить, является ли данный текст слишком длинным (я использую метод MeasureString из Graphics class). Как лучше всего рассчитать максимальную подстроку, которая будет соответствовать форме (подстрока, которая width < form.Width)?

Ответы [ 5 ]

1 голос
/ 05 мая 2017

Я использовал этот код, чтобы подогнать текст в строке состояния, удалив символы из начала строки. Может быть, вы можете изменить его под свои нужды

        status.Text = status.Text + " | " + newText;
        while (TextRenderer.MeasureText(status.Text, status.Font).Width > status.Width)
            status.Text = status.Text.Substring(1);
1 голос
/ 08 марта 2012

У меня есть решение этой проблемы, так как я сам столкнулся с ней сегодня.Мой ToolStripStatusLabel установлен на автоматический размер, но он превышал ширину родительского элемента управления и таким образом скрывался.Мое решение специально для использования с элементом управления ToolStripStatusLabel .Поскольку это так, этот элемент управления не предоставляет свойство MaxWidth или свойство AutoEllipsis.Он также не будет генерировать объект Graphics для меня, поскольку он не является частью семейства элементов управления.Этот метод может быть изменен для работы с двумя объектами Control, без особых изменений, за исключением параметра.Мои возможности были весьма ограничены, поэтому я сфабриковал этот метод:

/// <summary>
/// If a child ToolStripStatusLabel is wider than it's parent then this method will attempt to
/// make the child's text fit inside of the parent's boundaries. An ellipsis can be appended
/// at the end of the text to indicate that it has been truncated to fit.
/// </summary>
/// <param name="child">Child ToolStripStatusLabel</param>
/// <param name="parent">Parent control where the ToolStripStatusLabel resides</param>
/// <param name="appendEllipsis">Append an "..." to the end of the truncated text</param>
public static void TruncateChildTextAccordingToControlWidth(ToolStripStatusLabel child, Control parent, bool appendEllipsis)
{
    //If the child's width is greater than that of the parent's
    if(child.Size.Width > parent.Size.Width)
    {
        //Get the number of times that the child is oversized [child/parent]
        decimal decOverSized = (decimal)(child.Size.Width) / (decimal)(parent.Size.Width);

        //Get the new Text length based on the number of times that the child's width is oversized.
        int intNewLength = (int)(child.Text.Length / (2M * decOverSized)); //Doubling as a buffer (Magic Number).

        //If the ellipsis is to be appended
        if(appendEllipsis) //then 3 more characters need to be removed to make room for it.
            intNewLength = intNewLength - 3;

        //If the new length is negative for whatever reason
        if(intNewLength < 0) 
            intNewLength = 0; //Then default it to zero

        //Truncate the child's Text accordingly
        child.Text = child.Text.Substring(0, intNewLength);

        //If the ellipsis is to be appended
        if(appendEllipsis) //Then do this last
            child.Text += "...";
    }
}

Я буду первым, кто укажет, что я совершил ужасную вещь и включил магическое число!Я прошу прощения, но 2M является буфером.Я не мог найти лучший способ сделать это, когда / если я найду способ, я обязательно вернусь и обновлю его здесь.Мне нужно было магическое число, потому что процент, который я вычислил, является точным, но для того, чтобы достаточно хорошо вписать дочерний элемент управления в родительский элемент, мне нужно было примерно вдвое больше, чем возвращали.

Я уверен, что это будет не совсем точно в зависимости от размера шрифта метки и других факторов, но эй, это место для начала.

1 голос
/ 19 апреля 2011

Единственный надежный способ, которым я знаю, - это укоротить вашу строку, пока она не подойдет, которую вы можете проверить с помощью MeasureString(), к сожалению, обратного метода не существует (учитывая ширину, сколько этой строки будет соответствовать), так что вы собираетесь чтобы построить это самостоятельно.

0 голосов
/ 29 января 2015

Установите для свойства AutoSize метки значение true, затем разделите текст на токены и добавьте их токен с токеном в label.Text до label.Width > Width.

0 голосов
/ 29 января 2015

Вы можете написать текст слово за словом и тем временем перемещать курсор вперед, пока он не достигнет конца строки (ширина формы). У меня была похожая проблема, но я рисовал текст в форме, я изменил свой код в соответствии с вашими потребностями.

private bool WriteWord(string word)
{
    Size size = TextRenderer.MeasureText(word + "  ", Font);
    if (cursor.X + size.Width > Width)
    {
        // you reached the end of the line
        return false;
    }
    label1.Text += word + "  "; // add the word to label.
    cursor.X += size.Width;
    return true;
}
Point Cursor;
private string FindMaxSubstring(string text)
{
    string[] tokens = text.Split(new string[] { " "}); 
    string substring ="";
    Cursor.X = 0;
    foreach (var t in tokens)
    {
        if (!string.IsNullOrEmpty(t.Trim()))
        {
            if (!WriteWord(t))
                return substring;
            substring += t;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...