优化窗口最大化和还原时的性能,添加节流机制和缓存逻辑

This commit is contained in:
zqm
2025-11-12 11:03:46 +08:00
parent c35117bc0d
commit ad71cfb6bd
4 changed files with 143 additions and 37 deletions

View File

@@ -146,7 +146,7 @@ namespace JoyD.Windows.CS
// toolStrip
//
this.toolStrip.AllowDrop = true;
this.toolStrip.CanOverflow = false;
this.toolStrip.CanOverflow = true;
this.toolStrip.Dock = System.Windows.Forms.DockStyle.None;
this.toolStrip.ImageScalingSize = new System.Drawing.Size(20, 20);
this.toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {

View File

@@ -4108,14 +4108,26 @@ namespace JoyD.Windows.CS
}
}
// 上次调整时间,用于节流
private DateTime lastAdjustTime = DateTime.MinValue;
// 节流时间间隔(毫秒)
private const int throttleInterval = 100;
// 缓存的可见按钮数量,避免每次都重新计算
private int cachedVisibleButtonCount = -1;
/// <summary>
/// 窗体大小变化事件处理程序
/// 根据toolStripContainer宽度动态调整toolStrip和TopToolStripPanel的尺寸
/// </summary>
private void Setting_Resize(object sender, EventArgs e)
{
// 调用调整toolStrip尺寸的方法
AdjustToolStripDimensions();
// 实现节流,避免频繁调用
DateTime now = DateTime.Now;
if ((now - lastAdjustTime).TotalMilliseconds >= throttleInterval)
{
AdjustToolStripDimensions();
lastAdjustTime = now;
}
}
/// <summary>
@@ -4125,43 +4137,23 @@ namespace JoyD.Windows.CS
{
try
{
// 确保toolStripContainer和toolStrip不为null
if (toolStripContainer != null && toolStrip != null)
// 确保toolStripContainer和toolStrip不为null,并且窗体未被释放
if (toolStripContainer != null && toolStrip != null && !this.IsDisposed)
{
// 获取toolStripContainer的宽度
int containerWidth = toolStripContainer.Width;
// 设置toolStrip的宽度与container一致
toolStrip.Width = containerWidth;
// 计算可见按钮的数量
int visibleButtonCount = 0;
foreach (ToolStripItem item in toolStrip.Items)
// 检查窗口句柄是否已创建如果已创建则使用BeginInvoke否则直接执行
if (this.IsHandleCreated)
{
if (item.Visible && !(item is ToolStripSeparator))
// 使用BeginInvoke确保调整操作在UI线程的下一个消息循环中执行
this.BeginInvoke((MethodInvoker)delegate
{
visibleButtonCount++;
}
TryAdjustToolStripDimensions();
});
}
else
{
// 窗口句柄未创建时直接执行
TryAdjustToolStripDimensions();
}
// 根据可见按钮数量和容器宽度计算需要的行数
int buttonWidth = 25;
int buttonsPerRow = Math.Max(1, containerWidth / buttonWidth);
int requiredRows = (int)Math.Ceiling((double)visibleButtonCount / buttonsPerRow);
// 设置TopToolStripPanel的最小高度确保有足够空间显示多行按钮
int buttonHeight = 25; // 按钮高度加上边距
int requiredHeight = requiredRows * buttonHeight + 10; // 加上额外边距
// 限制最大高度,防止高度过大
requiredHeight = Math.Max(requiredHeight, 35);
toolStrip.MinimumSize = new Size(toolStrip.MinimumSize.Width, requiredHeight);
// 设置TopToolStripPanel的最小高度
toolStripContainer.TopToolStripPanel.MinimumSize = new Size(toolStripContainer.TopToolStripPanel.MinimumSize.Width, requiredHeight);
// 重新布局toolStrip和容器
toolStrip.PerformLayout();
toolStripContainer.PerformLayout();
}
}
catch (Exception ex)
@@ -4169,6 +4161,104 @@ namespace JoyD.Windows.CS
Console.WriteLine("调整toolStrip尺寸失败: " + ex.Message);
}
}
/// <summary>
/// 实际执行toolStrip尺寸调整的逻辑
/// </summary>
private void TryAdjustToolStripDimensions()
{
try
{
// 再次检查控件是否存在且不为null并检查是否已被释放
if (toolStripContainer != null && toolStrip != null && !this.IsDisposed && !toolStrip.IsDisposed && !toolStripContainer.IsDisposed)
{
// 获取toolStripContainer的宽度
int containerWidth = toolStripContainer.Width;
// 只有当宽度发生显著变化时才进行调整容差5像素
bool widthChanged = Math.Abs(toolStrip.Width - containerWidth) > 5;
if (widthChanged)
{
toolStrip.Width = containerWidth;
}
// 优化:仅当缓存无效或按钮状态可能变化时才重新计算可见按钮数量
bool needRecalculateButtons = cachedVisibleButtonCount == -1;
if (!needRecalculateButtons)
{
// 快速检查:只检查前几个按钮作为可见性变化的判断依据
int quickCheckCount = 0;
foreach (ToolStripItem item in toolStrip.Items)
{
if (quickCheckCount >= 5) break; // 只检查前5个按钮
if (item.Visible && !(item is ToolStripSeparator))
{
quickCheckCount++;
}
}
// 如果快速检查结果与缓存的差异超过一半,则重新计算
needRecalculateButtons = quickCheckCount > cachedVisibleButtonCount / 2 || quickCheckCount < cachedVisibleButtonCount / 2;
}
// 重新计算可见按钮数量(如果需要)
if (needRecalculateButtons)
{
int visibleButtonCount = 0;
foreach (ToolStripItem item in toolStrip.Items)
{
if (item.Visible && !(item is ToolStripSeparator))
{
visibleButtonCount++;
}
}
cachedVisibleButtonCount = visibleButtonCount;
}
// 简化计算逻辑
int buttonWidth = 40;
int buttonsPerRow = Math.Max(1, containerWidth / buttonWidth);
int requiredRows = Math.Min(3, (int)Math.Ceiling((double)cachedVisibleButtonCount / buttonsPerRow));
// 简化高度计算,使用固定值避免多次计算
int requiredHeight = requiredRows * 40;
requiredHeight = Math.Max(requiredHeight, 60);
// 只有当高度需要显著变化时才更新容差10像素
bool heightChanged = Math.Abs(toolStrip.MinimumSize.Height - requiredHeight) > 10;
if (heightChanged)
{
toolStrip.MinimumSize = new Size(toolStrip.MinimumSize.Width, requiredHeight);
// 设置TopToolStripPanel的最小高度
toolStripContainer.TopToolStripPanel.MinimumSize = new Size(toolStripContainer.TopToolStripPanel.MinimumSize.Width, requiredHeight);
}
// 只在实际有尺寸变化时执行布局并使用BeginInvoke延迟执行
if (widthChanged || heightChanged)
{
this.BeginInvoke((MethodInvoker)delegate
{
try
{
// 再次检查控件状态
if (!this.IsDisposed && !toolStrip.IsDisposed && !toolStripContainer.IsDisposed)
{
toolStrip.PerformLayout();
toolStripContainer.PerformLayout();
}
}
catch (Exception innerEx)
{
Console.WriteLine("执行布局失败: " + innerEx.Message);
}
});
}
}
}
catch (Exception ex)
{
Console.WriteLine("执行toolStrip尺寸调整失败: " + ex.Message);
}
}
/// <summary>
/// 根据颜色查找对应的温度值
/// </summary>

View File

@@ -120,4 +120,20 @@
<metadata name="toolStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>516, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="toolStripButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>