* UINavMenu: 尝试减少刷新闪烁

This commit is contained in:
Sunny 2024-02-19 17:18:39 +08:00
parent 9eaf41849f
commit b78aed01f7

View File

@ -97,6 +97,15 @@ namespace Sunny.UI
selectedForeColor = UIStyles.Blue.NavMenuMenuSelectedColor; selectedForeColor = UIStyles.Blue.NavMenuMenuSelectedColor;
selectedHighColor = UIStyles.Blue.NavMenuMenuSelectedColor; selectedHighColor = UIStyles.Blue.NavMenuMenuSelectedColor;
_timer = new System.Windows.Forms.Timer();
_timer.Tick += Timer_Tick;
}
protected override void Dispose(bool disposing)
{
_timer.Dispose();
base.Dispose(disposing);
} }
private int scrollBarWidth = 0; private int scrollBarWidth = 0;
@ -638,146 +647,154 @@ namespace Sunny.UI
protected override void OnDrawNode(DrawTreeNodeEventArgs e) protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{ {
if (BorderStyle != BorderStyle.None) if (_resizing)
{ {
BorderStyle = BorderStyle.None; return;
} //e.DrawDefault = true;
SetScrollInfo();
CheckBoxes = false;
if (e.Node == null || (e.Node.Bounds.Width <= 0 && e.Node.Bounds.Height <= 0 && e.Node.Bounds.X <= 0 && e.Node.Bounds.Y <= 0))
{
e.DrawDefault = true;
} }
else else
{ {
int drawLeft = e.Node.Level * 16 + 16 + 4; if (BorderStyle != BorderStyle.None)
int imageLeft = drawLeft;
bool haveImage = false;
if (MenuHelper.GetSymbol(e.Node) > 0)
{ {
haveImage = true; BorderStyle = BorderStyle.None;
drawLeft += MenuHelper.GetSymbolSize(e.Node) + 6; }
SetScrollInfo();
CheckBoxes = false;
if (e.Node == null || (e.Node.Bounds.Width <= 0 && e.Node.Bounds.Height <= 0 && e.Node.Bounds.X <= 0 && e.Node.Bounds.Y <= 0))
{
e.DrawDefault = true;
} }
else else
{ {
if (ImageList != null && ImageList.Images.Count > 0 && e.Node.ImageIndex >= 0 && e.Node.ImageIndex < ImageList.Images.Count) int drawLeft = e.Node.Level * 16 + 16 + 4;
{ int imageLeft = drawLeft;
haveImage = true; bool haveImage = false;
drawLeft += ImageList.ImageSize.Width + 6;
}
}
if (e.Node == SelectedNode)
{
if (SelectedColorGradient)
{
using LinearGradientBrush br = new LinearGradientBrush(new Point(0, 0), new Point(0, e.Node.Bounds.Height), SelectedColor, SelectedColor2);
br.GammaCorrection = true;
e.Graphics.FillRectangle(br, new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(Width, e.Node.Bounds.Height)));
}
else
{
e.Graphics.FillRectangle(SelectedColor, new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(Width, e.Node.Bounds.Height)));
}
e.Graphics.DrawString(e.Node.Text, Font, SelectedForeColor, new Rectangle(drawLeft, e.Bounds.Y, e.Bounds.Width - drawLeft, ItemHeight), ContentAlignment.MiddleLeft);
e.Graphics.FillRectangle(SelectedHighColor, new Rectangle(0, e.Bounds.Y, 4, e.Bounds.Height));
}
else if (e.Node == CurrentNode && (e.State & TreeNodeStates.Hot) != 0)
{
e.Graphics.FillRectangle(HoverColor, new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(e.Node.Text, Font, ForeColor, new Rectangle(drawLeft, e.Bounds.Y, e.Bounds.Width - drawLeft, ItemHeight), ContentAlignment.MiddleLeft);
}
else
{
Color color = fillColor;
if (showSecondBackColor && e.Node.Level > 0)
{
color = SecondBackColor;
}
e.Graphics.FillRectangle(color, new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(e.Node.Text, Font, ForeColor, new Rectangle(drawLeft, e.Bounds.Y, e.Bounds.Width - drawLeft, ItemHeight), ContentAlignment.MiddleLeft);
}
//画右侧图标
Color rightSymbolColor = ForeColor;
if (e.Node == SelectedNode) rightSymbolColor = SelectedForeColor;
if (TreeNodeSymbols.ContainsKey(e.Node) && TreeNodeSymbols[e.Node].Count > 0)
{
int size = e.Node.Nodes.Count > 0 ? 24 : 0;
int left = Width - size - 6;
if (Bar.Visible) left -= Bar.Width;
int firstLeft = left - TreeNodeSymbols[e.Node].Count * 30;
for (int i = 0; i < TreeNodeSymbols[e.Node].Count; i++)
{
e.Graphics.DrawFontImage(TreeNodeSymbols[e.Node][i], 24, rightSymbolColor, new Rectangle(firstLeft + i * 30, e.Bounds.Top, 30, e.Bounds.Height));
}
}
//画图片
if (haveImage)
{
if (MenuHelper.GetSymbol(e.Node) > 0) if (MenuHelper.GetSymbol(e.Node) > 0)
{ {
Color color = e.Node == SelectedNode ? SelectedForeColor : ForeColor; haveImage = true;
Point offset = MenuHelper.GetSymbolOffset(e.Node); drawLeft += MenuHelper.GetSymbolSize(e.Node) + 6;
e.Graphics.DrawFontImage(MenuHelper.GetSymbol(e.Node), MenuHelper.GetSymbolSize(e.Node), color, new Rectangle(imageLeft, e.Bounds.Y, MenuHelper.GetSymbolSize(e.Node), e.Bounds.Height), offset.X, offset.Y, MenuHelper.GetSymbolRotate(e.Node));
} }
else else
{ {
if (e.Node == SelectedNode && e.Node.SelectedImageIndex >= 0 && e.Node.SelectedImageIndex < ImageList.Images.Count) if (ImageList != null && ImageList.Images.Count > 0 && e.Node.ImageIndex >= 0 && e.Node.ImageIndex < ImageList.Images.Count)
e.Graphics.DrawImage(ImageList.Images[e.Node.SelectedImageIndex], imageLeft, e.Bounds.Y + (e.Bounds.Height - ImageList.ImageSize.Height) / 2); {
else haveImage = true;
e.Graphics.DrawImage(ImageList.Images[e.Node.ImageIndex], imageLeft, e.Bounds.Y + (e.Bounds.Height - ImageList.ImageSize.Height) / 2); drawLeft += ImageList.ImageSize.Width + 6;
}
} }
}
//显示右侧下拉箭头 if (e.Node == SelectedNode)
if (ShowItemsArrow && e.Node.Nodes.Count > 0)
{
int size = 24;
int left = Width - size - 6;
if (Bar.Visible) left -= Bar.Width;
SizeF sf = e.Graphics.GetFontImageSize(61702, 24);
Rectangle rect = new Rectangle((int)(left + sf.Width / 2) - 12, e.Bounds.Y, 24, e.Bounds.Height);
e.Graphics.DrawFontImage(e.Node.IsExpanded ? 61702 : 61703, 24, ForeColor, rect);
}
//显示Tips圆圈
if (ShowTips && MenuHelper.GetTipsText(e.Node).IsValid())
{
using var TempFont = TipsFont.DPIScaleFont(TipsFont.Size);
Size tipsSize = TextRenderer.MeasureText(MenuHelper.GetTipsText(e.Node), TempFont);
int sfMax = Math.Max(tipsSize.Width, tipsSize.Height);
int tipsLeft = Width - sfMax - 16;
if (e.Node.Nodes.Count > 0) tipsLeft -= 24;
if (Bar.Visible) tipsLeft -= Bar.Width;
if (TreeNodeSymbols.ContainsKey(e.Node)) tipsLeft -= TreeNodeSymbols[e.Node].Count * 30;
int tipsTop = e.Bounds.Y + (ItemHeight - sfMax) / 2;
if (MenuHelper[e.Node] != null)
{ {
if (MenuHelper[e.Node].TipsCustom) if (SelectedColorGradient)
{ {
e.Graphics.FillEllipse(MenuHelper[e.Node].TipsBackColor, tipsLeft - 1, tipsTop, sfMax, sfMax); using LinearGradientBrush br = new LinearGradientBrush(new Point(0, 0), new Point(0, e.Node.Bounds.Height), SelectedColor, SelectedColor2);
e.Graphics.DrawString(MenuHelper.GetTipsText(e.Node), TempFont, MenuHelper[e.Node].TipsForeColor, new Rectangle(tipsLeft, tipsTop, sfMax, sfMax), ContentAlignment.MiddleCenter); br.GammaCorrection = true;
e.Graphics.FillRectangle(br, new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(Width, e.Node.Bounds.Height)));
} }
else else
{ {
e.Graphics.FillEllipse(TipsColor, tipsLeft - 1, tipsTop, sfMax, sfMax); e.Graphics.FillRectangle(SelectedColor, new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(MenuHelper.GetTipsText(e.Node), TempFont, TipsForeColor, new Rectangle(tipsLeft, tipsTop, sfMax, sfMax), ContentAlignment.MiddleCenter); }
e.Graphics.DrawString(e.Node.Text, Font, SelectedForeColor, new Rectangle(drawLeft, e.Bounds.Y, e.Bounds.Width - drawLeft, ItemHeight), ContentAlignment.MiddleLeft);
e.Graphics.FillRectangle(SelectedHighColor, new Rectangle(0, e.Bounds.Y, 4, e.Bounds.Height));
}
else if (e.Node == CurrentNode && (e.State & TreeNodeStates.Hot) != 0)
{
e.Graphics.FillRectangle(HoverColor, new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(e.Node.Text, Font, ForeColor, new Rectangle(drawLeft, e.Bounds.Y, e.Bounds.Width - drawLeft, ItemHeight), ContentAlignment.MiddleLeft);
}
else
{
Color color = fillColor;
if (showSecondBackColor && e.Node.Level > 0)
{
color = SecondBackColor;
}
e.Graphics.FillRectangle(color, new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(e.Node.Text, Font, ForeColor, new Rectangle(drawLeft, e.Bounds.Y, e.Bounds.Width - drawLeft, ItemHeight), ContentAlignment.MiddleLeft);
}
//画右侧图标
Color rightSymbolColor = ForeColor;
if (e.Node == SelectedNode) rightSymbolColor = SelectedForeColor;
if (TreeNodeSymbols.ContainsKey(e.Node) && TreeNodeSymbols[e.Node].Count > 0)
{
int size = e.Node.Nodes.Count > 0 ? 24 : 0;
int left = Width - size - 6;
if (Bar.Visible) left -= Bar.Width;
int firstLeft = left - TreeNodeSymbols[e.Node].Count * 30;
for (int i = 0; i < TreeNodeSymbols[e.Node].Count; i++)
{
e.Graphics.DrawFontImage(TreeNodeSymbols[e.Node][i], 24, rightSymbolColor, new Rectangle(firstLeft + i * 30, e.Bounds.Top, 30, e.Bounds.Height));
}
}
//画图片
if (haveImage)
{
if (MenuHelper.GetSymbol(e.Node) > 0)
{
Color color = e.Node == SelectedNode ? SelectedForeColor : ForeColor;
Point offset = MenuHelper.GetSymbolOffset(e.Node);
e.Graphics.DrawFontImage(MenuHelper.GetSymbol(e.Node), MenuHelper.GetSymbolSize(e.Node), color, new Rectangle(imageLeft, e.Bounds.Y, MenuHelper.GetSymbolSize(e.Node), e.Bounds.Height), offset.X, offset.Y, MenuHelper.GetSymbolRotate(e.Node));
}
else
{
if (e.Node == SelectedNode && e.Node.SelectedImageIndex >= 0 && e.Node.SelectedImageIndex < ImageList.Images.Count)
e.Graphics.DrawImage(ImageList.Images[e.Node.SelectedImageIndex], imageLeft, e.Bounds.Y + (e.Bounds.Height - ImageList.ImageSize.Height) / 2);
else
e.Graphics.DrawImage(ImageList.Images[e.Node.ImageIndex], imageLeft, e.Bounds.Y + (e.Bounds.Height - ImageList.ImageSize.Height) / 2);
}
}
//显示右侧下拉箭头
if (ShowItemsArrow && e.Node.Nodes.Count > 0)
{
int size = 24;
int left = Width - size - 6;
if (Bar.Visible) left -= Bar.Width;
SizeF sf = e.Graphics.GetFontImageSize(61702, 24);
Rectangle rect = new Rectangle((int)(left + sf.Width / 2) - 12, e.Bounds.Y, 24, e.Bounds.Height);
e.Graphics.DrawFontImage(e.Node.IsExpanded ? 61702 : 61703, 24, ForeColor, rect);
}
//显示Tips圆圈
if (ShowTips && MenuHelper.GetTipsText(e.Node).IsValid())
{
using var TempFont = TipsFont.DPIScaleFont(TipsFont.Size);
Size tipsSize = TextRenderer.MeasureText(MenuHelper.GetTipsText(e.Node), TempFont);
int sfMax = Math.Max(tipsSize.Width, tipsSize.Height);
int tipsLeft = Width - sfMax - 16;
if (e.Node.Nodes.Count > 0) tipsLeft -= 24;
if (Bar.Visible) tipsLeft -= Bar.Width;
if (TreeNodeSymbols.ContainsKey(e.Node)) tipsLeft -= TreeNodeSymbols[e.Node].Count * 30;
int tipsTop = e.Bounds.Y + (ItemHeight - sfMax) / 2;
if (MenuHelper[e.Node] != null)
{
if (MenuHelper[e.Node].TipsCustom)
{
e.Graphics.FillEllipse(MenuHelper[e.Node].TipsBackColor, tipsLeft - 1, tipsTop, sfMax, sfMax);
e.Graphics.DrawString(MenuHelper.GetTipsText(e.Node), TempFont, MenuHelper[e.Node].TipsForeColor, new Rectangle(tipsLeft, tipsTop, sfMax, sfMax), ContentAlignment.MiddleCenter);
}
else
{
e.Graphics.FillEllipse(TipsColor, tipsLeft - 1, tipsTop, sfMax, sfMax);
e.Graphics.DrawString(MenuHelper.GetTipsText(e.Node), TempFont, TipsForeColor, new Rectangle(tipsLeft, tipsTop, sfMax, sfMax), ContentAlignment.MiddleCenter);
}
} }
} }
} }
}
base.OnDrawNode(e); base.OnDrawNode(e);
}
} }
private Color tipsColor = Color.Red; private Color tipsColor = Color.Red;
@ -1220,5 +1237,38 @@ namespace Sunny.UI
public delegate void OnNodeRightSymbolClick(object sender, TreeNode node, int index, int symbol); public delegate void OnNodeRightSymbolClick(object sender, TreeNode node, int index, int symbol);
public event OnNodeRightSymbolClick NodeRightSymbolClick; public event OnNodeRightSymbolClick NodeRightSymbolClick;
protected override void OnResize(EventArgs e)
{
//_resizing = true;
//_previousClientSize = ClientSize;
// 启动计时器
//_timer.Start();
}
private bool _resizing;
private System.Windows.Forms.Timer _timer;
private Size _previousClientSize;
private void Timer_Tick(object sender, EventArgs e)
{
// 检查控件的大小是否与前一次检查时相同
if (ClientSize == _previousClientSize)
{
// 控件已停止调整大小
_resizing = false;
// 清除计时器
_timer.Stop();
// 刷新 TreeView
Invalidate();
}
else
{
// 更新前一次检查时的大小
_previousClientSize = ClientSize;
}
}
} }
} }