identfying listview cell on mouseover - vb.net

I am trying to identify which cell the user has their mouse over on a listview, currently I have
Private Sub ListView1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseMove
Dim cellnum As ListViewItem = ListView1.GetItemAt(e.X, e.Y)
tooltip1.SetToolTip(ListView1, thisItem.Text)
end sub
which is not functioning. How would I accomplish this

If by "cell" you mean the subitem, use HitTest to find the subitem:
Dim ht As ListViewHitTestInfo = lvex.HitTest(pt.X, pt.Y)
if ht.Item IsNot Nothing then
IndexOfSubItemAtXY = ht.Item.SubItems.IndexOf(ht.SubItem)
End if
Setting the tooltip on a MouseMove may prove problematic though. There is an ItemMouseHover where you could figure out which cell/subitem, it is over and set the tooltip accordingly/

Related

programmatically select and highlight a row of a ListView in VB.NET

I want to do something seemingly simple - programmatically select and highlight a row of a ListView in VB.NET.
VB.NET: How to dynamically select a list view item?
tells me what should to be all that is needed, but it isn't. The row is selected, but not highlighted.
http://vbcity.com/forums/t/28260.aspx
tells me about the "HideSelection" property and the .Focus() method (also referenced at Select programmatically a row of a Listview), which sounded hopeful, but the best I can get is the faint highlight mentioned, I want the full monty. I tried a Noddy example with just a ListView, in Details mode, FullRowSelection = true, HideSelection = False, one columnheader defined and then
ListView1.Items.Add("Red")
ListView1.Items.Add("Orange")
ListView1.Items.Add("Yellow")
ListView1.Items.Add("Green")
ListView1.Items(2).Selected = True
I get this
but I want this
I can simulate highlighting by adding these lines
ListView1.SelectedItems(0).BackColor = Color.CornflowerBlue
ListView1.SelectedItems(0).ForeColor = Color.White
but then how can I be sure to undo the artificial highlight if the row can be implicitly as well as explicitly deselected? Do I have to think of all the possible cases? That's too much work for what should be a simple operation. Plus, since I want to color-code my rows, there is an additional challenge that when I undo the highlight color, I have to figure out what color is appropriate at that point. Is there a better, simpler way?
You can access the Graphics object used to draw each item, and draw them yourself.
Make a new project with a Button and ListView. Paste the following code:
Form_Load to use multiple subitems
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.ListView1.OwnerDraw = True ' or else can't handle DrawItem event
ListView1.Columns.Add("ColumnHeader1")
ListView1.Columns.Add("ColumnHeader2")
ListView1.Columns.Add("ColumnHeader3")
Me.ListView1.Items.Add("Red")
Me.ListView1.Items.Add("Orange")
Me.ListView1.Items.Add("Yellow")
Me.ListView1.Items.Add("Green")
ListView1.Items(0).SubItems.Add("Strawberry")
ListView1.Items(0).SubItems.Add("Apple")
ListView1.Items(1).SubItems.Add("Pepper")
ListView1.Items(1).SubItems.Add("Apricot")
ListView1.Items(2).SubItems.Add("Plum")
ListView1.Items(2).SubItems.Add("Banana")
ListView1.Items(3).SubItems.Add("Apple")
ListView1.Items(3).SubItems.Add("Lime")
End Sub
Three handlers for the ListView's drawing related events. Code copied from this answer
Private Sub listView1_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
e.DrawDefault = True
End Sub
Private Sub listView1_DrawSubItem(sender As Object, e As DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
Const TEXT_OFFSET As Integer = 1
' I don't know why the text is located at 1px to the right. Maybe it's only for me.
Dim listView As ListView = DirectCast(sender, ListView)
' Check if e.Item is selected and the ListView has a focus.
If Not listView.Focused AndAlso e.Item.Selected Then
Dim rowBounds As Rectangle = e.SubItem.Bounds
Dim labelBounds As Rectangle = e.Item.GetBounds(ItemBoundsPortion.Label)
Dim leftMargin As Integer = labelBounds.Left - TEXT_OFFSET
Dim bounds As New Rectangle(rowBounds.Left + leftMargin, rowBounds.Top, If(e.ColumnIndex = 0, labelBounds.Width, (rowBounds.Width - leftMargin - TEXT_OFFSET)), rowBounds.Height)
Dim align As TextFormatFlags
Select Case listView.Columns(e.ColumnIndex).TextAlign
Case HorizontalAlignment.Right
align = TextFormatFlags.Right
Exit Select
Case HorizontalAlignment.Center
align = TextFormatFlags.HorizontalCenter
Exit Select
Case Else
align = TextFormatFlags.Left
Exit Select
End Select
TextRenderer.DrawText(e.Graphics, e.SubItem.Text, listView.Font, bounds, SystemColors.HighlightText, align Or TextFormatFlags.SingleLine Or TextFormatFlags.GlyphOverhangPadding Or TextFormatFlags.VerticalCenter Or TextFormatFlags.WordEllipsis)
Else
e.DrawDefault = True
End If
End Sub
Private Sub listView1_DrawItem(sender As Object, e As DrawListViewItemEventArgs) Handles ListView1.DrawItem
Dim listView As ListView = DirectCast(sender, ListView)
' Check if e.Item is selected and the ListView has a focus.
If Not listView.Focused AndAlso e.Item.Selected Then
Dim rowBounds As Rectangle = e.Bounds
Dim leftMargin As Integer = e.Item.GetBounds(ItemBoundsPortion.Label).Left
Dim bounds As New Rectangle(leftMargin, rowBounds.Top, rowBounds.Width - leftMargin, rowBounds.Height)
e.Graphics.FillRectangle(SystemBrushes.Highlight, bounds)
Else
e.DrawDefault = True
End If
End Sub
Button click handler to simulate item(2) selected
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.ListView1.Items(2).Selected = True
End Sub
This will draw the background color regardless of focus. You have a lot of control over other colors and fonts going this route too.
Here, the button has been clicked, to select item 2, while the button still has focus, and item 2 is selected.
Easiest thing,
Just allocate the LST_ItemIndex = lstList.FocusedItem.Index everytime you select a different item
and then fire the below whenever you want the highlight
If lstList.Items.Count > 0 Then
lstList.Items(LST_ItemIndex).Selected = True
lstList.Items(LST_ItemIndex).EnsureVisible()
End If

Mouse hovering event

I want to do an mouse hovering event, when the mouse is over an button I want to change button text color and font size, I have try this code but doesn't work:
Private Sub Command1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Command1.ForeColor.MediumBlue()
Command1.FontSize = 10
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Command1.ForeColor.White()
Command1.FontSize = 8
End Sub
Can anyone give me a suggestion i have search on Google and try different ways with mouse event handler but didn't work.
First, instead of tracking every mouse move, you can rely on MouseEnter and MouseLeave events of the button.
Second, do not forget to add Handles <Control>.<Event> clause at the declaration of your event-handling procedures.
Result:
Private Sub Command1_MouseEnter(sender As Object, e As EventArgs) _
Handles Command1.MouseEnter
Command1.FontSize = 10
End Sub
Private Sub Command1_MouseLeave(sender As Object, e As EventArgs) _
Handles Command1.MouseLeave
Command1.FontSize = 8
End Sub
Also please do not forget that some users are preferring keyboard control.
This means that
You might want to equip the button with an accelerator.
Command1.Text = "&Launch" (now Alt+L activates the button)
Note: accelerator character for winforms is &, for wpf is _.
You might want to make your entry/leave effect also when the button receives/looses keyboard focus (focus is moved using Tab and Shift+Tab key).
You can try making your changes into MouseEnter and MouseLeave
Private Sub RightButton_MouseEnter(sender As System.Object, e As System.EventArgs) Handles RightButton.MouseEnter
RightButton.ForeColor = Color.AliceBlue
RightButton.Font = New Font(RightButton.Font, 12)
End Sub
Private Sub RightButton_MouseLeave(sender As System.Object, e As System.EventArgs) Handles RightButton.MouseLeave
RightButton.ForeColor = Color.White
RightButton.Font = New Font(RightButton.Font, 10)
End Sub

Unselect listview item when hovering in listview background

I am needing some help with a listview control that uses large icon view. I have icons in my listview control that when I hover over them, it displays a custom tooltip (not the in-built listview tooltip).
My problem is that when I hover into the background of the listview, it doesn't de-select the selected item. I would also like to cut the tooltip short (if possible) so if the tooltip is meant to be visible for 5 seconds and someone hovers into the background of the listview before this time, then the item deselects and the tooltip disappears.
My code currently looks like this:
Private Sub lsvStores_ItemMouseHover(sender As Object, e As ListViewItemMouseHoverEventArgs) Handles lsvStores.ItemMouseHover
Dim storeID As String = e.Item.Name
ShowStoreDetailsTooltip(storeID, sender, e.Item.Position.X, e.Item.Position.Y - 80)
End Sub
Private Sub lsvStores_MouseHover(sender As Object, e As EventArgs) Handles lsvStores.MouseHover
lsvStores.SelectedItems.Clear()
End Sub
Private Sub ShowStoreDetailsTooltip(ByVal Code As String, ByVal Obj As Control, ByVal XPos As
ttpStoreDetails.ToolTipTitle = StoreName
ttpStoreDetails.IsBalloon = True
ttpStoreDetails.Show(String.Empty, Obj, 0)
ttpStoreDetails.Show(tmpString, Obj, XPos, YPos, 5000)
End Sub
Any help appreciated thanks.
Using some code from this answer, we can get the item currently under the mouse cursor using ListView.GetItemAt(), then see if it's Nothing. If it is, then you'll do whatever you need to to make your Tooltip disappear.
Private _item As ListViewItem = Nothing
Private Sub lsvStores_MouseMove(sender As Object, e As MouseEventArgs) Handles lsvStores.MouseMove
Dim item As ListViewItem = lsvStores.GetItemAt(e.X, e.Y)
If item Is Nothing Then
If _item IsNot Nothing Then
_item.Selected = False
End If
_item = Nothing
ttpStoreDetails.Hide(sender)
End If
End Sub

contextmenustrip opening event determining sender

I have 30 labels. They can have any value I want.
I need to be able to assign one context menu to them all then determine which label was clicked in order to use my x variable.
Private Sub Label_Click(sender As Object, e As MouseEventArgs) Handles Label1.MouseClick, Label2.MouseClick, Label3.MouseClick, Label4.MouseClick, _
Label5.MouseClick, Label6.MouseClick, Label7.MouseClick, Label8.MouseClick, Label9.MouseClick, Label10.MouseClick, Label11.MouseClick, _
Label12.MouseClick, Label13.MouseClick, Label14.MouseClick, Label15.MouseClick, Label15.MouseClick, Label16.MouseClick, Label17.MouseClick, _
Label18.MouseClick, Label19.MouseClick, Label20.MouseClick, Label21.MouseClick, Label22.MouseClick, Label23.MouseClick, Label24.MouseClick, _
Label25.MouseClick, Label26.MouseClick, Label27.MouseClick, Label28.MouseClick, Label29.MouseClick, Label30.MouseClick
Dim x As String = sender.Text
xmlinteraction.appCall(x)
End Sub
I received awesome help the other day passing variable into contextmenustrip
But I am too new to put it all together and make it work. I understand what we are trying to do, but not all the syntax. Please help.
Jay,
Here is what I put together from the code you gave me. Is this what you were thinking? I feel like I missing something still and further clean the code. Possibly removing the case statements.
Private Sub rcmenuOption(x, y)
' x is equal to what the menu item was clicked
' Create case stament for that to call the correct xmlinteraction passing in y
Select Case x
Case "Copy Link"
copyClipboard(y)
End Select
End Sub
Private Sub rcmenuClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles rcmenu.ItemClicked
' Get the Label clicked from the SourceControl property of the clicked ContextMenuStrip.
Dim contextMenu = DirectCast(sender, ContextMenuStrip)
Dim label = DirectCast(contextMenu.SourceControl, Label)
Dim var2 As String = label.Text
' Get the clicked menu strip and update its Text to the Label's Text.
Dim toolStripItem = e.ClickedItem
Dim var As String = toolStripItem.Text
rcmenuOption(var, var2)
End Sub
contextmenustrip opening event determining sender
OK, you have a number of Labels on a form and all of them use the same ContextMenuStrip (all the Labels have their ContextMenuStrip property set to the same ContextMenuStrip control).
When the user right clicks a Label and selects a menu item, you want that menu item's Text to change to the clicked Label's Text.
You can do this using your ContextMenuStrip ItemClicked event handler. Use the handler's sender and ToolStripItemClickedEventArgs parameters to get the Label's Text and a reference to the ToolStripItem clicked.
Private Sub ContextMenuStrip1_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles ContextMenuStrip1.ItemClicked
' Get the Label clicked from the SourceControl property of the clicked ContextMenuStrip.
Dim contextMenu = DirectCast(sender, ContextMenuStrip)
Dim label = DirectCast(contextMenu.SourceControl, Label)
' Get the clicked menu strip and update its Text to the Label's Text.
Dim toolStripItem = e.ClickedItem
toolStripItem.Text = label.Text
End Sub

Setting Combobox Height OwnerDrawVariable ( Unexpected display result )

First of all, i did make a combox box with ownerdrawvariable mod because i wanted to handle a tooltips with the mouse hover. To do this i handled two methods DrawItem and MeasureItem :
Private Sub DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles cboPneuGlobal.DrawItem
If e.Index = -1 Then
Exit Sub
End If
e.DrawBackground()
Dim p As Point = New Point(CInt(cboPneuGlobal.Location.X * Ratio), CInt(cboPneuGlobal.Location.Y * Ratio))
Dim brColor As Brush = Brushes.Black
If e.State = DrawItemState.Selected Then
ToolTipFormBase.Show(CType(cboPneuGlobal.Items(e.Index), clsPneuEtTypeMarque).ToDisplay, Me, p)
brColor = Brushes.White
End If
e.Graphics.DrawString(CType(cboPneuGlobal.Items(e.Index), clsPneuEtTypeMarque).ToDisplay, e.Font, brColor, New Point(e.Bounds.X, e.Bounds.Y))
End Sub
Here the second :
Private Sub measureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles cboPneuGlobal.MeasureItem
' fetch the current item we’re painting as specified by the index
Dim comboBoxItem As Object = cboPneuGlobal.Items(e.Index)
' measure the text of the item (in Whidbey consider using TextRenderer.MeasureText instead)
Dim textSize As Size = e.Graphics.MeasureString(CType(cboPneuGlobal.Items(e.Index), clsPneuEtTypeMarque).ToDisplay, cboPneuGlobal.Font).ToSize()
e.ItemHeight = textSize.Height
e.ItemWidth = textSize.Width
End Sub
I got a small display problem which the combo box height doesn't follow the font of my item and stay small. That make my text truncate. See the image :
What i'm doing wrong ??
It's work great with a non ownerdraw combobox