I have a ComboBox which gets Text and Value fields from a DataTable object.
foreach (DataRow dr in dtSip.Rows)
{
cbxSipNo.Items.Add(new { Text = dr[0].ToString() ,Value = dr[2].ToString()});
}
cbxSipNo.ValueMember = "Value";
cbxSipNo.DisplayMember = "Text";
My problem is while accessing that specified Text and Value fields as below.
if (cbxSipNo.Items.Contains( new { Text= row.Cells[5].Value.ToString()} )
{
//some code
}
While doing contains, I couldn't figure out to access Text field. When i try without new syntax, it looks for Text and Value field combination. How can i do contains in the Text field of ComboBox?
One approach is to create a class.
class MyItem
{
public string Text { get; set; }
public string Value { get; set; }
}
And add your data row value to an object of an above class to combo box like
foreach (DataRow dr in dtSip.Rows)
{
cbxSipNo.Items.Add(new MyItem { Text = Convert.ToString(dr[0]), Value = Convert.ToString(dr[2]) });
}
And then you can cast your combo box items to above MyItem class and then check whether Any item present in combo box that contains your data row value
string str = row.Cells[5].Value;
if (cbxSipNo.Items.Cast<MyItem>().Any(x => Convert.ToString(str).Contains(x.Text)))
{
//some code
}
Related
How can I show Text in ComboBox when no item selected in Windows Application using LINQ C#
Here is my code how I get all rooms.... in Combobox.
private void LoadRoom()
{
try
{
db = new HotelEntities();
// cmbProvince.Text = "";
var Room = (from u in db.Room
select new { u.RoomId, u.RoomNumber }).ToList();
cmbRoom.Text = ".. Select.."; // This one do not working.
cmbRoom.DisplayMember = "RoomNumber";
cmbRoom.ValueMember = "RoomId";
cmbRoom.DataSource = Room;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Thank you!
If you set the DataSource of a combobox, a currencymanager is used on the background and its position is selected (the first item).
Instead of setting DataSource, try adding the items:
cmbRoom.Items.AddRange(Room);
NB, setting Text as a placeholder will not work if an item is chosen and cleared later, unless you add an extra check (in TextChanged or SelectedIndexChanged)
Fast solution
Create a source class for your ComboItems, with (at least) the properties to Display and the inner value of the property. If you create a generic class you can use it for all your combo boxes.
class ComboDisplay<TSource>
{
public string Display {get; set;}
public TSource Value {get; set;}
}
cmbRoom.DisplayMember = nameof(ComboDisplay.Display);
cmbRoom.ValueMember = nameof(ComboDisplay.Value);
When you create the data source for your combobox, make sure you add a default value. In the example below I assume that you want to select items of type Room in your combo:
IEnumerable<Room> availableRooms = myDbContext.Rooms
.Where(room => room.IsAvailable)
.Select(room => new ComboDisplay<Room>
{
Display = room.Name,
Value = new Room
{
Id = room.Id,
...
},
})
// add a dummy value if nothing is selected
.Concat(new Room[]
{
Display = "Please select a room",
Value = null, // meaning: nothing selected
});
After selection, use comboBox1.SelectedValue to get the selected Room, or null if nothing is selected.
Create a Special Combobox class
If you have to use this regularly, consider creating a generic sub class of ComboBox that can display items of a certain TSource, and will return null if nothing is selected:
class MyComboBox<TSource> : ComboBox
{
public MyComboBox() : base()
{
base.DataSource = this.EmptyList;
base.DisplayMember = nameof(ComboDisplay.Display);
base.ValueMember = nameof(ComboDisplay.Value);
}
private static readonly EmptyItem = new ComboDisplay
{
Display = "Please select a value",
Value = null,
}
Make a property that returns the available combo items. Make sure that the EmptyItem is always in the collection:
public IReadonlyCollection<TSource> ComboItems
{
get {return (IReadOnlyCollection<TSource>)base.DataSource;}
set
{
// TODO: check if the empty element is in your list; if not add it
base.DataSource = value;
}
}
Finally: the function to get the Selected value, or null if nothing is selected:
public TSource SelectedValue
{
get => return (TSource)base.SelectedValue;
set
{
// TODO: check if value is in ComboItems
base.SelectedValue = value;
}
}
I'm using ASP.NET to create a dynamic web form with variable controls. Some of the controls that I want to create are dropdownlists, and I would like them to be populated with certain custom subitems. How can I do this? I'm unable to populate the ddl with the subitems themselves (they are not of string type), but am also unable to populate the ddl with a string member variable (subitem.displayName) without losing the entire subitem. Here is some code for reference:
public class SubItem
{
string displayName;
string value;
...
}
At first I tried to add the objects to the ddl directly:
DropDownList x;
x.ItemType = SubItem; //error "type not valid in this context"
x.Add(subitem); // error
Ideally, I could solve this by displaying subitem.name in the ddl, but with the functionality of a subitem being parsed, so that in an event handler I can access all of the subitem's properties. Is there something like the following that exists?
DropDownList x;
x.ItemType = SubItem;
x.DisplayType = SubItem.displayName;
x.Items.Add(subitem);
Thanks in advance!
You can only bind something do a DropDownList that has and IEnumerable interface. Like a List or Array.
//create a new list of SubItem
List<SubItem> SubItems = new List<SubItem>();
//add some data
SubItems.Add(new SubItem() { displayName = "Test 1", value = "1" });
SubItems.Add(new SubItem() { displayName = "Test 2", value = "2" });
SubItems.Add(new SubItem() { displayName = "Test 3", value = "3" });
//create the dropdownlist and bind the data
DropDownList x = new DropDownList();
x.DataSource = SubItems;
x.DataValueField = "value";
x.DataTextField = "displayName";
x.DataBind();
//put the dropdownlist on the page
PlaceHolder1.Controls.Add(x);
With the class
public class SubItem
{
public string value { get; set; }
public string displayName { get; set; }
}
I'm trying to get the Tag associated to a value of ComboBox like this way:
var league = ((ComboBoxItem)this.League.SelectedValue).Tag.ToString();
Console.WriteLine(league);
The compiler show me a Invalid Cast Exception
I only want to get the associated Tag of the selected value by user, in particular:
(combobox value and Tag)
-Italy (item) - 10 (Tag)
-France (item) - 12 (Tag)
If the user select Italy, in the code I must get "10". But I can't do this, what am I doing wrong?
UPDATE (Populate combo):
List<RootObject> obj = JsonConvert.DeserializeObject<List<RootObject>>(responseText);
foreach (var item in obj)
{
foreach (var code in nation_code)
{
if (code.Equals(item.League))
{
League.Items.Add(item.Caption);
//link for each team
League.Tag = item.Links.Teams.href;
}
}
}
If you see the Tag is setting for the combo box itself and not for its individual item.
You can build a dictionary and use it as datasource of your combo box. Specify the value and display members of the combo box with dictionary key and value attributes
Try modifying the combo population logic as follows -
List<RootObject> obj = JsonConvert.DeserializeObject<List<RootObject>>(responseText);
Dictionary<string, string> comboSource = new Dictionary<string, string>();
foreach (var item in obj)
{
foreach (var code in nation_code)
{
if (code.Equals(item.League))
{
comboSource.Add(item.Caption, item.Links.Teams.href);
}
}
}
League.ValueMember = "Value";
League.DisplayMember = "Key";
League.DataSource = comboSource;
And then the required values can be fetched using the selectedText and selectedvalue properties.
League.SelectedText; //Return the "item.Caption"
League.SelectedValue; //Return the "item.Links.Teams.href"
For WPF we need to use different properties viz. ItemsSource,
DisplayMemberPath and SelectedValuePath while binding the combo
box. The above solution is for win forms.
You can add any type of object to a ComboBox, it does not need to be a string, it just needs to overwrite .ToString().
You could define a class:
class League {
public string Country { get; set; }
public int Id { get; set; }
public override string ToString() {
return Country;
}
}
and then just add these objects to the ComboBox:
comboBox.Items.Add(new League { Country = "France", Id = 10 });
You can then just cast the SelectedItem of your comboBox back to your class:
var selectedLeague = (League)comboBox.SelectedItem;
//access selectedLeague.Country;
//access selectedLeague.Id;
I'm setting the value member and display member from a datareader to combobox like this.
public void getPartyNamesCombo()
{
SqlDataReader reader = new VotingOP().getPartyNamesToCombo();
while (reader.Read())
{
cmbPartyName.Items.Add(new { PartyID = reader["partyID"].ToString(), PartyName = reader["partyName"].ToString() });
}
cmbPartyName.ValueMember = "PartyID";
cmbPartyName.DisplayMember = "PartyName";
}
I'm trying to access the id like this
int selectedValue = (int)cmbPartyName.SelectedValue;
MessageBox.Show("Selected value is"+selectedValue);
but it gives me "An unhandled exception of type 'System.NullReferenceException'" Exception. What's wrong I'm doing here?
I suggest the following approach:
First: you create some class for your data items:
class MyDataItem
{
public string PartyID { get;set; }
public string PartyName { get;set; }
}
Second: you use it in place of your anonymous object:
public void getPartyNamesCombo()
{
SqlDataReader reader = new VotingOP().getPartyNamesToCombo();
while (reader.Read())
{
cmbPartyName.Items.Add(new MyDataItem() {
PartyID = reader["partyID"].ToString(),
PartyName = reader["partyName"].ToString()
});
}
cmbPartyName.ValueMember = "PartyID";
cmbPartyName.DisplayMember = "PartyName";
}
Third: finally you are now able to cast your selected item to the custom data item and get its properties:
MyDataItem selectedItem = cmbPartyName.SelectedItem as MyDataItem;
if (selectedItem != null)
{
MessageBox.Show(String.Format("You've just selected the '{0}' party with the ID {1}", selectedItem.PartyName, selectedItem.PartyID));
}
Notice here that I used the SelecetedItem which gives you the whole object unlike the SelectedValue where you only get the PartyID.
If you later change your mind and want to show other properties they will already be available.
If there is no selected value currently then the cmbPartyName.SelectedValue will return null. First you need to get the selected value and check if it is not null:
object selectedValue = cmbPartyName.SelectedValue;
if (selectedValue != null)
{
// Now convert the selected value to integer.
int selectedPartyID = (int)selectedValue;
// And now you can handle the integer.
// ...
}
else
{
// There is no value selected...
}
I have one form in a Windows application as per below image:
I try to use this code to display text in comboBox in "Designer.cs":
this.cmbLanguage.FormattingEnabled = true;
this.cmbLanguage.Items.AddRange(new object[] {
Language.LSelectLang.LANGUAGE_ENGLISH, //"English",
"Chinese_TC",
"Chinese_SC",
Language.LSelectLang.LANGUAGE_GERMAN, //"German",
Language.LSelectLang.LANGUAGE_FRENCH, //"French",
Language.LSelectLang.LANGUAGE_JAPANESE, //"Japanese",
Language.LSelectLang.LANGUAGE_SPANISH, //"Spanish",
Language.LSelectLang.LANGUAGE_HINDI}); //"Hindi"});
It's OK with it, but I want to also pass a value type to access specific text display in combo box.
So, how to pass that in my combo box?
Unluckily, Win Form does not define ListItem like Web, but you can define your own class, then override ToString method:
public class YourItem<T>
{
public string Text { get; set; }
public T Value { get; set; }
public override string ToString()
{
return Text;
}
}
Then you can use:
var item = new YourItem<string>() {
Text = "text",
Value = "value"
};
cmbLanguage.Items.Add(item);
To access value:
var selectedItem = (YourItem<string>) cmbLanguage.SelectedItem;
var value = selectedItem.Value;