Adding enum to combobox - c#

Hi may i know how to get the enum value below to bind into the combobox?
I wrote the below code which works well but wonder is this the best way.
public enum CourseStudentStatus
{
Active = 1,
Completed = 2,
TempStopped = 3,
Stopped = 4,
}
//Bind Course Status
Dictionary<string, int> list = new Dictionary<string, int>();
foreach (int enumValue in Enum.GetValues(typeof(CourseStudentStatus)))
list.Add(Enum.GetName(typeof(CourseStudentStatus), enumValue), enumValue);
var column = ((DataGridViewComboBoxColumn)dgv.Columns["studentCourseStatus"]);
column.DataPropertyName = "StudentStatus";
column.DisplayMember = "Key";
column.ValueMember = "Value";
column.DataSource= list.ToList();
----------------- UPDATE -------------------
Hi i have changed my code to this according to Sanjeevakumar Hiremat and it works perfectly.
cbStatus.DataSource = Enum.GetValues(typeof(CourseStudentStatus));
However, when i want to a Get() and want to bind the value back to the cbStatus, it cast error {"Object reference not set to an instance of an object."}
cbStatus.SelectedValue = Course.Status;.
The cbStatus.Datasource is not empty and it has value after bound to cbStatus.DataSource = Enum.GetValues(typeof(CourseStudentStatus));
please advice.

Following should be the simplest way to bind it.
column.DataSource = Enum.GetValues(typeof(CourseStudentStatus));
To get the selected value you need to cast it to the enum type.
CourseStudentStatus selectedValue = (CourseStudentStatus)column.SelectedValue
Enum.GetValues returns an array of the enumType values which can then be bound to any control.
I've tested this on a standalone combobox, not in a combobox column in DataGridView, YMMV.

I don't think there is a best way. I used to do something similar with a GenericListItem<T> class where T is the backing value, in your case, an enum.
This class exposed Display string and Value T properties to bind to. I think I was also overriding ToString because it is the default if you don't specify the DisplayMember. I went further and made a constructor taking just Value and defaulting Display to Value.ToString, which in the case of enums works I think.
I'd then make a List<GenericListItem<T>>, feed that into the DataSource of the column and set the DisplayMember and ValueMember properties accordingly in code. This list is the alternative to the dictionary used in your example.
But I'm not saying it's a better solution :-) however it means you can remove code, say enum iteration, into this class or specialise the class for handling certain data types better, all with the end goal of being inserted into a list and bound to a control.

Related

Get Values from anonymous type

In one button I made a query where I selected these 3 values: idStudent, name, lastName and bounded to a DataGridView and now I get those values again to use them in another button with this:
var Selected = dgvShow.CurrentRow.DataBoundItem;
And the result from Selected is this:
{idStudent = 31, name = "John", lastName = "Travolta"}
The above result is an Anonymous Type, so how can I get those values and show them in a TextBox?
Also:
Can I get a single value from that var ("Selected")?
Is it possible or I have to change my code?
PS: I'm using Entity Framework, C#
To use your properties as an anonymous type you can cast it to a dynamic.
Eg:
var Selected = dgvShow.CurrentRow.DataBoundItem;
var objDynamic = (dynamic)Selected;
Console.WriteLine(objDynamic.idStudent);
I would recommend using a model instead of an anonymous type and unbox your DataBoundItem into your model, it will benefit accessibility of your property names via IntelliSense and make it more manageable for other people to maintain.

Calling the property names of a dynamic property "ints": can't call property

I am assigning property names of a dynamic object as ints in string form. The int value represents an int ID in a database I am using. However I am stuck on how to retrieve the value assigned to the property as shown below:
dynamic test = new ExpandoObject()
IDictionary<string, object> proxyFiler = test as IDictionary<string, object>;
proxyFiler["four"] = 4;
proxyFiler["5"] = 5;
int r = test.four; // Works
int s = test.5; // Doesn't work
A method which reads the database will return an "int" and I would like to be able to access the property value with that property name.
To expand on this: what if I wanted to do a linq query to sort out a list of dynamic objects according to a property name? In this case I need to get the propertyName which I have retrieved as a string e.g. "15":
return disorderedList.OrderBy(o => o.propertyName).ToList();
Does anyone know a simple solution to this problem or do you recommend a different approach? Thanks.
In order for dynamic to work in this way, the key has to follow the rules for valid identifier names in C# (the rules are specified in this outdated MSDN page, but also in the C# language specification). A single number (5) is not an allowed identifier name, which is why that doesn't work.
Note that you can still retrieve the value by using the type as a dictionary, in a similar manner to how you populated it.
As for your second example - you are never using value, so it has no effect. It's the same as just writing int r = test.four;
Edit:
I believe, given your approach, you'd need to cast to a dictionary:
return disorderedList
.OrderBy(o => ((IDictionary<string, object>)o)[propertyName]).ToList();

How to bind enums to dropdown list?

I used linq to get a set of Enums except one.This is my Linq
List<SyncRequestTypeEnum> lstDefaultSyncList = (List<SyncRequestTypeEnum>)(Enum
.GetValues(typeof(SyncRequestTypeEnum))
.Cast<SyncRequestTypeEnum>()
.Except(new SyncRequestTypeEnum[] { SyncRequestTypeEnum.ProjectLevel })).ToList();
SyncRequestTypeEnum is my enum class which has 3 Enums.
Here I am using (Enum.GetValues(typeof(SyncRequestTypeEnum)) so I am getting values. Now I am binding these values to dropdownlist as:
((DropDownList)control).DataSource = HtmlEncodeHelper.HtmlEncode(lstDefaultSyncList );
((DropDownList)control).DataBind();
This is not binding the actual enums. In UI it is displaying the values as System.Data.DataRowView. If I use GetNames instead of GetValues it is throwing a cast error
can someone help on this?

Sort a datagrid column by an enum type

I have a column in my DataGrid which displays some enumeration value. I set the SortMemberPath to my property which is represented by these enumerated values. However, when clicking on the column header, it won't sort on my enum because I haven't specified how to sort this type. It's an enum, so I can't exactly override the < operator. Any ideas?
UPDATE:
I'm trying to avoid a second property if I can. I can only set SortMemberPath = "MyEnumProperty". I can't tell it how to interpret that value.
_colDefs["Subtype"] = new DataGridTextColumn()
{
Binding = new Binding("") { Converter = new SubtypeConverter() },
SortMemberPath = "Subtype"
};
My property looks like this:
public SubtypeEnum Subtype { get; set; }
Try to specify property name in binding:
_colDefs["Subtype"] = new DataGridTextColumn()
{
Binding = new Binding("Subtype"),
SortMemberPath = "Subtype"
};
You even won`t need converter anymore (if it just converts to string).
You can cast an enum to int just by a hard cast:
(int)MyEnum.EnumValue
If you can add a fake property to your data structure that simply recasts its enumeration value to int, you ought to be able to sort it by that property, even if it's not visible.

What does each ComboBox.Selected... return?

Right now, to be sure I am getting what I want I am using
actionComboBox.Items[actionComboBox.SelectedIndex].ToString()
to retrieve the string that is stored as an item in my TextBox
Does one of the Selected properties return my above statement? I can never seem to get what I want when I use those.
Like, does actionComboBox.SelectedItem as string return the above value?
EDIT:
I guess the true question here is: What do each Selected Property return such as; SelectedItem, SelectedValue, SelectedText.
I think SelectedText returns the text that is selected if you are able to edit the text in the combo box. I don't think you use this property if you have the DropDownList style selected where the user cannot just type values into the combobox.
SelectedValue only applies if you are bind to a datasource. SelectedValue will return the item in the datasource you've selected, or if you have the DisplayMember field filled in, the value of the property/column that you have specified.
SelectedItem will return the selected item if you have just filled in the list items through the designer.
I get burned on these all the time, cause I always forget. The big question in your example is how are the items being populated into the combo box, that will affect the return values of these properties.
ComboBox.Items is a collection of System.Object's, so it can be anything. By default the ComboBox displays the return value of an object's ToString method. Whatever you add to the ComboBox will be what you will get back, though its returned as a System.Object and you will have to convert it back to its original type to access its members.
comboBox.Items.Add("foo");
The above will add a System.String to the ComboBox.
class Foo
{
public String Bar { get; set; }
}
Foo foo = new Foo();
foo.Bar = "Value";
comboBox.Items.Add(foo);
The above will add a Foo to the ComboBox. So to get your values back.
Object obj = comboBox.Items[comboBox.SelectedIndex];
Foo foo = obj as Foo;
if (foo != null) { // check just in case
}
For strings, there's no need for a conversion, calling ToString is fine. It's better to just use SelectedItem instead.
Foo foo = comboBox.SelectedItem as Foo;
if (foo != null) { // again, check to make sure
}
The power of the ComboBox is that since it stores a collection of System.Object, you can store multiple types of objects, but you are in charge of converting it back to whatever usable type it was to begin with when you need to access it.

Categories

Resources