Creating a strip of selectable letters for a form - windows

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

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

This is the "dynamic way" I would do it in. I know you asked for other clever ways to do it in but I think this is the most accepted way to do it.
This will produce those buttons and add a click-handler that takes the button as sender. It will also see to that the buttons location wraps if outside of the forms width.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim ButtonSize As New Size(20, 20)
Dim ButtonLocation As New Point(10, 20)
For p As Integer = Asc("A") To Asc("Z")
Dim newButton As New Button
If ButtonLocation.X + ButtonSize.Width > Me.Width Then
ButtonLocation.X = 10
ButtonLocation.Y += ButtonSize.Height
End If
newButton.Size = ButtonSize
newButton.Location = ButtonLocation
newButton.Text = Chr(p)
ButtonLocation.X += newButton.Width + 5
AddHandler newButton.Click, AddressOf ButtonClicked
Me.Controls.Add(newButton)
Next
End Sub
Sub ButtonClicked(ByVal sender As Object, ByVal e As System.EventArgs)
MsgBox(CType(sender, Button).Text)
End Sub
End Class
alt text http://img235.imageshack.us/img235/2267/testoa6.jpg

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

Related

How to display selected features in ArcGIS Identify Dialog using Visual Studio 2010/ArcObjects?

I'm brand new to ArcObjects SDKs and am struggling. I have a Python Add-in performing a query to select records (works great)and now trying to call the identify dialog via an .NET addin button that displays the identify dialog box to show attributes of the selected records. Below is the code I have at this point. I currently have the identify dialog displaying, but no records appearing. I know I need to input the selected records somewhere....but not sure where. Any thoughts would be appreciated. (I'm using Visual Studio/Microsoft Visual Basic 2010 and ArcGIS 10.2.1)
Imports ESRI.ArcGIS.ArcMapUI
Imports ESRI.ArcGIS.Carto
Public Class Identify_Button
Inherits ESRI.ArcGIS.Desktop.AddIns.Button
Dim pMxDoc As IMxDocument
Dim activeView As IMap
Public Sub DoIdentify(ByVal activeView As ESRI.ArcGIS.Carto.IActiveView, ByVal x As System.Int32, ByVal y As System.Int32)
pMxDoc = My.ArcMap.Application.Document
activeView = pMxDoc.FocusMap
If activeView Is Nothing Then
Return
End If
Dim map As ESRI.ArcGIS.Carto.IMap = activeView.FocusMap
Dim identifyDialog As ESRI.ArcGIS.CartoUI.IIdentifyDialog = New ESRI.ArcGIS.CartoUI.IdentifyDialogClass
identifyDialog.Map = map
'Clear the dialog on each mouse click
identifyDialog.ClearLayers()
Dim screenDisplay As ESRI.ArcGIS.Display.IScreenDisplay = activeView.ScreenDisplay
Dim display As ESRI.ArcGIS.Display.IDisplay = screenDisplay ' Implicit Cast
identifyDialog.Display = display
Dim identifyDialogProps As ESRI.ArcGIS.CartoUI.IIdentifyDialogProps = CType(identifyDialog, ESRI.ArcGIS.CartoUI.IIdentifyDialogProps) ' Explicit Cast
Dim enumLayer As ESRI.ArcGIS.Carto.IEnumLayer = identifyDialogProps.Layers
enumLayer.Reset()
Dim layer As ESRI.ArcGIS.Carto.ILayer = enumLayer.Next
Do While Not (layer Is Nothing)
identifyDialog.AddLayerIdentifyPoint(layer, x, y)
layer = enumLayer.Next()
Loop
identifyDialog.Show()
End Sub
Public Sub New()
End Sub
Protected Overrides Sub OnClick()
DoIdentify(activeView, 300, 100)
End Sub
Protected Overrides Sub OnUpdate()
Enabled = My.ArcMap.Application IsNot Nothing
End Sub
End Class
Give the code below a try. This is executed from the OnClick event from an ArcMap command button that Inherits from BaseCommand. It displays the selected features in the map in the identifyDialog just as you were needing it to except I used AddLayerIdentifyOID() instead of AddLayerIdentifyPoint() although both should work.
Public Overrides Sub OnClick()
'VBTest.OnClick implementation
Try
Dim mxDoc As IMxDocument = m_application.Document
Dim map As ESRI.ArcGIS.Carto.IMap = mxDoc.FocusMap
Dim layer As ESRI.ArcGIS.Carto.ILayer
Dim flayer As ESRI.ArcGIS.Carto.IFeatureLayer
Dim featSelection As ESRI.ArcGIS.Carto.MapSelection = map.FeatureSelection
Dim feat As ESRI.ArcGIS.Geodatabase.IFeature = featSelection.Next()
Dim count As Int16 = 0
While feat IsNot Nothing
count += 1 ' flag for clearing layers
flayer = New ESRI.ArcGIS.Carto.FeatureLayer()
flayer.FeatureClass = feat.Class
layer = flayer
DoIdentify(layer, feat.OID, (count = 1))
feat = featSelection.Next()
End While
Catch ex As Exception
' handle error
MsgBox("Error: " + ex.Message)
End Try
End Sub
Private Sub DoIdentify(ByVal layer As ESRI.ArcGIS.Carto.ILayer, ByVal OID As Int32, Optional ByVal clearLayers As Boolean = True)
If layer Is Nothing Or OID <= 0 Then
Return
End If
Dim pMxDoc As IMxDocument = m_application.Document
Dim activeView As ESRI.ArcGIS.Carto.IActiveView = pMxDoc.ActiveView
Dim map As ESRI.ArcGIS.Carto.IMap = activeView.FocusMap
Dim identifyDialog As ESRI.ArcGIS.CartoUI.IIdentifyDialog = New ESRI.ArcGIS.CartoUI.IdentifyDialogClass()
Dim screenDisplay As ESRI.ArcGIS.Display.IScreenDisplay = activeView.ScreenDisplay
Dim display As ESRI.ArcGIS.Display.IDisplay = screenDisplay
identifyDialog.Map = map ' REQUIRED
identifyDialog.Display = display ' REQUIRED
' Clear the dialog
If clearLayers Then
identifyDialog.ClearLayers()
End If
' Add our selected feature to the dialog
identifyDialog.AddLayerIdentifyOID(layer, OID)
' Show the dialog
identifyDialog.Show()
End Sub

Mouse Move Handle on a ListBox

I have a ListBox on which I want to handle the mousemove event; And for that reason I'm using the following code
Private Sub AreaLB_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles AreaLB.MouseMove
Dim ListMousePosition As Point = AreaLB.PointToClient(Me.MousePosition)
Dim itemIndex As Integer = AreaLB.IndexFromPoint(ListMousePosition)
Dim AreaToolTip As ToolTip = ToolTip1
Dim myLB As ListBox = AreaLB
AreaToolTip.Active = True
Dim g As Graphics = AreaLB.CreateGraphics()
If itemIndex > -1 Then
Dim s As String = myLB.Items(itemIndex)
If g.MeasureString(s, myLB.Font).Width > myLB.ClientRectangle.Width Then
AreaToolTip.SetToolTip(myLB, s)
Else
AreaToolTip.SetToolTip(myLB, "")
End If
g.Dispose()
End If
End Sub
My problem is... When I'm not moving the mouse this procedure runs always when the
g.MeasureString(s, myLB.Font).Width > myLB.ClientRectangle.Width
Why that happens and how can I avoid it.
What you can do is only set the ToolTip if it isn't already the value you want it to be:
Private Sub AreaLB_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles AreaLB.MouseMove
ToolTip1.Active = True
Dim itemIndex As Integer = AreaLB.IndexFromPoint(e.X, e.Y)
If itemIndex > -1 Then
Using g As Graphics = AreaLB.CreateGraphics()
Dim s As String = AreaLB.Items(itemIndex)
If g.MeasureString(s, AreaLB.Font).Width > AreaLB.ClientRectangle.Width Then
If ToolTip1.GetToolTip(AreaLB) <> s Then
ToolTip1.Show(s, AreaLB)
End If
Else
ToolTip1.Show("", AreaLB)
End If
End Using
End If
End Sub

Visual Studio - Perform a event action for "X" number of checkboxes?

I have 20 checkboxes.
This is the event for the checkbox nÂș1 :
Public Sub C1CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles C1CheckBox1.CheckedChanged
If C1CheckBox1.Checked = True Then My.Settings.box1_selected = "Y" Else My.Settings.box1_selected = "N"
Dim checkedpath1 = C1CheckBox1.Text
End Sub
I know I can add all the checkboxes in the "handles", but my number of checkboxes is undetermined and this is what I want to do:
(Pseudocode)
Public Sub ALL_THE_CHECKBOXES_CheckedChanged(sender As Object, e As EventArgs) Handles ALL_THE_CHECKBOXES.CheckedChanged
If ANY_CHECKBOX.Checked = True
My.Settings.boxNUMBER_OF_THIS_SELECTED_CHECKBOX_selected = "Y"
Else
My.Settings.boxNUMBER_OF_THIS_SELECTED_CHECKBOX_selected = "N"
End If
Dim checkedpathNUMBER_OF_THIS_SELECTED_CHECKBOX = C1CheckBoxNUMBER_OF_THIS_SELECTED_CHECKBOX.Text
End Sub
I need to generate a event that handles an undetermined number of checkboxes,
I need to do the same action if any of the checkboxes is selected, but only in that selected checkbox.
Basically I want to remember in the settings which checkboxes was selected and which not...
UPDATE:
At form load I create ALL the form checkboxes with this code:
Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim List As Integer = 0
Dim posy As Integer = 10
filesystem = CreateObject("Scripting.FileSystemObject")
ThisDir = filesystem.GetFolder(My.Settings.folderpath)
For Each folder In ThisDir.Subfolders
List = List + 1
posy = posy + 20
Dim newCheckBox As New CheckBox()
Panel1.Controls.Add(newCheckBox)
newCheckBox.Name = "checkbox" & List.ToString()
newCheckBox.Text = folder.name
newCheckBox.Location = New Point(10, posy)
Next
End Sub
That creates a checkboxes named "checkbox1", "checkbox2", "checkbox3", etc...
All checkboxes are inside of another control. might be form, panel whatever. So you can cycle through these checkboxes and manually assign the eventhandler for each checkbox you find
Revised Sample code:
You need a setting of type StringCollection named MyCBs - or you can use whatever name you like, just make the necessary changes to the code.
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
My.Settings.Save()
End Sub
Private Sub AnyCB_CheckedChanged(sender As Object, e As EventArgs)
Dim cb = DirectCast(sender, CheckBox)
If cb.Checked AndAlso Not My.Settings.MyCBs.Contains(cb.Name) Then
My.Settings.MyCBs.Add(cb.Name)
ElseIf Not cb.Checked AndAlso My.Settings.MyCBs.Contains(cb.Name) Then
My.Settings.MyCBs.Remove(cb.Name)
End If
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
If My.Settings.MyCBs Is Nothing Then My.Settings.MyCBs = New Collections.Specialized.StringCollection
For Each s In My.Settings.MyCBs
DirectCast(Me.Controls(s), CheckBox).Checked = True
Next
For Each cb In Me.Controls.OfType(Of CheckBox)()
AddHandler cb.CheckedChanged, AddressOf AnyCB_CheckedChanged
Next
End Sub
This sample saves the checked status of the checkboxes in my.settings inside a StringCollection. If a CB is checked it's name is added to the collection, if it's unchecked, it's name is removed. This means on startup you can simply check which CB name is in the collection and sets its checked stats to true. Finally you use AddHandler to execute the code for any CB contained in your Form.
Note that there's NO error handling inside the code, which means that this is your part ...

How to change the location of a picture box in VB 2010 using the arrow or wasd keys?

I only have access to the internet at school, so the filters get in the way of any real research. I'm currently coding an rpg for a school project but it's difficult to get the avatar to move on a map. Here's my pathetic code so far:
Public Class Map1
Private Sub USER_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
User.Top = User.Top - 1
End Sub
Private Sub USER_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
User.Top = User.Bottom + 1
'User.Location.X = 200
End Sub
End Class
I have the following problems with it:
User.location.x = 200 had syntax errors when I deleted the x and when I didn't.
The player also had to continually press the keys to move.
both I do not know how to correct.
Any help at all is greatly appreciated as it's for my final grade.
You can put it in a timer_tick to loop over it, that is what I do.
And the correct version of User.Location.X = 200 is:
User.location = new point(200, User.location.y)
nvm found the solution.
Here it is for anyone else how might need the code in the future.
Private Sub Map_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = Keys.Up Then
User.Location = New Point(User.Location.X, User.Location.Y - 5)
ElseIf e.KeyCode = Keys.Down Then
User.Location = New Point(User.Location.X, User.Location.Y + 5)
ElseIf e.KeyCode = Keys.Left Then
User.Location = New Point(User.Location.X - 5, User.Location.Y)
ElseIf e.KeyCode = Keys.Right Then
User.Location = New Point(User.Location.X + 5, User.Location.Y)
End If
Module
Public Sub MovePictureBox(ByRef PictureBox As PictureBox)
Tiempo.Tag = PictureBox
AddHandler PictureBox.Parent.KeyDown, AddressOf Parent_KeyDown
AddHandler PictureBox.Parent.KeyUp, AddressOf Parent_KeyUp
AddHandler CType(PictureBox.Parent, Form).Load, AddressOf Parent_Load
End Sub
Private Up, Down, Left, Right As Boolean
WithEvents Tiempo As New Timer() With {.Interval = 1}
Private Sub Tiempo_Tick() Handles Tiempo.Tick
If Up Then Tiempo.Tag.Top -= 2
If Down Then Tiempo.Tag.Top += 2
If Left Then Tiempo.Tag.Left -= 2
If Right Then Tiempo.Tag.Left += 2
End Sub
Private Sub Parent_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
If e.KeyCode = Keys.Up Then Up = True
If e.KeyCode = Keys.Down Then Down = True
If e.KeyCode = Keys.Left Then Left = True
If e.KeyCode = Keys.Right Then Right = True
Tiempo.Enabled = True
End Sub
Private Sub Parent_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
Tiempo.Enabled = False
Up = False : Down = False : Right = False : Left = False
End Sub
Private Sub Parent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
sender.KeyPreview = True
End Sub
End Module

SelectedIndex of a DataGridViewComboBoxCell? VB.NET

How do I set SelectedIndex of a DataGridViewComboBoxCell?
The code fill the combobox with items, but I need to select one of them
My Code:
Dim cListItems As New System.Collections.Generic.List(Of Combobox_values)
If ds.Tables("items_prices").Rows(0).Item("item_selldozen") > 0 Then
Dim item_selldozen As String = ds.Tables("items_prices").Rows(0).Item("item_selldozen")
cListItems.Add(New Combobox_values("Docena (" + item_selldozen + ")", item_selldozen))
End If
Dim dgvcbc As DataGridViewComboBoxCell = DirectCast(CType(main.ActiveMdiChild, discount_new_discount).discountitems_new_discount.Rows(last_row).Cells(3), DataGridViewComboBoxCell)
dgvcbc.DataSource = cListItems 'Fill Remote Comboboxcell
dgvcbc.DisplayMember = "Text"
dgvcbc.ValueMember = "Value"
If you have a ComboBoxColumn in your DataGridView and you want to know what is the selected index of the combo box, then you need to do this:
Handle the EditingControlShowing event of DataGridView. In this event handler, check if the current column is of our interest. Then we
create a temporary ComboBox object and get the selected index:
Private Sub dataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs)
If dataGridView1.CurrentCell.ColumnIndex = 0 Then
' Check box column
Dim comboBox As ComboBox = TryCast(e.Control, ComboBox)
comboBox.SelectedIndexChanged += New EventHandler(AddressOf comboBox_SelectedIndexChanged)
End If
End Sub
Private Sub comboBox_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim selectedIndex As Integer = DirectCast(sender, ComboBox).SelectedIndex
MessageBox.Show("Selected Index = " & selectedIndex)
End Sub

Resources