带有 AllowColumnReorder 的 ListView OwnerDraw 不能正常工作
ListView OwnerDraw with AllowColumnReorder don't work correct
我正在绘制自定义 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);
}
这工作正常:
但是如果我移动第一列就会出现绘图问题 - 前两列的数据被绘制在第一列中,而被移动的列中的数据根本没有被绘制:
发生这种情况是因为 e.Bounds 两个不同列的值相等。我该怎么做才能获得正确的 e.Bounds 值。
是的,这是 ListView class 中的错误。它的私有 GetItemRectOrEmpty() method 很无聊。作为错误解决方法编写,内部错误编号 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);
}
感谢 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);
}
我正在绘制自定义 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);
}
这工作正常:
但是如果我移动第一列就会出现绘图问题 - 前两列的数据被绘制在第一列中,而被移动的列中的数据根本没有被绘制:
发生这种情况是因为 e.Bounds 两个不同列的值相等。我该怎么做才能获得正确的 e.Bounds 值。
是的,这是 ListView class 中的错误。它的私有 GetItemRectOrEmpty() method 很无聊。作为错误解决方法编写,内部错误编号 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);
}
感谢 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);
}