如何将多行文本添加到 ListBox 项?

Uni*_*eOS 3 .net c# graphics listbox winforms

我有一个小问题,找不到解决办法。
我想在一个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());
Run Code Online (Sandbox Code Playgroud)

我已经试过了,但不幸的是它不能那样工作。也许有人知道如何将文本放在最后,并带有代码?

我希望所有项目的文本匹配 我希望所有项目的文本相互匹配 而且我找不到解决方案如何将文本放在最后以及文本如何相互匹配 而且我找不到解决方案如何将文本放在最后以及文本如何相互匹配

Jim*_*imi 6

要将多行文本添加到 ListBox 控件,您需要自己测量和绘制文本。

ListBox.DrawMode设置为DrawMode.OwnerDrawVariable,然后覆盖 OnMeasureItemOnDrawItem

? OnMeasureItem在绘制 Item 之前调用,以允许定义 Item Size、设置MeasureItemEventArgs e.ItemWidthe.ItemHeight属性(您必须在尝试测量之前验证 ListBox 包含 Items)。

? 当OnDrawItem被调用时,e.Bounds其财产DrawItemEventArgs将被设置为指定的措施OnMeasureItem

要测量文本,您可以使用TextRendererMeasureText()方法或Graphics.MeasureString。前者是首选,因为我们将使用TextRenderer类来绘制 Items 的文本:在这种情况下比Graphics.DrawString()TextRenderer.DrawText可预测,并且它自然地呈现文本(就像 ListBox - 或 ListView - 那样)。

TextRendererTextFormatFlags用于微调渲染行为。我已添加TextFormatFlags.ExpandTabs到标志中,因此您还可以"\t"在需要时将制表符 ( )添加到文本中。请参阅视觉示例。
"\n"可用于生成换行符。

在示例代码中,我将8像素添加到 Items 的测量高度,因为还绘制了行分隔符以更好地定义 Item 的限制(否则,当 Item 跨越多条线时,可能很难了解其文本的开始和结束位置)。

? 重要提示:最大值Item.Height255像素。超出这个度量,项目的文本可能不会被渲染或被部分渲染(但它通常只是消失)。示例代码中对项目高度进行了最小/最大检查。

这是它的工作原理:

ListBox OwnerDrawn 多行

我建议使用类对象(如果还没有)来存储您的项目并描述它们。然后使用 aList<class>作为 ListBox.DataSource. 这样,您可以更好地定义每个部分的渲染方式。某些部分可能使用粗体或不同的颜色。

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

public class ListBoxMultiline : ListBox
{
    TextFormatFlags flags = TextFormatFlags.WordBreak |
                            TextFormatFlags.PreserveGraphicsClipping |
                            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;
    }
}
Run Code Online (Sandbox Code Playgroud)