Change the tooltip text when selecting item in listview - vb.net

I have a listview containing the source addresses of files (from user system) and the destination addresses (two columns, multilpe selection = false).
Since the source addresses might be quite long like:
d:\root\branch1\branch2\branch3\branch4\myfile.dat
the first column shows just:
d:\ ... \myfile.dat
The real path is stored in the ListViewItem.Tag
I want to have a tooltip showing the whole path every time the user clicks (or changes) the selected item. I came out with this:
Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
For Each locItem As ListViewItem In ListView1.SelectedItems
With ToolTip1
.RemoveAll()
.SetToolTip(ListView1, locItem.Tag)
End With
Next
End Sub
Now, the tooltip does change, but it always skip one selection. That is:
selecting item 1: tooltip shows correctly
selecting item 2: tooltip don't show
selecting item 3: tooltip shows correctly
selecting item 5: tooltip don't show
selecting item 2: tooltip shows correctly (selection went back to item 2 which didn't show the 1st time)
Any idea?
PS: I am using Visual Studio Community 2015
PPS: I also need to have the View property set to View.Details (to show both columns and headers), so setting ShowItemToolTip = True does not work
CURRENT SOLUTION
I found a workaround, destroying and recreating the tooltip control. Now the tooltip shows correctly on every item:
Private myTooltip As ToolTip
Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
If myTooltip IsNot Nothing Then myTooltip.Dispose()
myTooltip = New ToolTip
For Each locItem As ListViewItem In ListView1.SelectedItems
myTooltip.SetToolTip(ListView1, locItem.Tag)
Next
End Sub
I'm still baffled about the skipping in the first approach.

ListView has a property called ShowItemToolTips (https://msdn.microsoft.com/en-us/library/system.windows.forms.listview.showitemtooltips(v=vs.110).aspx). You can set that to true and then set the ToolTipText property of the ListViewItems to the long path.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
ListView1.ShowItemToolTips = True
Dim lvi1 As New ListViewItem With {.Text = "d:\..\myFile.dat", .Tag = "d:\myLongPath\myFile.dat", .ToolTipText = .Tag}
Dim lvi2 As New ListViewItem With {.Text = "d:\..\myFile2.dat", .Tag = "d:\myLongPath\myFile2.dat", .ToolTipText = .Tag}
ListView1.Items.Add(lvi1)
ListView1.Items.Add(lvi2)
End Sub

Related

Selecting 1 Tool Strip Menu Item at any one time

I have a Tool strip menu with 4 options.
The options are degrees of screen rotation. (0, 90, 180, 270)
I am trying to select only 1 of these and keep it selected.
When I choose one then another, both are ticked (selected).
I have searched and found some solutions but only this works for me.
I have used the click event for each option to clear the ones not chosen like below.
Private Sub DegreesToolStripMenuItem6_Click(sender As Object, e As EventArgs) Handles DegreesToolStripMenuItem6.Click
DegreesToolStripMenuItem6.Checked = True
DegreesToolStripMenuItem7.Checked = False
DegreesToolStripMenuItem8.Checked = False
DegreesToolStripMenuItem9.Checked = False
End Sub
This sub is in my code 4 times to make it work but i'm sure there must be a cleaner, easier way to do this.
I have found online some other solutions but I can't seem to make it work, this one kind of makes sense like it should work but I can't figure it out
Private Sub DegreesToolStripMenuItem6_CheckedChanged(sender As Object, e As EventArgs) Handles DegreesToolStripMenuItem6.CheckedChanged, _
DegreesToolStripMenuItem7.CheckedChanged, _
DegreesToolStripMenuItem8.CheckedChanged, _
DegreesToolStripMenuItem9.CheckedChanged
Dim currentItem As ToolStripMenuItem = TryCast(sender, ToolStripMenuItem)
If currentItem IsNot Nothing AndAlso currentItem.Checked Then
Dim menu As ContextMenuStrip = TryCast(currentItem.Owner, ContextMenuStrip)
If menu IsNot Nothing Then
'The current item has just been checked so uncheck all other items on the same context menu strip.
For Each item As ToolStripMenuItem In menu.Items
If item IsNot currentItem Then
item.Checked = False
End If
Next item
End If
End If
End Sub
the toolstrip menu reads like this
-PreferedRotationToolStripMenuItem-DegreesToolStripMenuItem6
DegreesToolStripMenuItem7
DegreesToolStripMenuItem8
DegreesToolStripMenuItem9
Thanks for your time and looking forward to any help you guys can give.
Set CheckOnClick to True for each menu item, which I'm guessing you already have. This code worked for me:
Private Sub ToolStripMenuItems_CheckedChanged(sender As Object, e As EventArgs) Handles DegreesToolStripMenuItem9.CheckedChanged,
DegreesToolStripMenuItem8.CheckedChanged,
DegreesToolStripMenuItem7.CheckedChanged,
DegreesToolStripMenuItem6.CheckedChanged
Dim currentMenuItem = DirectCast(sender, ToolStripMenuItem)
If currentMenuItem.Checked Then
Dim menu = DirectCast(currentMenuItem.Owner, ContextMenuStrip)
For Each menuItem In menu.items.Cast(Of ToolStripMenuItem)
menuItem.Checked = menuItem Is currentMenuItem
Next
End If
End Sub
Here's a slight variation that avoids checking the already checked current item:
Private Sub ToolStripMenuItems_CheckedChanged(sender As Object, e As EventArgs) Handles DegreesToolStripMenuItem9.CheckedChanged,
DegreesToolStripMenuItem8.CheckedChanged,
DegreesToolStripMenuItem7.CheckedChanged,
DegreesToolStripMenuItem6.CheckedChanged
Dim currentMenuItem = DirectCast(sender, ToolStripMenuItem)
If currentMenuItem.Checked Then
Dim menu = DirectCast(currentMenuItem.Owner, ContextMenuStrip)
For Each menuItem In menu.Items.Cast(Of ToolStripMenuItem).Except({currentMenuItem})
menuItem.Checked = False
Next
End If
End Sub
The code above works if you have added the items to a ContextMenuStrip. If you have added them directly to an item on a MenuStrip then change this:
Dim menu = DirectCast(currentMenuItem.Owner, ContextMenuStrip)
to this:
Dim menu = DirectCast(currentMenuItem.Owner, ToolStripDropDownMenu)

Multi select listbox's last clicked item to textbox

I want to show the last clicked item on my ListBox that has multi-select. It only shows the first item on the list selected when I use the following:
Textbox1.text = listbox1.text
I think your only option would be to store a list of the selected indices and add/remove to/from it whenever the selection changes.
Something like this should do the job (assuming WinForms):
Private selectedIndices As New List(Of Integer)
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
' Add the newly selected items.
selectedIndices.AddRange(
ListBox1.SelectedIndices.Cast(Of Integer).
Where(Function(i) Not selectedIndices.Contains(i)))
' Remove the unselected items.
selectedIndices.RemoveAll(Function(i) Not ListBox1.SelectedIndices.Contains(i))
' Update the TextBox text. You can move this code to a different method
' if you want to trigger it using a button or something.
If selectedIndices.Count = 0 Then
TextBox1.Text = String.Empty
Else
Dim lastIndex As Integer = selectedIndices.Last()
TextBox1.Text = ListBox1.GetItemText(ListBox1.Items(lastIndex))
End If
End Sub
See it in action:

Set focus on ListView

I've just starting using ListView control in VS2019.
I'm sure there's a simple solution, but I can't figure out how to set the focus on the control like I can with most other controls.
I want the ListView to be focused when the form loads, and then I want to programmatically focus an item in the ListView.
I know how to focus a particular item using ListView1.FocusedItem.Index, but I can't focus the actual control.
I have tried both ListView1.Select() and ListView1.Focus() but these seem to do nothing.
What am I missing!?
Thanks
EDIT
As pointed out below, the control is actually focused using ListView1.Select() it's just not focused in the same way I'd expect, for example, a ListBox to be focused - ie, with a particular item in the list highlighted.
How would you best focus the ListView and highlight a particular item?
I have tried this in a command button on the form, but it doesn't do anything. Though it works correctly AFTER I click an Item in the ListView.
ListView1.Select()
If (ListView1.SelectedItems.Count > 0) Then
ListView1.Items(4).Selected = True
End If
listview1.focus()
For I as Integer = 0 to ListView1.Items.Count - 1
If ListView1.Items(i).Text = "youritemtexthere" then
ListView1.Items(i).Selected = true
End If
End For
or if you have the index but not a known text just do:
listview1.focus()
ListView1.Items(index).Selected = true
ListView1.Select works, you probably just don't see that the ListView has focus. You can verify this by checking the GotFocus and LostFocus events on the ListView:
Private Sub ListView1_GotFocus(sender As Object, e As EventArgs) Handles ListView1.GotFocus
Me.Text = "Got Focus"
End Sub
Private Sub ListView1_LostFocus(sender As Object, e As EventArgs) Handles ListView1.LostFocus
Me.Text = "Lost Focus"
End Sub
This simply updates your Form's title to "Got Focus" or "Lost Focus". You can force the focus in your Form Load event:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
ListView1.Items.Add("a")
ListView1.Items.Add("b")
ListView1.Items.Add("c")
ListView1.Select()
End Sub

Disable listview item in vb.net

I am trying to disable item (row) in my list view but its seem there no option like .enable = false and I tried to find anything to get my item to by disable but visible. Is there anything like that? If the user is allowed to select it then the item is enabled else it's visible but not enabled.
I have a table in the database that admin will fill it in which the user can view the window or not, so I want the user to able to see it and if not allowed to view it then its disable.
This only works if MultiSelect is set to False and the .Tag property is set for every item. (Yes or No).
Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
If Not ListView1.SelectedItems.Count = 0 Then
Dim item As ListViewItem = ListView1.SelectedItems(0)
If item.Tag.ToString = "No" Then
item.Selected = False
End If
End If
End Sub
As per # jmcilhinney , The following code should work with MultiSelect = True. I tried to access the last item added to the collection but it seems that the SelectedItems collection is ordered the same as the order the items appear in the ListView; not as expected the last item added would be last in the collection..
Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
If Not ListView1.SelectedItems.Count = 0 Then
For Each item As ListViewItem In ListView1.SelectedItems
If item.Tag.ToString = "No" Then
item.Selected = False
End If
Next
End If
End Sub

Transfer data from one listview to another when data been double click

I have 2 ListView setup.
Listview1 need to pass the data to listview2 when any of the data is double click by user.
How can I archive this? I am using vb 2008.
here is the image :
This is crude and simple, but it will give you a starting point. Note that there are any number of ways to approach this problem, and you will want to figure out any validation and such as required by your application. The biggest hurdle appears to be grabbing a reference to the item which is the target of the double click (as important, making sure that if the user double-clicks in an empty area of the ListView Control, that the last selected item is not added by mistake.
Hope this helps:
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.ListView1.FullRowSelect = True
Me.ListView2.FullRowSelect = True
End Sub
Private Sub AddItemToSecondList(ByVal item As ListViewItem)
' NOTE: We separate this part into its own method so that
' items can be added to the second list by other means
' (such as an "Add to Purchase" button)
' ALSO NOTE: Depending on your requirements, you may want to
' add a check in your code here or elsewhere to prevent
' adding an item more than once.
Me.ListView2.Items.Add(item.Clone())
End Sub
Private Sub ListView1_MouseDoubleClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseDoubleClick
' Use the HitTest method to grab a reference to the item which was
' double-clicked. Note that if the user double-clicks in an empty
' area of the list, the HitTestInfo.Item will be Nothing (which is what
' what we would want to happen):
Dim info As ListViewHitTestInfo = Me.ListView1.HitTest(e.X, e.Y)
'Get a reference to the item:
Dim item As ListViewItem = info.Item
' Make sure an item was the trget of the double-click:
If Not item Is Nothing Then
Me.AddItemToSecondList(item)
End If
End Sub
End Class