[C#] ListView 的 Details 顯示和刪除列

承上一篇:Windows Form 的 ListBox 排版對齊問題,經網友前輩們建議改用 ListView Details 來做訂單顯示,先看結果:

這個結果比較接近我們平常看到的 Excel 等二維表格,整齊漂亮對好。

ListBox 基本使用和刪除項目

介紹 ListView Details 之前先比較一下 ListBox 的建構方法和取出選擇項目的 index ,然後給旁邊的 Button button1 的 Click 事件中要刪除 ListBox 所選項目,而 button2 會清空訂單資料和 ListBox。

namespace ListBoxDemo
{
  public partial class Form1 : Form
  {
    ListBox listBox1;
    public Form1()
    {
      InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
      listBox1 = new ListBox
      {
        Size = new Size(400,300),       // ListBox 很陽春沒什麼好設定的
        Location = new Point(100,100)   // 大概就大小、位置、字型...
      };
      this.Controls.Add(listBox1);
      
      foreach(Order ord in orderList)   // 讓 Items 呼叫 .Add() 方法來新增項目
      {
        listBox1.Items.Add(ord.Name + ord.Price + ord.SugarIce);
      }                                 // 串接成一個字串
    }
    private void button1_Click(object sender, EventArgs e)
    {
      int idx = listBox1.SelectedIndex;
      if(idx > -1)                      // 當沒有選 ListBox 項目時 idx 得 -1
      {
        orderList.RemoveAt(idx);
        listBox1.Items.RemoveAt(idx);   // 刪除 ListBox 上的項目
      }
    }
    private void button2_Click(object sender, EventArgs e)
    {
      listBox1.Items.Clear();
    }
  }
}

ListView 基本使用和刪除

ListView 的 Details 顯示多了 Column Header(如同 HTML 的 table 中的 th 標籤)要設定,可以手動拉取一個 ListView ,在屬性視窗中找到

  • View 設為 Details 或控制項右上角的向右箭頭選「檢視」為「Details」
  • FullRowSelect 設為 true,當選擇項目時會全選整個 row
  • GridLines 設為 true 可讓格線顯示
  • Columns 點選更多,或控制項右上角的向右箭頭選「編輯資料行」:

左邊點選「加入」會新增一個標頭欄位,右邊有 Text 表示欄位名,Width 表欄位寬度,下圖手動增加三個欄位:

下面是程式碼新增與設定 ListView

namespace ListViewDemo
{
  public partial class Form1 : Form
  {
    ListView listView1;
    public Form1()
    {
      InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
      listView1 = new ListView
      {
        Size = new Size(400,300),
        Location = new Point(100,100),
        View = View.Details,
        FullRowSelect = true
      }
      listView1.Columns.Add("品項",150);    // Column 的 Text 和 Width
      listView1.Columns.Add("單價",70);
      listView1.Columns.Add("糖冰",150);
      this.Controls.Add(listView1);

      foreach(Order ord in orderList)
      {
        ListViewItem item = new ListViewItem(
          new string[] { 
            ord.Name, 
            ord.Price.ToString(), 
            ord.SugarIce }
          );
        listView1.Items.Add(item);
      }
    }
    private void button1_Click(object sender, EventArgs e)
    {
      if(listView1.FocusedItem == null)          // 還沒選取任何內容時
      {
        return;
      }
      int idx = listView1.FocusedItem.Index;     // 取得選取何列的 index
      orderList.RemoveAt(idx);
      listView1.Items.RemoveAt(idx);
    }
    private void button2_Click(object sender, EventArgs e)
    {
      listView1.Items.Clear();   // 注意不是listView1.Clear() ,這樣會連標頭都清光
    }
  }
}

用字串陣列來新增項目的寫法其實是快速的 overload:

  foreach(Order ord in orderList)
  {
    ListViewItem item = new ListViewItem(
      new string[] { 
        ord.Name, 
        ord.Price.ToString(), 
        ord.SugarIce }
      );
    listView1.Items.Add(item);
  }

本來的寫法會更清楚 ListView 裡面項目是長什麼樣子:

  foreach(Order ord in orderList)
  {
    ListViewItem item = new ListViewItem(ord.Name);
    item.SubItems.Add(ord.Quantity.ToString());
    item.SubItems.Add(ord.SugarIce);
    listView1.Items.Add(item);
  }

留言