gpt4 book ai didi

C# .net 4.0 tabControl1_DrawItem 事件不断触发

转载 作者:太空宇宙 更新时间:2023-11-03 12:43:26 25 4
gpt4 key购买 nike

我最近在我的一个程序中添加了一项功能,并注意到一些非常奇怪的事情。该功能要求我向正在使用的选项卡控件添加一个新选项卡。然后,这会将选项卡推过可以在表单上显示的默认大小,需要箭头在选项卡控件上导航选项卡。

enter image description here

我发现的问题是,如果选项卡控件上存在这些箭头,则 tabControl1_DrawItem 事件每隔几毫秒就会触发一次,导致程序变得迟缓,并且在窗体后坐在那里什么都不做时使用大约 15% 到 20% 的 CPU加载事件。

一旦我增加了表单大小使得箭头不存在,该事件仅在移动表单或选择不同的选项卡时触发。

我为此搜索了一整天并调试并找到了答案,或者我想你可以说解决方法,但不是在这里。所以我想我有两个问题。如果箭头存在,为什么事件会不断触发?有什么办法可以阻止它发生这种情况,因为我无法阻止应用程序的用户调整表单大小并实现这种情况?

这是我在事件中的代码。

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
Platform.Log(LogLevel.Debug, "DrawItem event is being called.");
//Draw the tabs on the tab conrol
e.DrawBackground();
using (Brush br = new SolidBrush(TabColors[tabControl1.TabPages[e.Index]]))
{
e.Graphics.FillRectangle(br, e.Bounds);
SizeF sz = e.Graphics.MeasureString(tabControl1.TabPages[e.Index].Text, e.Font);
e.Graphics.DrawString(tabControl1.TabPages[e.Index].Text, e.Font, DGVBrushForeColor, e.Bounds.Left + (e.Bounds.Width - sz.Width) / 2, e.Bounds.Top + (e.Bounds.Height - sz.Height) / 2 + 1);

Rectangle rect = e.Bounds;
rect.Offset(0, 1);
rect.Inflate(0, -1);
e.Graphics.DrawRectangle(DGVPenBackColor, rect);
e.DrawFocusRectangle();
}

//To Fill the blank portion of the end of the tab control
SolidBrush fillbrush = new SolidBrush(BACK_COLOR);
//draw rectangle behind the tabs
Rectangle lasttabrect = tabControl1.GetTabRect(tabControl1.TabPages.Count - 1);
Rectangle background = new Rectangle();
background.Location = new Point(lasttabrect.Right, 0);

//pad the rectangle to cover the 1 pixel line between the top of the tabpage and the start of the tabs
background.Size = new Size(tabControl1.Right - background.Left, lasttabrect.Height + 1);
e.Graphics.FillRectangle(fillbrush, background);
}

最佳答案

在 Hans Passant 的帮助下找到了答案。我在我的应用程序的 stackoverflow 上实现了这段代码。

    public Form1()
{
InitializeComponent();

int style = NativeWinAPI.GetWindowLong(this.Handle, NativeWinAPI.GWL_EXSTYLE);
style |= NativeWinAPI.WS_EX_COMPOSITED;
NativeWinAPI.SetWindowLong(this.Handle, NativeWinAPI.GWL_EXSTYLE, style);
}

internal static class NativeWinAPI
{
internal static readonly int GWL_EXSTYLE = -20;
internal static readonly int WS_EX_COMPOSITED = 0x02000000;

[DllImport("user32")]
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32")]
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
}

这就是当存在选项卡导航箭头时绘图事件不断触发的问题。为了解决这个问题,我将选项卡控件的多行属性设置为 true。这样可以防止显示导航箭头,并且我可以接受多行选项卡。

我还想指出,如果没有这段代码,问题就不会发生,但是如果没有像 Hans 所说的“WS_EX_COMPOSITED hack”,选项卡就会不断地疯狂闪烁。通过使用此 hack 对所有内容进行双缓冲,它使所有内容都运行良好,因此它暂时保留在此应用程序中。

关于C# .net 4.0 tabControl1_DrawItem 事件不断触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38133954/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com