ListView - 使用标题分隔符对齐垂直网格线 - 使最后一列填充空格

时间:2015-09-06 13:24:56

标签: c# winforms listview

我正在尝试用C#编写Windows Forms MusicPlayer应用程序。

应用程序应显示一个列表并有一些播放/停止按钮。

我刚开始半小时前,但我的设计差不多完成了。现在我有三件事需要解决。一个错误和2个好看的东西:

  1. 在图片上你可以看到我发现的错误。你可能会说这没什么,但却是一个引人注目的人。我该如何解决这个问题?

    -

  2. 如何在不对内容居中的情况下对齐列的标题?

  3. 如何让最后一列填写listView的其余部分?

2 个答案:

答案 0 :(得分:3)

  • 您可以设置除{1st Column's Header之外的所有内容的TextAlign;它始终保持对齐。要更改,您需要所有者绘制它。

  • 没有自动填充选项,因此您需要编写一个setColumnwidth函数,该函数循环除了最后一列以外的所有函数并汇总其Widths;然后它从ListView的Clientsize.Width中减去总和,并设置最后一列的宽度。

  • 网格线中的显示错误对我来说是新的;到目前为止我不知道如何解决它;也许所有者绘图也会有帮助..?

<强>更新

以下是一些代码:

void setLastColumnTofill(ListView lv)
{
     int sum = 0;
     int count  = lv.Columns.Count;
     for (int i = 0; i < count   - 1; i++) sum += lv.Columns[i].Width;
     lv.Columns[count   - 1].Width = lv.ClientSize.Width - sum;
}

设置OwnerDraw = true后,你可以编码三个(所有都需要!)绘制事件:

private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
    e.Graphics.FillRectangle(SystemBrushes.Menu, e.Bounds);
    e.Graphics.DrawRectangle(SystemPens.GradientInactiveCaption, 
        new Rectangle(e.Bounds.X , 0, e.Bounds.Width , e.Bounds.Height) );

    string text = listView1.Columns[e.ColumnIndex].Text;
    TextFormatFlags cFlag = TextFormatFlags.HorizontalCenter 
                          | TextFormatFlags.VerticalCenter;
    TextRenderer.DrawText(e.Graphics, text, listView1.Font, e.Bounds, Color.Black, cFlag);
}

private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    e.DrawDefault = true;
}

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    e.DrawDefault = true;
}

你可能想要用颜色或宽度玩一点..

如果您有一个包含用于显示排序顺序(或其他内容)的图像的ImageList,您可以添加它以绘制它们:

 ColumnHeader colH = listView1.Columns[e.ColumnIndex];
 int ii = colH.ImageIndex;
 if (ii >= 0 && ii < imageList1.Images.Count) 
            e.Graphics.DrawImage(imageList1.Images[ii], 
              e.Bounds.Width + e.Bounds.X - imageList1.ImageSize.Width, 0);

enter image description here

答案 1 :(得分:3)

OwnerDraw设置为true后,您可以执行以下其他操作:

绘制ListView

int sortIndex = 0;
private void listView1_DrawColumnHeader(object sender,
   DrawListViewColumnHeaderEventArgs e)
{
    var state = e.State == ListViewItemStates.Selected ?
        VisualStyleElement.Header.Item.Hot : VisualStyleElement.Header.Item.Normal;
    var sortOrder = listView1.Sorting == SortOrder.Ascending ?
        VisualStyleElement.Header.SortArrow.SortedUp :
        VisualStyleElement.Header.SortArrow.SortedDown;
    var itemRenderer = new VisualStyleRenderer(state);
    var sortRenderer = new VisualStyleRenderer(sortOrder);
    var r = e.Bounds; 
    r.X += 1;
    itemRenderer.DrawBackground(e.Graphics, r);
    r.Inflate(-2, 0);
    var flags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter |
        TextFormatFlags.SingleLine;
    itemRenderer.DrawText(e.Graphics, r, e.Header.Text, false, flags);
    var d = SystemInformation.VerticalScrollBarWidth;
    if (e.ColumnIndex == sortIndex) //Sorted Column
        sortRenderer.DrawBackground(e.Graphics, 
            new Rectangle(r.Right - d, r.Top, d, r.Height));
}

private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    e.DrawDefault = true;  /*Use default rendering*/
}

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    e.DrawDefault = true;  /*Use default rendering*/
}

使用最后一栏填写ListView

private void ListViewSample_Load(object sender, EventArgs e)
{
    var otherItemWisth= this.listView1.Columns.Cast<ColumnHeader>()
        .Where(x => x.Index < this.listView1.Columns.Count - 1)
        .Sum(x => x.Width);
    this.listView1.Columns[this.listView1.Columns.Count - 1].Width = 
        this.listView1.ClientSize.Width - otherItemWisth;
}

<强>结果

enter image description here