Windows ComboBox Selected Item (populated from List<>) - c#

I am setting a combobox item like this:
List<Object> items = new List<Object>();
items.Add(new { Text = "MyVal", Value = 1 });
cbo.DataSource = items;
It then in VS returns:
But I cannot simply now say cbo.SelectedItem.Text or cbo.SelectedItem.Value.
If i try this, I get the error
"object does not contain a definition for value and no extension method value
accepting a first argument of type object could be found"
How can I get the Value Property please
Based on great replies, I have now added this, to show that I cannot get the properties of Text or Value at all.
I've tried this code to pass the "string" into
public class ComboboxItem
{
public string Text { get; set; }
public short Value { get; set; }
public ComboboxItem(string t, short v)
{
Text = t;
Value = v;
}
}

The combo box is bound to a list containing anonymous types. You ought to use the dynamic keyword.
dynamic item = cbo.SelectedItem;
String text = item.Text;
Int32 value = item.Value;

You should add this.cbo.SelectedItem as object;
Then, for example:
public class student
{
public string name;
public int age;
}
var stu = cbo.SelectedItem as student;
string name = stu.name;
int age = stu.age;
OK,this is my first answer.

create class with Text and Value properties (ComboboxItem), then create the item list with that class. now you can do as below
ComboboxItem obj = cbo.SelectedItem as ComboboxItem;
//now you can get the obj.Value

I notice you're blanking out certain parts of your code, as of such I shall assume you're not using the object 'object' but something else, else your code wouldn't compile.
The ComboBox does not hold the datatype of its values, it all treats them as simple objects. So SelectedItem will be of type object, which should then be casted to the correct datatype in order to access the text / value property.
var myItem = cbo.SelectedItem as MyObject
if(myItem != null){
Console.WriteLine("Value is {0}", myItem.Value);
}

Related

How to pull out the item and subitems of the listview selected entry

I would like to edit a listview item consisting of 2 ints and 3 strings. I am saving the items to the listview from a public class, "Rineitem". I can assign the selected row to an object and see it in my locals window but I don't know how to get to it, or the subitems of it.
I've tried to find examples but found nothing that is as simple as this should be. My own attempts have often given messages that perhaps I am forgetting a cast to !??? If I convert the object to string I get a text naming the public class.
object item = lvw_Smd_Jobs.SelectedItem;
When I try to assign the lvw selectedItem to the class I get, Cannot implicitly convert type 'object' to 'Rin...Auftrag_Verwalter.Rineitem'. An explicit conversion exists (are you missing a cast?)
I would like to save two of the string values to textboxes where the user can change the value(s) and then I would save the listview item with it's changes.
One, why not save all items as strings, that way your casting is simplified.
Then to remove a selected item. You'd do the following
var item = (string)lvw_Smd_Jobs.SelectedItem;
lvw_Smd_Jobs.Items.Remove(item);
You can cast a "ListBoxItem" (type object) to the class it realy is.
Here a little example how to add, read and modify items in your ListBox:
// Example class
public class RineItem
{
public string Name { get; set; }
public int Id { get; set; }
// Override ToString() for correct displaying in listbox
public override string ToString()
{
return "Name: " + this.Name;
}
}
public MainWindow()
{
InitializeComponent();
// Adding some examples to our empty box
this.ListBox1.Items.Add(new RineItem() { Name = "a", Id = 1 });
this.ListBox1.Items.Add(new RineItem() { Name = "b", Id = 2 });
this.ListBox1.Items.Add(new RineItem() { Name = "c", Id = 3 });
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// Loop through SelectedItems
foreach (var item in this.ListBox1.SelectedItems)
{
// Have a look at it's type. It is our class!
Console.WriteLine("Type: " + item.GetType());
// We cast to the desired type
RineItem ri = item as RineItem;
// And we got our instance in our type and are able to work with it.
Console.WriteLine("RineItem: " + ri.Name + ", " + ri.Id);
// Let's modify it a little
ri.Name += ri.Name;
// Don't forget to Refresh the items, to see the new values on screen
this.ListBox1.Items.Refresh();
}
}
The Error-Message you're facing tells you, that there is no implicit cast to convert an object to and RineItem.
There are implicit cast possible (From int to long). And you can create you own ones. Here an example:
public class RineItem2
{
public string Name2 { get; set; }
public int Id2 { get; set; }
public static implicit operator RineItem(RineItem2 o)
{
return new RineItem() { Id = o.Id2, Name = o.Name2 };
}
}
Now you can do this:
RineItem2 r2 = new RineItem2();
RineItem r = r2;
But this should only be used if every object from Class RineItem2 can be cast to RineItem.
A cast from object to RineItem would have to work every time! Hence you don't know what type is your object you're not allowed to:
object o = "bla bla";
RineItem r = (RineItem)o; // Not allowed! Will not work!

Adding a value to a listbox item. C#

I have a list box with my desired information inside it. However I need a number to be sent when the user selects on a specific row.
ListBox data:
Test1
Test2
Test3
For example when I select Test1 in my list my I need to return the integer 2. I am asking if there is anyway I can assign the number 2 to be associated with "Test2"
listbox.Items.Add("Name displayed on list", value);
Yes, ListBox Items are of type object and you can assign any object to them, so build a class like this:
public class ListItem
{
public string Name {get; set;}
public int Value {get; set;}
public override string ToString()
{
return Name;
}
}
Now you can add ListBox Items like this:
listbox.Items.Add(new ListItem { Name = "Test1", Value = 2});
When a ListBox Item is Selected you can get its value like:
var value = ((ListItem)listbox.SelectedItem).Value;
Note that as ListBox Uses its Items .ToString() method to create Texts to show so you have to override it's ToString() method like this:
public override string ToString()
{
return Name;
}
Otherwise it will show the name of the class instead of your desired value.
As already suggested, you could specify DataSource of your listBox, then you could use conviniently SelectedValue of ListBox class. But before you have to also specify ValueMember and DisplayMember of a list box.
The most convinient in my opinion will be adding Tuple<string, int> objects to your list box and settings ValueMember to "Item2" and DisplayMember to "Item1", as Item1 willb e our string Test1 and Item2 will be integer value.
Code example:
listBox1.ValueMember = "Item2";
listBox1.DisplayMember = "Item1";
listBox1.DataSource = new Tuple<string, int>[] {
new Tuple<string, int>("Test1", 1),
new Tuple<string, int>("Test2", 2)
};
Now, in code you can just use listBox1.SelectedValue to access integer value of selected item.

C# select first item in datasource generated list

I have this class
class UserData
{
public UserData() { }
public string Name { get; set; }
public string Val { get; set; }
}
I have a normal ListBox. Im selecting Data from MySql.
private void ListUsers(string server)
{
List<UserData> ls = new List<UserData>();
foreach(dynamic obj in _data)
{
if(obj.servername == server)
{
ls.Add(new UserData() { Name = obj.username, Val = obj.password });
}
}
UserList.Sorted = true;
UserList.DisplayMember = "Name";
UserList.ValueMember = "Val";
UserList.DataSource = ls;
}
When debugging the ls it contains
[0]
Name => "Test",
Val => "12345"
[1]
Name => "Test2",
Val => "54321"
Now sometimes there ist only 1 postition in that list. If this happens, I want to select that entry or at least the Name and paste this into a textbox.
But for some reason I cant achive this. And Google didnt brought any results. At least non that suites to my problem.
I tried
rdpUserList.Items[0].ToString();
but this brings me ProjectName.UserData and not Test.
What is the right way to select the first Item in a list that was generated by a datasource ?
You're calling ToString() on an instance of the type ProjectName.UserData, which gives you its type name.
You want to access that instance's Name property instead.
If rdpUserList is a List<UserData>, you want this:
rdpUserList.Items[0].Name
If instead it's a datasource, you need to cast the item in order to access its properties:
((ProjectName.UserData)rdpUserList.Items[0]).Name
There are two approaches to this issue. The first is a logical problem; you need to call the Name property and not the ToString() method. Note that using this way, you need to cast to your object type.
((UserData)rdpUserList.Items[0]).Name
The second option is to override the ToString() method so you can call the name the way you tried.
class UserData
{
public UserData() { }
public string Name { get; set; }
public string Val { get; set; }
public override string ToString()
{ return this.Name; }
}
and then call with
rdpUserList.Items[0].ToString()
Sorry for previous post, I did not test before I answered,
try the following if you want, I just like linq :)
var item = rdpUserList.Items.OfType<ListItem>().First();
Class1 t = new Class1(){Id=Convert.ToInt32(item.Value), description = item.Text};
OR for just the name
string name = rdpUserList.Items.OfType<ListItem>().First().Text;

WinForms Combobox: Fill with String and Object

I already have seen that there are many Topics about this,but I am not able to make them work.
I have an Combobox which shall be filled with an List of String.
this.elementBox.DataSource = this.elementList;
this.elementBox.SelectedIndexChanged += new EventHandler(this.elementBox_SelectedIndexChanged);
If I put this into the Code my GUI does not appear, I suppose the assignment of the data is wrong. I already tried Bindingsource.
Then I want to fill an Combobox with an List of Objects and this does not work either. itemData is an Dictionary with an String as key and the Objectlist as value.
box1.DataSource = itemData["ele1"];
box1.DisplayMember = "Name";
box2.DataSource = itemData["ele2"];
box2.DisplayMember = "Id";
I tried to play around with DisplayMember and Value but I am not able to get it to work.
The Type of the List is MyItem:
class myItem{ int Id; Internal data;}
class Internal {String name;}
Obviously I want to show the myItem.data.name in the Combobox, but I do not know how to get it. Furthermore what is the difference of DisplayMember and Value?
DisplayMember expects a public property not a private field
Change the classes:
class myItem
{
public int Id {get; set}
public Internal data {get;set;}
}
class Internal
{
public string Name {get; set;}
}
Note also that the property names are case sensitive. So 'name' and 'Name' are considered to be different entities.
Further, if you are adding an object of 'myItem` class, you cannot get the combo box to access the a member of a member. You will have to do the fetching yourself:
class myItem
{
public int Id {get; set}
public Internal data {get;set;}
public string Name { get { return data.Name; }}
}
Now by setting DisplayMember to "Name" it will reference the Name property of myItem which in turn accesses the data.Name property.
If the list comes to you from somewhere else (you don't own the list class and thus cannot modify it's code), you will have to wrap the objects inside another class and replace the list with a list of the wrapped objects:
class myItemWrapper
{
private myItem _myItem;
public myItemWrapper(myItem item)
{
_myItem = item;
}
public override string ToString()
{
return _myItem.data.Name;
}
public myItem Item { get { return _myItem;}}
}
then you can get rid of the DisplayMember assignment
box1.DisplayMember = "Name";
as the ToString() will be called instead.
but you have to replace the
box1.DataSource = itemData["ele1"];
with a bit more code:
var wrapper = new List<myItemWrapper>();
foreach(var item in itemData["ele1"]);
wrapper.Add(new myItemWrapper(item));
box1.DataSource = wrapper;
And don't forget that, when you are handling the selected item in the listbox that you are no longer dealing with myItem objects, but myItemWrapper objects instead. So to access the actual myItem object you will have to use the Item property of the myItemWrapper class instead.

C# DataGridView empty when using concrete type, displays data when using anonymous type

I'm trying to display using a DataGridView and I'm getting some strange results.
When I set the data source with an anonymous type like so:
var displayList = CreateAnAnonymousBindingList(new { prop1 = string. Empty ...etc... } );
displayList.AllowNew = true; //The property in the DataGridView is set in the designer
var list = from someEntity in entities.EntityGroup //I want some of the fields from each entity
select new { prop1 = someEntity.prop1...etc...};
foreach(item in list)
{
displayList.add(item);
}
form.dataGridView.DataSource = displayList;
The data I want is displayed, but I cannot add new items, there is an exception caused by the anonymous type. This, I know, is because it is an anonymous type and has no constructors.
The problem is, when I create a concrete class using the same types, even names as the anonymous type, create a BindingList (simply by new BindingList()) and add items to it like:
BindingList<ClassName> displayList = new BindingList<ClassName>();
displayList.AllowNew = true;
var list = from someEntity in entities.EntityGroup
select someEntity;
foreach(var item in list)
{
ClassName temp = new ClassName();
/* Assign all the properties I want*/
displayList.Add(temp);
}
form.dataGridView.DataSource = displayList;
Nothing is displayed, even though the list has items in it, and the data source is set to the list. I cannot work out why this is happening, maybe I'm overlooking something really, really simple, but I cannot see where the issue is coming from.
Any help would be fantastic.
Change your class to use properties and datagridview will display the list.
class ClassName
{
public string ID { get; set; }
public string Name { get; set; }
}

Categories