Как добавить многострочный текст в элемент ListBox? - PullRequest
2 голосов
/ 07 марта 2020

У меня небольшая проблема, и я не могу найти решение.
Я хотел бы поместить текст в конец элемента ListBox, и я не знаю, как ...

TagLib.File f = TagLib.File.Create(paths[i]);
listBox1.Items.Add("0" + i + ". " + f.Tag.Title +"\n" + string.Join(", ", f.Tag.Performers) + " - " + "\r" + f.Tag.Album + "                                               "  + f.Properties.Duration.TotalMinutes.ToString());

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

I want the text of all items to match Я хочу, чтобы текст всех элементов совпадал друг с другом And I can't find a solution how to put the text at the end and how the text can match each other И я не могу найти решение, как поместить текст в конец и как текст может соответствовать друг другу

1 Ответ

4 голосов
/ 08 марта 2020

Чтобы добавить многострочный текст в элемент управления ListBox, необходимо измерить и нарисовать текст самостоятельно.

Установите ListBox.DrawMode на DrawMode.OwnerDrawVariable , затем переопределите OnMeasureItem и OnDrawItem .

OnMeasureItem вызывается до рисования элемента, чтобы дать возможность определить размер элемента, устанавливая MeasureItemEventArgs e.ItemWidth и e.ItemHeight свойств (вы должны убедиться, что ListBox содержит элементы, прежде чем пытаться измерить один).

→ Когда вызывается OnDrawItem, свойство e.Bounds его DrawItemEventArgs будет установлено в меру, указанную в OnMeasureItem.

Для измерения текста вы можете использовать метод TextRenderer class MeasureText () или Graphics.MeasureString . Первый предпочтительнее, поскольку мы будем использовать класс TextRenderer для рисования текста элементов: TextRenderer.DrawText больше предсказуемого , чем Graphics.DrawString () в этом контекст, и он визуализирует текст естественно (как это делает ListBox - или ListView).

TextRenderer TextFormatFlags используются для тонкой настройки поведения рендеринга. Я добавил TextFormatFlags.ExpandTabs к флагам, так что вы также можете добавлять вкладки ("\t") в текст при необходимости. См. Визуальный пример.
"\n" можно использовать для создания перевода строки.

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

► Важно: максимум Item.Height составляет 255 пикселей. Помимо этой меры, текст Предмета не может быть визуализирован или представлен частично (но обычно он просто исчезает ). В примере кода есть проверка Мин / Макс на высоте элемента.

Вот как это работает:

ListBox OwnerDrawn Multiline

Я предлагаю использовать объект класса, если у вас его нет, хранить ваши предметы и описать их. Затем используйте List<class> в качестве ListBox.DataSource. Таким образом, вы можете лучше определить, как должна отображаться каждая часть. Некоторые части могут использовать жирный шрифт или другой цвет.

using System;
using System.Drawing;
using System.Windows.Forms;

public class ListBoxMultiline : ListBox
{
    TextFormatFlags flags = TextFormatFlags.WordBreak |
                            TextFormatFlags.PreserveGraphicsClipping |
                            TextFormatFlags.GlyphOverhangPadding | 
                            TextFormatFlags.LeftAndRightPadding |
                            TextFormatFlags.ExpandTabs |
                            TextFormatFlags.VerticalCenter;

    public ListBoxMultiline() { this.DrawMode = DrawMode.OwnerDrawVariable; }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        if (Items.Count == 0) return;
        if (e.State.HasFlag(DrawItemState.Focus) || e.State.HasFlag(DrawItemState.Selected)) {
            using (var selectionBrush = new SolidBrush(Color.Orange)) {
                e.Graphics.FillRectangle(selectionBrush, e.Bounds);
            }
        }
        else {
            e.DrawBackground();
        }

        TextRenderer.DrawText(e.Graphics, GetItemText(Items[e.Index]), Font, e.Bounds, ForeColor, flags);

        if (e.Index != Items.Count - 1) {
            Point lineOffsetStart = new Point(e.Bounds.X, e.Bounds.Bottom - 1);
            Point lineOffsetEnd = new Point(e.Bounds.Right, e.Bounds.Bottom - 1);
            e.Graphics.DrawLine(Pens.LightGray, lineOffsetStart, lineOffsetEnd);
        }
        base.OnDrawItem(e);
    }

    protected override void OnMeasureItem(MeasureItemEventArgs e)
    {
        if (Items.Count == 0) return;
        var size = GetItemSize(e.Graphics, GetItemText(Items[e.Index]));
        e.ItemWidth = size.Width;
        e.ItemHeight = size.Height;
        base.OnMeasureItem(e);
    }

    private Size GetItemSize(Graphics g, string itemText)
    {
        var size = TextRenderer.MeasureText(g, itemText, Font, ClientSize, flags);
        size.Height = Math.Max(Math.Min(size.Height, 247), Font.Height + 8) + 8;
        return size;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...