Add Icon to context Menu in VB.NET inside a windows forms appliction - vb.net

I have searched many times here and on Google looking for a solution that did not envolve utilizing someone's class.
This context menu is pops up where the user right clicks inside a dataGridView
When adding the items the VB code is
Dim m As New ContextMenu()
m.MenuItems.Add(New MenuItem("Disassociate *A* Device"))
m.MenuItems.Add(New MenuItem("Purge Device Assosciations"))
Is there no simple way to reference a resource to add an icon to said menuItems?
Pseudo
m.MenuItem(0).Icon.Source = ....
?

Assuming that this is for a Windows Forms application.
Why not use the ContextMenuStrip?
Example:
Dim m As New ContextMenuStrip()
Dim item As New ToolStripMenuItem("Click Me!")
item.Image = My.Resources.image
m.Items.Add(item)
DataGridView1.ContextMenuStrip = m

You will need to set Owner Draw to true and actually draw the menu item yourself
Here is a good detailed example

I use the image propery and assign a system.drawing.image object to it.
You wont be able to do it in one line, you do the add once all the properties of the newmenu is set.

Related

How to change the image displayed on a button at runtime in Visual Basic?

I am trying to change the Image attribute associated with a button when the button is clicked.
I have added the image I want to display (called "Black Pawn.png") as a resource within the solution and (from searching around and looking at similar questions) am trying to set the image attribute to it as shown below:
Private Sub boardButtonA2_Click(sender As Object, e As EventArgs) Handles boardButtonA2.Click
Dim sprites As Object = My.Resources.ResourceManager
boardButtonA2.Image = sprites.GetObject("Black Pawn.png")
End Sub
But when I click the button, the default image on it just disappears and is replaced with nothing instead of Black Pawn.png.
I am pretty new to using Visual Basic and Visual Studio so I may have failed to have added the image as a resource properly but I can see the image in the Solution Explorer above the form the button is in.
Any help or advice would be a great help.
Thanks.
EDIT:
Having thought more about the potential scenario, I'm wondering whether this answer is actually relevant. Your example code uses a hard-coded String but I'm wondering whether the actual String really would be a user selection. I'll leave it here anyway.
ORIGINAL:
There's no reason to use a hard-coded String to get a resource. If the String was from user entry then maybe, depending on the circumstances. As it is though, you should be using the dedicated property for that resource. That means using this:
boardButtonA2.Image = My.Resources.Black_Pawn
Just be aware that a new object is created every time you get a resource from My.Resources. For that reason, don't keep getting the same property over and over. If you need to use a resource multiple times, get it once and assign it to a field, then use that field multiple times, e.g.
Private blackPawnImage As Image
Private Function GetBlackPawnImage() As Image
If blackPawnImage Is Nothing Then
blackPawnImage = My.Resources.Black_Pawn
End If
Return blackPawnImage
End Function
and then:
boardButtonA2.Image = GetBlackPawnImage()
Also, I suggest that you change the name of the property to BlackPawn rather than Black_Pawn. You can change it to whatever you want on the Resources page of the project properties.
EDIT:
If this application is a chess game then you definitely will need every resource image for the playing pieces so you probably ought to get all of them at load and assign them to variables, then use them from those variables over the course of the game.
(I am assuming the question is for WinForms, if it isn't I will remove this answer)
When adding images as resources to a project, you have to pay attention to the name given to the resource after it is imported - the name can be changed if you want.
The image below is from one of my projects:
The name of the files on disk are:
CSV - Excel.png
GreenDot.png
RedDot.png
To fix your problem change the line:
boardButtonA2.Image = sprites.GetObject("Black Pawn.png")
to be:
boardButtonA2.Image = sprites.GetObject("Black_Pawn")
I don't think adding the image by going into Project > Add Existing Item properly added the image as a resource.
I instead went into *Project > (Solution Name) Properties > Resources > Images > Add Existing Item * and added it that way and was then able to get it working using jmcilhinney's method (I think my original method/a variation of it would work too but theirs is better).

Getting Selected Items from a Listbox

Good Wednesday All.
I am running into a brick wall (easy for a shade tree coder to do) I have a Listbox that i populated with a datatable. I want to get the all LicenseID's from the selected items. In other words, if the user selects 3 out of 8 of the list box, I need to get the LicenseID for each of those 3.
Below is how I populated the listbox
Using cmd As New OleDbCommand(cmdText, conn)
conn.Open()
Dim reader As OleDbDataReader = cmd.ExecuteReader()
dt.Load(reader)
ListBox1License.DataSource = dt
ListBox1License.DisplayMember = "InstitutionTypeAbrev"
ListBox1License.ValueMember = "LicenseID"
End Using
I need to get the selected items from the listbox to use later.
I am thinking of adding the selected Items to an array.
I have searched around STackOverflow for some examples but none seem to work for me.
Any Help Appreciated
I'll show you how to derive the answer for this yourself:
I've set up a form:
Really simple; the listbox is like your listbox. The button is just there to give me an easy way to stop the code and examine what is going on.
I wrote some code to populate some things into my listbox. It's a screenshot because it doesn't matter that you have exactly this code, so you don't need to write this code (hence why I'm making it hard to copy paste):
I've double clicked my button to make a click handler. I haven't written any code, but I have put a breakpoint on the method declaration - see it's red? Click the margin where the dot is, to put breakpoints in your code. When you hit them, the code stops and waits for you to inspect:
I've run my app and clicked my button. The code has stopped and VS has switched to showing me the code, not the app:
I can now point to some variable that is in scope (like ListBox1) and see a tooltip, or I can open the Locals/Autos windows and see variables that are in scope and drill into them:
Expand you ListBox in the Autos/Locals window. It has a lot of properties. Scroll to SelectedItems:
SelectedItems is a collection of things.. We can tell partly because Microsoft is good at naming collections of things with a plural name, and because the inspector says "enumerate the enumerable" .. it means that it is a bunch of things that we can ForEach to look through
Expanding it we see that my selecteditems has only one thing selected (i truly did only have one selected item in my list when I clicked the button)
We can see that an entry in the SelectedItems collection is a DataRowView type of object. We can see that a DataRowView has a Row property that is a DataRow.. This Row is the DataRow in the DataTable to which the list is bound (you set the DataSource to a DataTable; this is a row from that table).
Every time you dig into the tree another level, that's like using either a dot or an indexer in your code. At this level we've gone listbox1.SelectedItems(0).Row..
So from this we can see that we need a code like:
' we will "enumerate the enumerable"
For Each drv as DataRowView in listbox1.SelectedItems
Dim originalRow = drv.Row 'we could do this to get the row...
Dim selectedAnimaId = row("AnimalID") ' ..and then index the row to get the animal ID ..
Dim selectedAnimalId = drv("AnimalID") ' ... or it's actually possible to index a DataRowView directly, so you can skip the row part
Next drv
It can be handy to write code while you're stopped on a breakpoint so you can look at the values of things as you're writing, and check you're going in the right direction. You might need to use F10 (or whatever key is associated with "step over"/"step into") to move the yellow bar along and execute code lines one by one:
You can only move the code execution along if you've written complete, legal code, but it doesn't have to be logically correct. You can back up and execute again by dragging the yellow arrow in the margin (or right clicking and choosing Set Next Statement). Here I've put some dummy statement in to move along to, so i can check that my animalID is correctly set in X like I expect . I point to X to see the value:
The standard ListBox won't help you with that, past getting the DataRowView objects from the SelectedItems collection. As an alternative, here's a custom control that you can use in place of a standard ListBox that will help you:
Public Class ListBoxEx
Inherits ListBox
Public Function GetItemValue(item As Object) As Object
Dim index = Me.Items.IndexOf(item)
If (index <> -1 AndAlso Me.DataManager IsNot Nothing) Then
Return Me.FilterItemOnProperty(Me.DataManager.List(index), Me.ValueMember)
End If
Return Nothing
End Function
End Class
You can then call GetItemValue and pass any item and get the same value back as you would if that was the SelectedItem and you got the SelectedValue. To get all the values in an array:
Dim licenseIDs = myListBoxEx.SelectedItems.
Cast(Of Object)().
Select(Function(o) CInt(myListBoxEx.GetItemValue(o)).
ToArray()
For more information, see here.
In case you're unaware, if you add a class to your project and it is a control or component, once you build, it will appear automatically at the top of the Toolbox window.
If you already have a standard ListBox in place and you don't want to have to delete it and add a new control, you can edit the designer code file by hand to change the existing control. To do that, open the Solution Explorer and select a node within your project, click the Show All Files button, expand the node for your form, double-click the designer code file and then replace ListBox with ListBoxEx (or whatever you call it) in the relevant places. I'd advise creating a backup copy or syncing with source control first, in case you mess it up.

ListView Not Displaying Added Text

Background:
Hello everyone, I'm not new to visual basic or programming. I just find it the fastest to make a GUI in visual basic for various programs; however, I'm having a recent issue.
I have a form with a ListView control that I populate using a textbox and a button.
the code I use for the button is:
Code:
listview1.items.add(textbox2.text)
Pretty simple code that has always worked. I changed a few properties on my ListView as well, and I will list them. I just don't know what is going on.Here's a list of the properties changed (everything else is default):
Properties:
BackColor = DarkGray
BorderStyle = FixedSingle
HeaderStyle = None
MultiSelect = False
View = Details
All properties were changed via the properties tab and not through code. I want to be able to add text to the control. I'm not adding any subitems either. I'm just confused because this code has always worked, and I've never had this issue. I'm also using Visual Basic 2010 Express Edition if that helps.
If the added item in ListView is not displaying then check the ListView.View property. if this property has set to Detail view then Columns must be added in that listView control otherwise added item will not display.
Make sure item is added correctly.
Dim item As ListViewItem = listView1.Items.Add("Item Text") ' This text will be displayed in first column. The column index will be 0
' Further values will be added in SubItem
item.SubItems.Add("Sub Item1")
item.SubItems.Add("Sub Item2")
item.SubItems.Add("Sub Item3")

ToolStripTextBox image is not appearing

I am using WindowsForms and I am trying to put a Textbox into my main menu and add an Image. However I cannot get the image to appear. What am I missing here.
txtRequestEdit.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText
txtRequestEdit.Image = Properties.Resources.Wrench16 'This is a valid image.
txtRequestEdit is a System.Windows.Forms.ToolStripTextBox
EDIT- Here is an image of the menu. The item at the bottom of this menu is the txtRequestEdit control.
Strangely the no matter how you apply the image, it won't show on ToolStripTextBox. I think this is a bug because I found nothing about this behavior in the documents or on the web.
I will try doing this with a hack like owner-drawing the item or something else and will put the wrong answer here so the next person with this issue avoids this wrong path.
This is wrong:
Apparently the Image property "supports the .NET Framework infrastructure and is not intended to be used directly from your code.", so if (as you say) everything's OK and you've checked the image itself to be valid, using ImageList and ImageIndex may solve the problem (assuming the item lies inside a MenuStrip named menuStrip1:
txtRequestEdit.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText
menuStrip1.ImageList = New ImageList()
menuStrip1.ImageList.Images.Add(Properties.Resources.Wrench16)
txtRequestEdit.ImageIndex = 0

listview in childform

I have 3 forms, one frmMain - main form, second is frmUserType- childform, and the last frmCreateUserType. In the main form I have a menu item to open my frmUserType, In this form I have a button to open another form which is my frmCreateUserType, In this form I have a button to add records then update the listview in frmUserType. The problem is the listview will not access with my add button control in frmCreateUserType. I tried not to used mdiparent declaration for my frmMain and frmUserType as children and it works, so meaning that the problem is showing my frmUserType as childform?I am using vb.net 2008
Any suggestion would greatly appreciated
Thans in advance
Code to open my second form (frmUserType)
Dim frmChildUserType As New frmUserType
frmChildUserType.MdiParent = Me
frmChildUserType.WindowState = FormWindowState.Maximized
frmChildUserType.Show()
Code for my add button to update the listview in frmUserType
frmUserType.lsvUserType.Items.Clear()
FillListViewUserType("SELECT * FROM pr_user_type", frmUserType.lsvUserType)
You're creating a new instance as:
Dim frmChildUserType As New frmUserType
But in your code:
frmUserType.lsvUserType.Items.Clear()
FillListViewUserType("SELECT * FROM pr_user_type", frmUserType.lsvUserType)
You're not accessing that instance but is instead using the default instance of frmUserType. So I think you're updating a different instance of the ListView than what you think.
If you change your code to instead be:
frmChildUserType.lsvUserType.Items.Clear()
FillListViewUserType("SELECT * FROM pr_user_type", frmChildUserType.lsvUserType)
I think it would work as you expect.
If you don't know what a default instance is, you can find a blog about them here (I think they're a bad idea).