winforms 我能知道标签上的哪个字符被点击了吗?

5uzkadbs  于 2023-03-31  发布在  其他
关注(0)|答案(5)|浏览(112)

我有一个带有标签的windows窗体(或其他控件,我可以选择),该窗体显示有外来字符。
我想做的是,当用户单击其中一个字符时,它应该打开一个包含该字符信息的模态对话框。
标签框是否可能知道单击了标签的哪个部分或哪个字符?

rqdpfwrv

rqdpfwrv1#

我将使用FlowLayoutPanel并将每个字符单独添加为LinkLabel

o2rvlv0m

o2rvlv0m2#

您可以自己获取此信息,使用标签上的MouseEvents之一。将其与Graphics.MeasureStringMouseEventArgs.Location结合,记住可能的Control.Padding值,您可能会接近您所需要的。
但这可能不是实现目标的最佳方式(看看你需要经历的所有事情才能得到这个简单的信息)。

xcitsw88

xcitsw883#

试试这个

private void label_MouseClick(object sender, MouseEventArgs e)
    {
        Label lbl = sender as Label;
        string s = "";
        foreach (char c in lbl.Text)
        {
            s += c.ToString();
            var x = TextRenderer.MeasureText(s, lbl.Font, lbl.Size, TextFormatFlags.TextBoxControl);
            Rectangle txtRec = new Rectangle(-lbl.Margin.Left, -lbl.Margin.Top, x.Width, x.Height);
            if (txtRec.Contains(e.Location))
            {
                MessageBox.Show("You clicked " + c.ToString());
                break;
            }
        }
    }
idv4meu8

idv4meu84#

public partial class Form1 : Form
{
    CharInfo[] charinfo;
    int selectedChar = -1;

    public Form1()
    {
        InitializeComponent();
        charinfo = CharInfo.MeasureCharacters(label1);
        label1.BackColor = Color.Transparent;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (selectedChar >= 0)
        {
            Rectangle highlightRect = Rectangle.Round(charinfo[selectedChar].charBounds);
            highlightRect.Offset(label1.Location);
            e.Graphics.FillRectangle(SystemBrushes.Highlight, highlightRect);
        }
        base.OnPaint(e);
    }

    private void label1_MouseMove(object sender, MouseEventArgs e)
    {
        for (int i = 0; i < charinfo.Length; i++)
        {
            if (charinfo[i].charBounds.Contains(e.Location))
            {
                if (selectedChar != i)
                {
                    selectedChar = i;
                    Invalidate(label1.Bounds);
                }
                break;
            }
        }
    }

    class CharInfo
    {
        public RectangleF charBounds;
        public int charIndex;
        CharInfo(RectangleF rect, int index)
        {
            charBounds = rect;
            charIndex = index;
        }

        public static CharInfo[] MeasureCharacters(Label lbl)
        {
            using (Graphics g = Graphics.FromHwnd(lbl.Handle))
            {
                StringFormat sf = new StringFormat();
                List<CharInfo> result = new List<CharInfo>();
                for (int curIndex = 0; lbl.Text.Length > curIndex; curIndex += 32)
                {
                    int nextGroup = Math.Min(lbl.Text.Length, curIndex + 32);
                    CharacterRange[] ranges = new CharacterRange[nextGroup - curIndex];
                    for (int i = curIndex; i < nextGroup; i++)
                        ranges[i % 32] = new CharacterRange(i, 1);
                    sf.SetMeasurableCharacterRanges(ranges);
                    Region[] charRegions = g.MeasureCharacterRanges(lbl.Text, lbl.Font, lbl.ClientRectangle, sf);
                    for (int i = 0; i < charRegions.Length; i++)
                        result.Add(new CharInfo(charRegions[i].GetBounds(g), i));
                    foreach (Region r in charRegions)
                        r.Dispose();
                }
                sf.Dispose();
                return result.ToArray();
            }
        }
    }

    private void label1_MouseClick(object sender, MouseEventArgs e)
    {
        if (selectedChar >= 0)
            MessageBox.Show("You clicked " + label1.Text[selectedChar]);
    }
}
b4wnujal

b4wnujal5#

如果有人要使用DOTNET MAUI,那么可以在这个Github Repo上找到一个完整的Windows示例应用程序:https://github.com/rafaelduluc/DOTNETMAUI-CHATGPT,将为您提供解决方案和“知识如何”-基础,让你做更多的事情。希望它是有帮助的。

相关问题