繁体   English   中英

根据标题栏中的文本设置表单的宽度

[英]Setting form's width according to text in title bar

当(或之后)我调用我的Form.Show()方法时,我想根据标题栏中的字符串( Form.Text )设置表单的宽度(或最小宽度),因为此文本会根据用户的选择。 表单宽度最终应该是完美的数量,这样标题栏文本就不会被截断并以“...”结尾。
目前,我只是将MinimumSize属性设置为适合所有选择的值,但自动调整大小看起来会稍微整洁一些。 我的问题是标题栏文本没有任何属性来获取其实际宽度。 AutoSize也仅根据表单中的控件更改大小。

有什么我可以做的吗?

你可以得到系统菜单的宽度,标题文本的宽度和控制框按钮的宽度,然后计算首选宽度并检查当前宽度是否小于首选宽度,然后将for的宽度更改为首选宽度.

根据标题文本宽度自动调整大小

要获取有关标题栏元素的信息,您可以向 window 发送WM_GETTITLEBARINFOEX消息,并获取包含有关标题栏信息的TITLEBARINFOEX结构的实例。

您还可以使用SystemInformation.CaptionButtonSize获取控制按钮大小和SystemInformation.SmallIconSize获取系统菜单图标大小并添加一些额外的填充空间。

例子

您可以像这样覆盖表单的 OnShown 方法:

protected override void OnShown(EventArgs e)
{
    base.OnShown(e);

    var info = NativeMethods.GetTitleBarInfo(this.Handle);
    var systemMenuWidth = info.rcTitleBar.Left - this.Left;
    var controlBoxWidth =
        info.rgrect[(int)NativeMethods.TitleBarRectangles.CloseButton].Right -
        info.rgrect[(int)NativeMethods.TitleBarRectangles.MinimizeButton].Left;
    var titleWidth = TextRenderer.MeasureText(this.Text, SystemFonts.CaptionFont).Width;

    //var preferred = titleWidth + systemMenuWidth + controlBoxWidth + 16;
    //if (this.Width < preferred)
    //   this.Width = preferred;

    var preferred = titleWidth + systemMenuWidth + controlBoxWidth;
    if (this.Width < preferred)
        this.ClientSize = new Size(preferred, this.ClientSize.Height);
}

这里是 NativeMethods:

using System;
using System.Drawing;
using System.Runtime.InteropServices;

public static class NativeMethods
{
    public const int WM_GETTITLEBARINFOEX = 0x033F;
    public static TITLEBARINFOEX GetTitleBarInfo(IntPtr hwnd)
    {
        var info = new TITLEBARINFOEX()
        { cbSize = (uint)Marshal.SizeOf(typeof(TITLEBARINFOEX)) };
        SendMessage(hwnd, WM_GETTITLEBARINFOEX, IntPtr.Zero, ref info);
        return info;
    }
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern IntPtr SendMessage(
        IntPtr hWnd, int Msg, IntPtr wParam, ref TITLEBARINFOEX lParam);

    [StructLayout(LayoutKind.Sequential)]
    public struct TITLEBARINFOEX
    {
        public const int CCHILDREN_TITLEBAR = 5;
        public uint cbSize;
        public RECT rcTitleBar;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = CCHILDREN_TITLEBAR + 1)]
        public uint[] rgstate;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = CCHILDREN_TITLEBAR + 1)]
        public RECT[] rgrect;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left, Top, Right, Bottom;
        public Rectangle ToRectangle() => Rectangle.FromLTRB(Left, Top, Right, Bottom);
    }
    public enum TitleBarRectangles
    {
        TitleBar = 0,
        Reserved = 1,
        MinimizeButton = 2,
        MaximizeButton = 3,
        HelpButton = 4,
        CloseButton = 5
    }
}

所以在设计师中有这样的形式:

设计模式下的表格

但在运行时:

根据标题文本宽度自动调整大小

替代解决方案 - 为标题栏设置工具提示

作为替代解决方案,您可以将 ToolTip 添加到表单标题栏

标题栏的工具提示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM