【问题标题】:How to add multiline Text to a ListBox item?如何将多行文本添加到 ListBox 项?
【发布时间】:2020-03-07 20:03:38
【问题描述】:

我有一个小问题,找不到解决方案。
我想在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());

我已经尝试过了,但不幸的是它不起作用。也许有人知道如何始终将文本放在末尾,并带有代码?

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

【问题讨论】:

  • 您需要在没有 \n 和 \r 的情况下执行此操作。谷歌“c#多行列表框”如果那不实用。
  • 通过将TextFormatFlags.Right 添加到标志或使用制表符来右对齐。

标签: c# .net winforms graphics listbox


【解决方案1】:

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

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

OnMeasureItem 在绘制项目之前调用,以允许定义项目大小,设置 MeasureItemEventArgs e.ItemWidthe.ItemHeight 属性(在尝试测量一项之前,您必须验证 ListBox 是否包含项)。

→ 调用OnDrawItem 时,其DrawItemEventArgse.Bounds 属性将设置为OnMeasureItem 中指定的度量值。

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

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

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

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

这就是它的工作原理:

如果你没有,我建议使用类对象来存储你的项目 并描述它们。然后使用List<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;
    }
}

【讨论】:

  • 列表框看起来非常好,对我很有帮助,但是当我尝试创建类时,代码中出现错误 System.ValueTuple´2 is not defined or import
  • 好的,进行了编辑。正如@Olivier Jacot-Descombes 所指出的,命名元组并不是真正需要的,我只是喜欢它:) 还将表达式主体构造函数更改为 normal 形式。
  • 是的,protected override void OnDrawItem(DrawItemEventArgs e) 的第一行没有成功(我在注释中写到了:)。添加该行:if (Items.Count == 0) return; 就可以了。
  • 在 OnDrawItem 中查看编辑,新的 SolidBrush(用 using 声明声明,因为 SolidBrush 是一次性对象)。你当然可以使用Color.FromArgb() 而不是Color.Orange
  • 如果有些事情你不能开始工作,花一些时间来测试这里描述的对象,你会做对的。如果您尝试在同一行中左右对齐文本的不同部分,则不能使用标志,因为没有标志。您需要使用硬标签。请参阅ListBox.UseCustomTabOffsets,使用ListBox.UseTabStops 激活。如果你以前没有做过,要正确地做是不容易的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
  • 2012-01-13
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多