带有AllowColumnReorder的ListView OwnerDraw无法正常工作

时间:2015-03-05 14:32:56

标签: c# .net listview

我正在绘制自定义ListView,并将OwnerDraw属性设置为“true”。 listview还有AllowColumnReorder'true'属性。

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    e.Graphics.DrawString(e.SubItem.Text, Font, Brushes.Black, e.Bounds);
}

这很好用:

enter image description here

但是,如果我移动第一列有一个绘图问题 - 前两列的数据被绘制在frist列中,并且移动的列中的数据根本没有绘制:

enter image description here

这是因为e.Bounds等于两个不同列的值。我该怎么做才能获得正确的e.Bounds值。

2 个答案:

答案 0 :(得分:3)

是的,这是ListView类中的一个错误。它的私人GetItemRectOrEmpty() method是borken。写为bug解决方法,内部错误号VSWhidbey#163674。有错误修复导致另一个错误是一个相当传统的编程事故,大男孩也是这样做:)当它向Windows询问项目矩形,通过e.Bounds属性传递给你时,它会啪嗒啪嗒地询问ItemBoundsPortion.Entire。哪个是完整的ListViewItem矩形,包括子项。

幸运的是,解决方法很简单,您可以自己使用ItemBoundsPortion.ItemOnly:

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) {
    var bounds = e.Bounds;
    if (e.ColumnIndex == 0) {
        bounds = listView1.GetItemRect(e.ItemIndex, ItemBoundsPortion.ItemOnly);
    }
    e.Graphics.DrawString(e.SubItem.Text, Font, Brushes.Black, bounds);
}

答案 1 :(得分:0)

感谢Hans Passant获取信息。我使用下一个代码修复了这个错误:

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
    {
        Rectangle bounds = e.Bounds;
        if (e.ColumnIndex == 0 && listView1.Columns[0].DisplayIndex != 0)
        {
            bounds = GetFirstColumnCorrectRectangle(e.Item);
        }
        e.Graphics.DrawString(e.SubItem.Text, Font, Brushes.Black, bounds);
    }

    private Rectangle GetFirstColumnCorrectRectangle(ListViewItem item)
    {
        int i;
        for (i = 0; i < listView1.Columns.Count; i++)
            if (listView1.Columns[i].DisplayIndex == listView1.Columns[0].DisplayIndex - 1)
                break;
        return new Rectangle(item.SubItems[i].Bounds.Right, item.SubItems[i].Bounds.Y, listView1.Columns[0].Width, item.SubItems[i].Bounds.Height);
    }