覆盖ListBox的DrawItem – 未重绘未选择的项目
这是一个C#桌面应用程序。 我的ListBox
的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
将以下代码放在Resize事件中:
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()。 但他们没有解释这种行为。 剪切区域出现问题,导致文本无法正确更新。 我没有看到发生的地方,Graphics对象状态没问题。
Graphics.DrawString()是一个非常麻烦的方法,你应该真的避免它。 所有Windows窗体控件(包括ListBox)都使用TextRenderer.DrawText()。 这解决了我使用它时的问题。 我知道测量更难,您可以通过在固定偏移处显示IP地址来解决这个问题。 看起来也更好,他们会以这样的方式排成一列。
它闪烁,因为你使用e.DrawBackground()。 这会删除现有文本,您可以在其上绘制文本。 我不认为双缓冲会解决这个问题,你必须绘制整个项目,这样你就不必绘制背景了。 如果你不能用大字体获得文本的确切大小,那么一个解决方法就是首先绘制一个位图。
上述就是C#学习教程:覆盖ListBox的DrawItem – 未重绘未选择的项目分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/951778.html