开发者

Can I tell which character was clicked on on a label?

开发者 https://www.devze.com 2023-02-26 21:35 出处:网络
I have a window开发者_如何学Pythons form with a label (or another control, i\'m open to options) that displays with foreign characters.

I have a window开发者_如何学Pythons form with a label (or another control, i'm open to options) that displays with foreign characters.

What I would like to do is that when a user clicks on one of the characters, it should open up a modal dialog with information about that character.

Is that possible for a label box to know which part of the label or which character was clicked?


I would use a FlowLayoutPanel and add each character separately as a LinkLabel.


You can get this information on your own, consuming one of MouseEvents on your label. Combine that with Graphics.MeasureString, MouseEventArgs.Location, keep in mind possible Control.Padding values and you might get close to what you need.

But this is probably not the best way to achieve your goal (look at all the stuff you need to go through to get this simple information). Personally, I'd go with Chris' answer.


Try This

    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;
            }
        }
    }


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]);
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消