【问题标题】:How to Format Listbox or padding如何格式化列表框或填充
【发布时间】:2019-01-27 17:16:27
【问题描述】:

当我从表单左侧单击我的产品时,我会在 ListBox 填充名称和价格上看到它们。 但是因为每个产品名称的名称长度都不同,所以价格是丑陋的格式,这不是你在我的图片左侧看到的直接方式。 如果您在我的附加图片上看到它们,我希望它们像右侧一样。 我在列表框格式事件中的代码如下,但无法正常工作。请帮忙!

private void ListOfPaidProducts_Format(object sender, ListControlConvertEventArgs e)
{
    string currentProductName = ((Product)e.ListItem).Description;
    string currentPrice = String.Format("{0}", ((Product)e.ListItem).Price); // I tried even with {0,20}....

    string currentProductNamePadded = currentProductName.PadRight(30);

    e.Value = currentProductNamePadded + currentPrice + "$";
}

【问题讨论】:

  • 您可能想改用DataGridView。虽然我建议您使用DataGridView,但仅供参考,如果不使用等距字体,您将无法为ListBox 实现干净整洁的多列格式,除非您决定进行自定义绘画,例如like this
  • 您可以使用ListBoxUseCustomTabOffsets 功能,或者更好地使用ListView 或DataGridView,如前所述。由于文本长度可能会发生变化,您可能希望避免硬编码值或不断测量文本,因此不同的控件是显而易见的选择。

标签: c# winforms listbox formatting


【解决方案1】:

您可能应该使用 ListView 而不是 ListBox。

例如,对于数据

List<Product> list = new List<Product>
{
   new Product{Description = "abc efg", Price= 123},
   new Product{Description = "abc efg hijk 12 1212 12", Price= 23},
   new Product{Description = "abc", Price= 343},
   new Product{Description = "abc efg", Price= 22}
};

您可以按如下方式配置 ListView。

将 ListView 的视图设置为 Detail 以显示多列

listView1.View = View.Details;

下一步添加两列,用于显示描述和价格。

listView1.Columns.Add("Description");
listView1.Columns.Add("Price");

现在您可以将项目添加到 ListView,如下所示。

foreach(var items in list)
{
   ListViewItem lvi = new ListViewItem();
   lvi.Text = items.Description;
   lvi.SubItems.Add($"{items.Price} $");
   listView1.Items.Add(lvi);
}

最后,您可以使用 AutoReizeColumn 方法确保 Columns 将自身调整到最大内容大小。

listView1.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.ColumnContent);
listView1.AutoResizeColumn(1, ColumnHeaderAutoResizeStyle.ColumnContent);

您可能还对 ListView 的 FullRowSelect 属性感兴趣,它可以选择整行,而不是鼠标点击行时的列。

listView1.FullRowSelect = true;

输出

【讨论】:

    【解决方案2】:

    如果您使用为每个字符分配相同空间的字体,例如“Courier New”,您可以像这样准备对象

    public class DisplayProduct // create a little decorator
    {
         public DisplayProduct(Product prod, int pad)
         {
             Display = prod.Name.PadRight(pad) + prod.Price;
         }
    
         private Product Prod {get; set;}
    
         // if you plan to use Product properties, you can change scope and do
         // ((ProductDisplay)list.SelectedItem).Prod.Price
         public int Id {get{return Prod.Id;}}  
    
         public string Name {get{return Prod.Name;}} 
    
         public string Display {get; private set;} 
    
    }
    
    List<Product> products = GetList(...);
    int maxLen = products.Max(p => p.Name.Length) + 5;
    var diplayList = products.Select(p => new DisplayProduct(p, maxLen));
    
    myListBox.DisplayMember = "Display";
    myListBox.ValueMember = "Id";    
    myListBox.DataSource = diplayList;
    

    但是您可以使用网格甚至ListView 来显示结构数据。您可以做的另一件事 - 在ListBox 中绘制自定义项目。但我认为这不值得练习。

    【讨论】:

    • 这些被称为 等宽字体,如果您想搜索列表以查看您还有哪些其他选项。
    • @Idle_Mind 我的回答与 OP 的愿望密切相关。当然,有很多选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 2011-01-22
    • 2021-05-23
    相关资源
    最近更新 更多