微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

根据标题栏中的文本设置表单的宽度 替代解决方案 - 为标题栏设置工具提示

如何解决根据标题栏中的文本设置表单的宽度 替代解决方案 - 为标题栏设置工具提示

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

有什么我可以做的吗?

解决方法

您可以获取系统菜单的宽度、标题文本的宽度和控制框按钮的宽度,然后计算首选宽度并检查当前宽度是否小于首选宽度,然后更改for的宽度到首选宽度。

auto-size based on title text width

要获取有关标题栏元素的信息,您可以向窗口发送一条 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,Bottom);
    }
    public enum TitleBarRectangles
    {
        TitleBar = 0,Reserved = 1,MinimizeButton = 2,MaximizeButton = 3,HelpButton = 4,CloseButton = 5
    }
}

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

form in design mode

但在运行时:

auto-size based on title text width

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

作为替代解决方案,您可以add a ToolTip to the Form titlebar

Tooltip for titlebar

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。