我正在绘制自定义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);
}
这很好用:
但是,如果我移动第一列有一个绘图问题 - 前两列的数据被绘制在frist列中,并且移动的列中的数据根本没有绘制:
这是因为e.Bounds等于两个不同列的值。我该怎么做才能获得正确的e.Bounds值。
答案 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);
}