调整ListView列以适应WinForms

时间:2011-01-26 09:01:27

标签: c# winforms listview

我面对listview列的调整大小问题。如果你锚定/停靠列表视图比正常winform比listview锚点或对接工作正常。我的意思是listview将调整大小并适合winforms,因为winforms最大化但你设计的列没有使用listview调整大小。

我的问题是:有没有办法用listview调整listview列以适应winform大小?

Listview设计代码:

 private void Form1_Load(object sender, EventArgs e)
    {

        listView1.View = View.Details;
        listView1.LabelEdit = true;
        listView1.BackColor = Color.GreenYellow;
        listView1.Columns.Add("Date", 100, HorizontalAlignment.Left);
        listView1.Columns.Add("TransID", 50, HorizontalAlignment.Left);
        listView1.Columns.Add("voucher", 100, HorizontalAlignment.Right);
        listView1.Columns.Add("particulars", 300, HorizontalAlignment.Left);
        listView1.Columns.Add("deposit", 100, HorizontalAlignment.Right);
        listView1.Columns.Add("withdrawal", 100, HorizontalAlignment.Right);

        string connstr = "server=.;initial catalog=DataBase;uid=UID;pwd=PWD";
        SqlConnection con = new SqlConnection(connstr);
        con.Open();
        listView1.Items.Clear();
        listView1.Refresh();
        string sql = "select date=convert(varchar,date,103),transID,max(particulars)as particulars,sum(deposit)as deposit,sum(withdrawal) as withdrawal,voucher from debank group by date,transID,voucher";
        SqlCommand cmd = new SqlCommand(sql, con);
        SqlDataAdapter dap = new SqlDataAdapter(cmd);
        DataSet ds = new DataSet();
        dap.Fill(ds);
        DataTable dt = ds.Tables[0];

        for (int i = 0; i < dt.Rows.Count; i++)
        {
            DataRow dr = dt.Rows[i];
            ListViewItem lvi = new ListViewItem(dr["date"].ToString());
            lvi.SubItems.Add(dr["transID"].ToString());
            lvi.SubItems.Add(dr["voucher"].ToString());
            lvi.SubItems.Add(dr["particulars"].ToString());
            lvi.SubItems.Add(dr["deposit"].ToString());
            lvi.SubItems.Add(dr["withdrawal"].ToString());
            listView1.Items.Add(lvi);
            listView1.FullRowSelect = true;

        }

        SizeLastColumn(listView1);


    }

5 个答案:

答案 0 :(得分:29)

  1. 程序设计。你必须在代码中维护它。
  2. 您可以在列表视图中调整最后一列的大小,以便自动调整大小。 净样本:
  3.   

    在ListView控件中,使用View   属性设置为详细信息,您可以   创建一个多列输出。   有时你会想要最后一个   ListView的列可以自行调整大小   占用所有剩余空间。您   可以通过设置列来完成此操作   宽度为魔术值-2。

         

    在以下示例中,名称为   ListView控件是lvSample:

    [c#]
    private void Form1_Load(object sender, System.EventArgs e)
    {
        SizeLastColumn(lvSample);
    }
    
    private void listView1_Resize(object sender, System.EventArgs e)
    {
        SizeLastColumn((ListView) sender);
    }
    
    private void SizeLastColumn(ListView lv)
    {
        lv.Columns[lv.Columns.Count - 1].Width = -2;
    }
    

    修改

    Programaticaly你可以用自己实现的算法做到这一点。问题是列表视图不知道您想要调整大小的列,而不知道什么不是。因此,您将在resize方法(或在resizeEmd方法中)指定所有列大小更改。因此,您计算列表视图的所有宽度,然后按比例划分所有列之间的值。 您的列宽度是50到50.因此,您的整个列表视图宽度为15 *х(默认状态下x = 50。我根据列数及其宽度计算出15个值)常规单位。调整表单大小后,您可以计算新的x = ListView.Width/15,然后将每个列宽设置为所需的值,所以

    private void SizeLastColumn(ListView lv)
    {
     int x = lv.Width/15 == 0 ? 1 : lv.Width/15;
     lv.Columns[0].Width = x*2; 
     lv.Columns[1].Width = x;
     lv.Columns[2].Width = x*2;
     lv.Columns[3].Width = x*6;
     lv.Columns[4].Width = x*2;
     lv.Columns[5].Width = x*2;
    }
    

答案 1 :(得分:10)

这是我的解决方案;

而不是resize事件,我更喜欢resizeEnd of form,这样代码只有在调整大小完成时才会运行一次。

private void Form1_ResizeEnd(object sender, EventArgs e)
{
    this.ResizeColumnHeaders();
}

ResizeColumnHeaders函数设置除最后一列之外的所有列以适合列内容。最后一列将使用LexRema提示的魔术值。

private void ResizeColumnHeaders()
{
    for (int i = 0; i < this.listView.Columns.Count - 1;i++ ) this.listView.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent);           
    this.listView.Columns[this.listView.Columns.Count - 1].Width = -2;
}

加载初始数据后,别忘了调用ResizeColumnHeaders();

private void Form1_Load(object sender, EventArgs e)
{            
    this.LoadEntries();
    this.ResizeColumnHeaders();
}

还有一件事是在列调整大小时防止闪烁,你需要对列表视图进行双重缓冲。

public Form1()
{
    InitializeComponent();            
    this.listView.DoubleBuffer();            
}

DoubleBuffer()实际上是一个易于使用的扩展。

public static class ControlExtensions
{
    public static void DoubleBuffer(this Control control) 
    {
        // http://stackoverflow.com/questions/76993/how-to-double-buffer-net-controls-on-a-form/77233#77233
        // Taxes: Remote Desktop Connection and painting: http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx

        if (System.Windows.Forms.SystemInformation.TerminalServerSession) return;
        System.Reflection.PropertyInfo dbProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        dbProp.SetValue(control, true, null);
    }
}

答案 2 :(得分:4)

一个简单的解决方案,它会自动调整列表视图和要调整大小的列的索引,以便将整个列表视图的客户区域的大小用于最后一个像素,不多也不少,即即使调整大小使控件变小,也不会出现丑陋的水平滚动条。

您希望从调整大小事件处理程序调用此方法,并在添加元素后再调用,以防在添加更多行之后出现垂直滚动条而不是控件具有空间垂直。

我不同意对ResizeEnd事件作出反应的想法,正如其他帖子中提到的那样,因为如果Windows设置为在移动和调整大小时绘制窗口,这在屏幕上看起来不太好。计算速度很快,因此不会产生任何问题,无法持续调整大小。

static private void ResizeAutoSizeColumn(ListView listView, int autoSizeColumnIndex)
{
  // Do some rudimentary (parameter) validation.
  if (listView == null) throw new ArgumentNullException("listView");
  if (listView.View != View.Details || listView.Columns.Count <= 0 || autoSizeColumnIndex < 0) return;
  if (autoSizeColumnIndex >= listView.Columns.Count)
    throw new IndexOutOfRangeException("Parameter autoSizeColumnIndex is outside the range of column indices in the ListView.");

  // Sum up the width of all columns except the auto-resizing one.
  int otherColumnsWidth = 0;
  foreach (ColumnHeader header in listView.Columns)
    if (header.Index != autoSizeColumnIndex)
      otherColumnsWidth += header.Width;

  // Calculate the (possibly) new width of the auto-resizable column.
  int autoSizeColumnWidth = listView.ClientRectangle.Width - otherColumnsWidth;

  // Finally set the new width of the auto-resizing column, if it has changed.
  if (listView.Columns[autoSizeColumnIndex].Width != autoSizeColumnWidth)
    listView.Columns[autoSizeColumnIndex].Width = autoSizeColumnWidth;
}

答案 3 :(得分:2)

您可以按照here所述按内容调整列的大小,或者您必须侦听ListView的Resize事件并在运行时设置列的大小。

答案 4 :(得分:0)

使用此

Private Sub ListView1_Resize(sender As Object, e As EventArgs) Handles ListView1.Resize
    Dim k = ListView1.Width - 10
    Dim i = k / 3
    ListView1.Columns(0).Width = k - i
    ListView1.Columns(1).Width = i / 2
    ListView1.Columns(2).Width = i / 2
End Sub

三列 一个更大的两个更小,相同大小