mirror of
https://gitee.com/yhuse/SunnyUI.git
synced 2025-12-06 15:59:45 +08:00
* UIStatusForm: 优化多行文本显示时的布局调整,支持任意行数的文本内容显示。
This commit is contained in:
@@ -18,9 +18,12 @@
|
||||
*
|
||||
* 2020-05-05: V2.2.5 增加文件
|
||||
* 2025-09-15: V3.8.8 进度提示框增加取消功能。#IA5Q0Z
|
||||
* 2025-11-29: V3.9.0 优化多行文本显示时的布局调整,支持任意行数的文本内容显示。
|
||||
******************************************************************************/
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Sunny.UI
|
||||
{
|
||||
@@ -119,10 +122,120 @@ namespace Sunny.UI
|
||||
else
|
||||
{
|
||||
labelDescription.Text = text;
|
||||
|
||||
// 动态调整布局以适应多行文本
|
||||
AdjustLayoutForMultiLineText();
|
||||
|
||||
labelDescription.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据文本内容动态调整布局,确保多行文本(任意行数)不被进度条遮住
|
||||
/// <para>实现方式:</para>
|
||||
/// <para>1. 计算文本实际需要的高度(考虑换行,支持任意行数)</para>
|
||||
/// <para>2. 动态调整 labelDescription 的高度以适应文本内容</para>
|
||||
/// <para>3. 动态调整 processBar 的位置,确保在 labelDescription 下方</para>
|
||||
/// <para>4. 自动增加窗体高度以容纳所有内容(无论多少行)</para>
|
||||
/// <para>5. 单行文本时恢复默认布局</para>
|
||||
/// </summary>
|
||||
private void AdjustLayoutForMultiLineText()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(labelDescription.Text))
|
||||
{
|
||||
// 空文本时恢复默认布局
|
||||
RestoreDefaultLayout();
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算文本实际需要的高度(考虑换行,支持任意行数)
|
||||
// labelDescription 的可用宽度:窗体宽度 - 左右边距(32*2)
|
||||
int labelWidth = this.ClientSize.Width - 32 * 2;
|
||||
if (labelWidth <= 0)
|
||||
{
|
||||
labelWidth = 409 - 32 * 2; // 使用默认宽度
|
||||
}
|
||||
|
||||
// 使用 TextRenderer.MeasureText 计算文本高度(更准确,支持换行和任意行数)
|
||||
// 使用 int.MaxValue 作为高度限制,确保能够测量所有行
|
||||
Size textSize = TextRenderer.MeasureText(
|
||||
labelDescription.Text,
|
||||
labelDescription.Font,
|
||||
new Size(labelWidth, int.MaxValue),
|
||||
TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl | TextFormatFlags.NoPrefix);
|
||||
|
||||
// 计算单行文本的高度(用于判断是否需要调整)
|
||||
int singleLineHeight = TextRenderer.MeasureText("A", labelDescription.Font).Height;
|
||||
|
||||
// 如果文本高度超过单行高度,说明是多行文本,需要调整布局
|
||||
if (textSize.Height > singleLineHeight)
|
||||
{
|
||||
// 计算 labelDescription 需要的实际高度(加上一些边距以确保显示完整)
|
||||
const int verticalPadding = 4; // 上下各2像素边距
|
||||
int labelHeight = textSize.Height + verticalPadding;
|
||||
|
||||
// 设置 labelDescription 的高度和宽度(取消 AutoSize 的固定高度限制)
|
||||
labelDescription.AutoSize = false;
|
||||
labelDescription.Width = labelWidth;
|
||||
labelDescription.Height = labelHeight;
|
||||
|
||||
// 调整 processBar 的位置,确保在 labelDescription 下方,留出适当间距
|
||||
const int spacing = 10; // labelDescription 和 processBar 之间的间距
|
||||
int newProcessBarTop = labelDescription.Top + labelHeight + spacing;
|
||||
|
||||
// 计算窗体需要的最小高度
|
||||
// 顶部边距(55) + labelDescription高度 + 间距 + processBar高度 + 底部边距
|
||||
const int topMargin = 55; // labelDescription 的 Top 位置
|
||||
const int bottomMargin = 20; // 底部边距
|
||||
int minFormHeight = topMargin + labelHeight + spacing + processBar.Height + bottomMargin;
|
||||
|
||||
// 确保窗体高度足够容纳所有内容
|
||||
if (minFormHeight > this.ClientSize.Height)
|
||||
{
|
||||
// 调整窗体高度
|
||||
this.ClientSize = new Size(this.ClientSize.Width, minFormHeight);
|
||||
}
|
||||
|
||||
// 调整 processBar 的位置
|
||||
processBar.Top = newProcessBarTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 单行文本,恢复默认布局
|
||||
RestoreDefaultLayout();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 如果调整失败,尝试恢复默认布局
|
||||
try
|
||||
{
|
||||
RestoreDefaultLayout();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 如果恢复也失败,保持当前状态
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 恢复默认布局(单行文本时的布局)
|
||||
/// </summary>
|
||||
private void RestoreDefaultLayout()
|
||||
{
|
||||
// 恢复 labelDescription 的 AutoSize
|
||||
labelDescription.AutoSize = true;
|
||||
|
||||
// 恢复 processBar 的默认位置
|
||||
processBar.Top = 91;
|
||||
|
||||
// 恢复窗体的默认高度
|
||||
this.ClientSize = new Size(473, 153);
|
||||
}
|
||||
|
||||
private delegate void StepItHandler(int step);
|
||||
|
||||
public void StepIt(int step = 1)
|
||||
|
||||
Reference in New Issue
Block a user