views:

108

answers:

3

I wish to display a list of letters from a through z on a form. Each letter needs to be clickable with that value being passed as a click argument. Aside from creating 26 letters and using the click event of each letter does anyone know of a quick way to do this? I know how to load dynamic controls etc and how to do it that way. Just wondering if anyone knew of a clever way to do this?

Cheers

+1  A: 
Stefan
+1 for going the extra mile and doing the position math. :) FlowLayoutPanel might not always be an option.
Tomalak
I like the FlowLayoutPanel, but when writing short examples I like to have as few controls involved as possible. ;)
Stefan
+1  A: 

You can use a FlowLayoutPanel and a loop like this:

private void button1_Click(object sender, EventArgs e)
{
  flowLayoutPanel1.FlowDirection = FlowDirection.LeftToRight;
  flowLayoutPanel1.AutoSize = true;
  flowLayoutPanel1.WrapContents = false; //or true, whichever you like
  flowLayoutPanel1.Controls.Clear();

  for (char c = 'A'; c <= 'Z'; c++)
  {
    Label letter = new Label();
    letter.Text = c.ToString();
    letter.AutoSize = true;
    letter.Click += new EventHandler(letter_Click);
    flowLayoutPanel1.Controls.Add(letter);

  }
}

private void letter_Click(object sender, EventArgs e)
{
  MessageBox.Show("You clicked on " + ((Label)sender).Text);
}
Tomalak
Just what I needed, cheers for that!
anonym0use
A: 

Draw a string on a control, then match mouse clicks to the character positions on the form. It's actually easier than it sounds (this is adapted from standard documentation on MeasureCharacterRanges, which simplifies the entrire task). The example is drawn on a form, it would be simple enough to make this into a user control.

In this example, clicking on a letter will cause a messagebox to appear, telling you which letter you just clicked.

Hope it helps.

P.S. Please forgive "magic numbers" e.g. "knowning" there'll be 25 items in the array, this is just a sample after all :)

Public Class Form1

    Const LETTERS As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    Private letterRects(25) As System.Drawing.RectangleF
    Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
        Dim index As Integer = -1
        Dim mouseP As Point = Me.PointToClient(MousePosition)
        For i As Integer = 0 To 25
            If letterRects(i).Contains(mouseP.X, mouseP.Y) Then
                index = i
                Exit For
            End If
        Next
        If index >= 0 Then
            MessageBox.Show("Letter = " + LETTERS(index).ToString())
        End If
    End Sub

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        ' Set up string.
        Dim stringFont As New Font("Times New Roman", 16.0F)

        ' Set character ranges 
        Dim characterRanges(26) As CharacterRange
        For i As Integer = 0 To 25
            characterRanges(i) = New CharacterRange(i, 1)
        Next

        ' Create rectangle for layout, measurements below are not exact, these are "magic numbers"
        Dim x As Single = 50.0F
        Dim y As Single = 50.0F
        Dim width As Single = 400.0F 
        Dim height As Single = 40.0F
        Dim layoutRect As New RectangleF(x, y, width, height)

        ' Set string format.
        Dim stringFormat As New StringFormat
        stringFormat.FormatFlags = StringFormatFlags.FitBlackBox
        stringFormat.SetMeasurableCharacterRanges(characterRanges)

        ' Draw string to screen.
        e.Graphics.DrawString(letters, stringFont, Brushes.Black, _
        x, y, stringFormat)
        Dim stringRegions() As [Region]
        ' Measure two ranges in string.
        stringRegions = e.Graphics.MeasureCharacterRanges(letters, _
        stringFont, layoutRect, stringFormat)
        For i As Integer = 0 To 25
            letterRects(i) = stringRegions(i).GetBounds(e.Graphics)
        Next
    End Sub
End Class
Binary Worrier
What about users with their "Large Fonts" setting enabled, or other modifications to the Windows configuration, or a missing font - does this work for them as well?
Tomalak
To be honest I have no idea, and will leave figuring this out as an exercise for the reader :)
Binary Worrier
This was a rhetorical question anyway. :-)
Tomalak