我有一個帶有標籤(或另一個控件,我打開選項)的窗體顯示外國字符。我可以告訴標籤上點擊了哪個字符嗎?
我想要做的是,當用戶點擊其中一個字符時,它應該打開一個有關該字符信息的模式對話框。
標籤框可以知道標籤的哪個部分或哪個字符被點擊了嗎?
我有一個帶有標籤(或另一個控件,我打開選項)的窗體顯示外國字符。我可以告訴標籤上點擊了哪個字符嗎?
我想要做的是,當用戶點擊其中一個字符時,它應該打開一個有關該字符信息的模式對話框。
標籤框可以知道標籤的哪個部分或哪個字符被點擊了嗎?
我會使用FlowLayoutPanel
並將每個字符單獨添加爲LinkLabel
。
我們應該記住,使用這個解決方案,這會忽略字體中的字距信息,並且每個字符都單獨顯示,這可能會(非常)慢一點,並且會佔用更多的內存。 – 2011-04-18 18:59:53
@Ed Marty我同意你的看法 – 2011-04-21 01:09:03
您可以自行獲取此信息,並在您的標籤上使用MouseEvent之一。結合Graphics.MeasureString,MouseEventArgs.Location,請記住可能的Control.Padding值,並且您可能會接近您的需要。
但是,這可能不是達到目標的最佳方式(查看所有需要獲取此簡單信息的內容)。就我個人而言,我會去Chris' answer。
嘗試這個
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]);
}
}
不容易* *。更好的解決方案是將每個字符顯示在自己的標籤中。 – 2011-04-16 11:26:04