如何调整Label和Combox使两个文本在同一基线上?

问题描述 投票:0回答:1

你好

我想在运行时创建一个标签和一个组合框。

如何计算 Label.Top 相对于 ComboBox.Top 的值,使两个控件的文本位于一行?

它应该适用于不同的字体和边框样式。两个控件的顶部和高度值相同并不能解决问题。

提前致谢

c# vb.net winforms controls
1个回答
0
投票

文本基线计算需要使用 GetTextMetrics Api:

获取文本指标(gdi32)

GetTextMetrics 函数(wingdi.h)

我更习惯 VB.net :

Imports System.Runtime.InteropServices

Public Module Font_Metrics
    Public Structure FontMetrics
        Dim Ascent As Integer
        Dim Descent As Integer
        Dim Height As Integer
    End Structure

    Public Function GetMetrics(gfx As Graphics, fnt As Font) As FontMetrics
        Dim Hdc As IntPtr = gfx.GetHdc()
        Dim Hfont As IntPtr = fnt.ToHfont()
        Dim Metric As TEXTMETRIC
        Dim hFontDefault As IntPtr = SelectObject(Hdc, Hfont)
        GetTextMetrics(Hdc, Metric)
        SelectObject(Hdc, hFontDefault)
        DeleteObject(Hfont)
        gfx.ReleaseHdc(Hdc)

        Dim fm As FontMetrics
        fm.Ascent = Metric.tmAscent
        fm.Descent = Metric.tmDescent
        fm.Height = Metric.tmHeight
        Return fm
    End Function

    Private Structure TEXTMETRIC
        Dim tmHeight As Integer
        Dim tmAscent As Integer
        Dim tmDescent As Integer
        Dim tmInternalLeading As Integer
        Dim tmExternalLeading As Integer
        Dim tmAveCharWidth As Integer
        Dim tmMaxCharWidth As Integer
        Dim tmWeight As Integer
        Dim tmOverhang As Integer
        Dim tmDigitizedAspectX As Integer
        Dim tmDigitizedAspectY As Integer
        Dim tmFirstChar As Char
        Dim tmLastChar As Char
        Dim tmDefaultChar As Char
        Dim tmBreakChar As Char
        Dim tmItalic As Byte
        Dim tmUnderlined As Byte
        Dim tmStruckOut As Byte
        Dim tmPitchAndFamily As Byte
        Dim tmCharSet As Byte
    End Structure

    <DllImport("gdi32.dll", CharSet:=CharSet.Unicode)>
    Private Function SelectObject(hdc As IntPtr, hgdiobj As IntPtr) As IntPtr
    End Function

    <DllImport("gdi32.dll", CharSet:=CharSet.Unicode)>
    Private Function GetTextMetrics(hdc As IntPtr, <Out> ByRef lptm As TEXTMETRIC) As Boolean
    End Function

    <DllImport("gdi32.dll", CharSet:=CharSet.Unicode)>
    Private Function DeleteObject(hdc As IntPtr) As Boolean
    End Function

End Module

现在您可以计算组合框的文本基线并根据它对齐标签的顶部:

Dim combo_fm As FontMetrics = GetMetrics(CreateGraphics, ComboBox.Font)
Dim label_fm As FontMetrics = GetMetrics(CreateGraphics, Label.Font)
SuspendLayout()
Label.Left = ComboBox.Left - Label.Width 
Dim BaseLine_y As Integer = ComboBox.Top + (ComboBox.Height - ComboBox.ItemHeight) / 2 + combo_fm.Ascent
Label.Top = BaseLine_y - Label.Padding.Top - label_fm.Ascent
ResumeLayout()
© www.soinside.com 2019 - 2024. All rights reserved.