C# 覆盖ListBox的DrawItem-未选中的项不会重新绘制
这是一个C#桌面应用程序。myC# 覆盖ListBox的DrawItem-未选中的项不会重新绘制,c#,winforms,listbox,ondrawitem,C#,Winforms,Listbox,Ondrawitem,这是一个C#桌面应用程序。my列表框的DrawStyle属性设置为OwnerDrawFixed 问题:我覆盖DrawItem,以不同的字体绘制文本,它可以工作。但是,当我在运行时开始调整窗体大小时,选定的项被正确绘制,但其余的项没有被重新绘制,从而导致未选定项的文本看起来已损坏 这是我的密码: private void listDevices_DrawItem(object sender, DrawItemEventArgs e) { e.DrawBackground(); s
列表框的DrawStyle
属性设置为OwnerDrawFixed
问题:我覆盖DrawItem,以不同的字体绘制文本,它可以工作。但是,当我在运行时开始调整窗体大小时,选定的项被正确绘制,但其余的项没有被重新绘制,从而导致未选定项的文本看起来已损坏
这是我的密码:
private void listDevices_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
string textDevice = ((ListBox)sender).Items[e.Index].ToString();
e.Graphics.DrawString(textDevice,
new Font("Ariel", 15, FontStyle.Bold), new SolidBrush(Color.Black),
e.Bounds, StringFormat.GenericDefault);
// Figure out where to draw IP
StringFormat copy = new StringFormat(
StringFormatFlags.NoWrap |
StringFormatFlags.MeasureTrailingSpaces
);
copy.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, textDevice.Length)});
Region[] regions = e.Graphics.MeasureCharacterRanges(
textDevice, new Font("Ariel", 15, FontStyle.Bold), e.Bounds, copy);
int width = (int)(regions[0].GetBounds(e.Graphics).Width);
Rectangle rect = e.Bounds;
rect.X += width;
rect.Width -= width;
// draw IP
e.Graphics.DrawString(" 255.255.255.255",
new Font("Courier New", 10), new SolidBrush(Color.DarkBlue),
rect, copy);
e.DrawFocusRectangle();
}
listDevices.Items.Add("Device001");
listDevices.Items.Add("Device002");
此外,正确绘制的项目(所选项目)在调整表单大小时闪烁。没什么大不了的,但如果有人知道原因。。。。tnx将以下代码放入调整大小事件中:
private void listDevices_Resize(object sender, EventArgs e) {
listDevices.Invalidate();
}
这将导致所有内容都被重新绘制
要停止闪烁,需要双缓冲
为此,创建一个从ListBox派生的新类,并将以下内容放入构造函数中:
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
或者将其粘贴到代码文件中:
using System.Windows.Forms;
namespace Whatever {
public class DBListBox : ListBox {
public DBListBox(): base() {
this.DoubleBuffered = true;
// OR
// this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
}
}
用项目使用的名称空间替换“Whatever”,或者使其更有用。编译之后,您应该能够在表单设计器中添加一个DBListBox。我重新处理了这个问题。代码中有几个错误,字体名为“Arial”,您不应该调整rect.Width,您忘记了对字体、画笔和区域调用Dispose()。但他们不能解释这种行为。剪切区域有问题,无法正确更新文本。我看不出在哪里发生这种情况,图形对象状态是正常的
DrawString()是一个非常麻烦的方法,您应该避免使用它。所有Windows窗体控件(包括ListBox)都使用TextRenderer.DrawText()。这解决了我使用它时的问题。我知道测量比较困难,您可以通过在固定偏移量显示IP地址来解决这一问题。看起来也更好,他们会以这种方式排成一列
它会闪烁,因为您使用了e.trackground()。如果删除现有文本,则将文本重新绘制在其上。我不认为双缓冲可以解决这个问题,你必须画出整个项目,这样你就不必画背景了。棘手的是,如果您无法使用大字体获得文本的确切大小,解决方法是首先绘制位图。感谢主要(重画)问题提示-它可以工作。不过,双缓冲对闪烁没有帮助。我真的很感谢您看到这一点。我会解决你指出的问题。但我想我现在会生活在闪烁中——这是一个供个人使用的小工具。