I have a combobox bound to an enum (through a binding source). I'm populating the combobox as follows:
var list = new List<KeyValuePair<MyEnum, string>>();
list.Add(new KeyValuePair<MyEnum, string>(myEnum.Customer, "Customer"));
cbo.DataSource = list;
cbo.DisplayMember = "Value";
cbo.ValueMember = "Key";
And I also have this event:
private void cbo_SelectedValueChanged(object sender, EventArgs e)
{
if (cbo.SelectedValue == null)
return;
var value = (KeyValuePair<MyEnum, string>)cbo.SelectedValue;
var item = (MyEnum)value.Key;
if (item == MyEnum.Customer)
{ //Do someting... }
}
However, I'm getting the exception:
Specified cast is not valid
when setting cbo.ValueMember
What am I doing wrong?
If I recall correctly SelectedValue will only contain the Enum value in this case, as you have specified that the value is stored in the "Key" property with the line
cbo.ValueMember = "Key";
If you modify your code like this, it should work:
cbo.DisplayMember = "Value"; // Please note that it is important to set the DisplayMember
cbo.ValueMember = "Key"; // and ValueMember before assigning the DataSource
var list = new List<KeyValuePair<MyEnum, string>>();
list.Add(new KeyValuePair<MyEnum, string>(myEnum.Customer, "Customer"));
cbo.DataSource = list;
and
private void cbo_SelectedValueChanged(object sender, EventArgs e)
{
if (cbo.SelectedValue == null)
return;
var item = (MyEnum)cbo.SelectedValue;
if (item == MyEnum.Customer)
{ //Do someting... }
}
Related
I bind a ComboBox with a data source it shows the datasource in the dropdown but I want a default selected value.
Example:
"Select" is selected by default like shown in this picture.
In my Case result are show like this
This is my code:
public void BindComboBoxItem()
{
try
{
ItemRepository repo = new ItemRepository();
List<Item> items = repo.GetAll();
cbxSelectItem.DataSource = items;
cbxSelectItem.DisplayMember = "Name";
cbxSelectItem.ValueMember = "Id";
}
catch (Exception ex)
{
MessageBox.Show(MessageResource.ErrorMessage, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
If you want to have "Select" as your default selected value then you need to add it in your items and set
cbxSelectItem.SelectedIndex = //input the index of "Select"
which is 0 in the case of your first image link.
By setting the DropDownStyle the ComboBox always has a value selected. If you do not want this behavior you can only use the last line.
//This makes it so you have to select a value from the list, there is also 1 auto selected
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
//This makes sure we're selecting the value we want
comboBox.SelectedIndex = comboBox.Items.IndexOf( "value" );
If you want to add an item to tell people to select a value you can do this:
comboBox.Items.Insert(0, "Please select any value");
Note* this creates a selectable item, if you don't want this you can do this:
private void comboBox_TextChanged(object sender, EventArgs e)
{
if(comboBox.SelectedIndex <= 0)
{
comboBox.Text = "Please select a value";
}
}
private void Form_Load(object sender, EventArgs e)
{
comboBox.Text = "Please select a value";
}
It can be done using Key pair my code is here
private void BindComboBoxItem()
{
ItemRepository repo = new ItemRepository();
List<Item> items = repo.GetAll();
List<KeyValuePair<int, string>> allitems = new List<KeyValuePair<int, string>>();
KeyValuePair<int, string> first = new KeyValuePair<int, string>(0, "Please Select");
allitems.Add(first);
foreach (Item item in items)
{
KeyValuePair<int, string> obj = new KeyValuePair<int, string>(item.Id, item.Name);
allitems.Add(obj);
}
cbxSelectItem.DataSource = allitems;
cbxSelectItem.DisplayMember = "Value";
cbxSelectItem.ValueMember = "Key";
}
How can i get the value of outlet ID it on a comboBox?
here is my code to getting the values from Database and store it on a combobox.
public partial class Addstock : Form
{
String connectionString = ConfigurationManager.ConnectionStrings["TCConnectionString"].ConnectionString;
List<BOStockTransfer> StockList = new List<BOStockTransfer>();
int updateIndex = -1;
public Addstock()
{
InitializeComponent();
}
private void Addstock_Load(object sender, EventArgs e)
{
loadstock();
GetOutlets();
Getproduct();
GetGetWH();
cmdoutletID.Visible = false;
lbloutid.Visible = false;
cmdwh.Visible = false;
lblwh.Visible = false;
}
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletId";
}
}
Thank you for your help!
you are setting :
cmdoutletID.Visible = false;
what makes the combobox invisible
you have to set it as follows :
cmdoutletID.Visible = true;
After you added the images , the column name is outletID and Not outletId
so change your code as follows :
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletID";
cmdoutletID.ValueMember = "outletID";
cmdoutletID.Enabled = true;
}
}
The combo box has two properties which determine where it loads data from:
DisplayMember
ValueMember
The "ValueMember" property defines which named field populates the ListItem's "ValueProperty". That way, when you do combobox.SelectedItem.Value, you will get the value stored in the named field you specified for "ValueProperty".
Assuming that you are certain that your query is returning rows, perhaps try adding the items "manually" rather than relying on automatic databinding.
private void GetOutlets()
{
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
cmdoutletID.DisplayMember = "outletId";
cmdoutletID.ValueMember = "pkID";
cmdoutletID.BeginUpdate();
try
{
cmdoutletID.Items.Clear();
foreach (var row in ds_OutletList.Tables[0].Rows)
cmdoutletID.Items(new { outletid = row["outletid"], pkID = row["primaryKeyIDFieldName"] });
}
finally { cmdoutletID.EndUpdate(); }
}
Try this:
BOStockTransfer obj_StockTransfer = new BOStockTransfer();
DataSet ds_OutletList = obj_StockTransfer.GetOutlets(connectionString);
if (ds_OutletList.Tables[0].Rows.Count != 0)
{
cmdoutletID.DataSource = ds_OutletList.Tables[0];
cmdoutletID.DisplayMember = "outletname";
cmdoutletID.ValueMember = "outletId";
}
To capture selected value, for example on button click:
protected button1_Click(object o, EventArgs e)
{
var selectedId = cmboutletID.SelectedValue;
MessageBox.Show(selectedId);
}
In my winForm application I have added databound combobox column in a datagridview. User needs to be able to select an item from dropdown list or write in the combobox. But it wouldn't let me write in the combobox as datasource is set. This is my code:
var entityModel= new AdminEntities();
var filterPractice = (from b in entityModel.FILTER where b.PRACTICE != null select b.PRACTICE).Distinct().OrderBy(y => y);
dgvCboColumn(filterPractice, "PRACTICE");
private void dgvCboColumn(dynamic item, string colName)
{
int i = dgvLoadTable.Columns[colName].Index;
DataGridViewComboBoxColumn dgvCol = new DataGridViewComboBoxColumn();
dgvCol.DataSource=item;
dgvCol.DataPropertyName = colName;
dgvLoadTable.Columns.Insert(i, dgvCol);
dgvLoadTable.Columns[i].HeaderText = dgvLoadTable.Columns[i + 1].HeaderText;
dgvLoadTable.Columns[i + 1].Visible = false;
dgvLoadTable.Columns.RemoveAt(i + 1);
}
private void HandleEditShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
var cbo = e.Control as ComboBox;
if (cbo == null)
{
return;
}
cbo.DropDownStyle = ComboBoxStyle.DropDown;
cbo.Validating -= HandleComboBoxValidating;
cbo.Validating += HandleComboBoxValidating;
}
private void HandleComboBoxValidating(object sender, CancelEventArgs e)
{
var combo = sender as DataGridViewComboBoxEditingControl;
if (combo == null)
{
return;
}
if (!combo.Items.Contains(combo.Text))
{
var comboColumn = this.dgvLoadTable.Columns[this.dgvLoadTable.CurrentCell.ColumnIndex] as DataGridViewComboBoxColumn;
combo.Items.Add(combo.Text);
comboColumn.Items.Add(combo.Text);
this.dgvLoadTable.CurrentCell.Value = combo.Text;
}
}
Can anyone tell me how can I make the combobox editable, please?
you can manually get the items frm datasource using Oledb or Ado recordset nd fill de comboBox manually by using for loops.. so basically you can also edit the items..
I populate a sorted ListBox (lbCustomer) via datasource which is a BindingList. The BindingList contains Items (customer) with a bunch of properties. DisplayMember is property "name" and ValueMember is property "id". Now, when clicking an Item, I see in the ClickEvent my lbCustomer is the correct Item, but the SelectedValue is wrong. In fact lbCustomer.SelectedValue returns the id as if there was no sorting, so if I select the first item in my ListBox, it returns the actual first (not sorted) customer.id from my DataSource-BindingList. Is this the usual outcome? I thought using DisplayMember and ValueMember is to prevent this behavior. How might i prevent this (without the need to sort my BindingList in the begining)?
Here is my code for connecting my list- and combo-Boxes with the DataSource:
private void SelectCorrectBox(bool dependence)
{
DeactivateEvents();
ChangeItems(lbCustomer, null, Entity.DataSource.LbCustomer.CustomerSource, false);
if(!dependence)
ChangeItems(null, cbCustomer, Entity.DataSource.LbCustomer.CustomerSource, false);
ChangeItems(lbProdukt, null, Entity.DataSource.LbProdukt.ProduktSource, false);
ChangeItems(null, cbProdukt, Entity.DataSource.LbProdukt.ProduktSource, false);
//if(dependence)
ChangeItems(lbVersion, null, Entity.DataSource.LbVersion.VersionSource, false);
ChangeItems(lbKategorie, null, Entity.DataSource.LbKategorie.KategorieSource, false);
ChangeItems(lbFehler, null, Entity.DataSource.LbFehler.FehlerSource, true);
ActivateEvents();
}
private void ChangeItems(ListBox lb, ComboBox cb, object source, bool fehler)
{
if (cb == null)
{
lb.DataSource = source;
if (!fehler)
lb.DisplayMember = "name";
else
lb.DisplayMember = "titel";
lb.ValueMember = "id";
lb.SelectedIndex = -1;
}
else if (cb != null)
{
cb.DataSource = source;
cb.DisplayMember = "name";
cb.ValueMember = "id";
cb.SelectedIndex = -1;
}
}
Edit:
The solution was using SelectedItem instead of SelectedValue:
Before:
private void lbCustomer_SelectedValueChanged(object sender, EventArgs e)
{
EventStarter(lbCustomer.SelectedValue, "customer");
}
After:
private void lbCustomer_SelectedValueChanged(object sender, EventArgs e)
{
EventStarter(((Entity.Customer)lbCustomer.SelectedItem).id, "customer");
}
I have a DataSource bound to a LookUpEdit. For example I have 2 columns FirstName and LastName and I want to set DisplayMember property to these two columns.
I found that I should subscribe to lookUp_CustomDisplayText() and edit display text property like this:
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
LookUpEdit edit = sender as LookUpEdit;
if (e.DisplayText != "")
{
e.DisplayText = e.DisplayText + " " + (string)e.Value;
}
}
but I did not understand what e.Value is and I want to display another column for selected row, not the valuemember of selected row.
This is how I bind the datasource to lookupedit:
private void populateComboBoxForCompanyPerson()
{
lookUpCompanyPerson.Properties.ForceInitialize();
bs = new BindingSource(myDataSet, "CompanyPerson");
lookUpCompanyPerson.Properties.DataSource = bs;
lookUpCompanyPerson.Properties.DisplayMember = "CompanyName";
lookUpCompanyPerson.Properties.ValueMember = "PersonID";
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("PersonID"));
this.lookUpCompanyPerson.Properties.Columns["PersonID"].Visible = false;
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("FirstName"));
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("LastName"));
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("CompanyName"));
}
And this is what my datasource looks like:
I've changed Ian O'Brien's code a little bit and it works:
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
RepositoryItemLookUpEdit props;
if (sender is LookUpEdit)
props = (sender as LookUpEdit).Properties;
else
props = sender as RepositoryItemLookUpEdit;
if (props != null && (e.Value is int))
{
DataRowView row = props.GetDataSourceRowByKeyValue(e.Value) as DataRowView;
if (row != null)
{
e.DisplayText = String.Format("{0} {1}", row["FirstName"], row["LastName"]);
}
}
}
From the DevExpress documentation:
e.Value gets or sets editor's current value.
e.DisplayText gets or sets an editor's display text
The lookup editor's value is obtained from the data source field specified by the RepositoryItemLookUpEditBase.ValueMember property. The GetDataSourceRowByKeyValue method searches for the specified value within this field and returns an object representing the first found record.
The GetDataSourceRowByKeyValue method's return value depends upon the type of the underlying data source. If the data source is a System.Data.DataTable or a System.Data.DataView, this method returns a System.Data.DataRowView object. If the data source is a custom list of items, the appropriate list item is returned.
You want to set the e.Value to the value that you want to display in the control.
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
RepositoryItemLookUpEdit props
if (sender is LookUpEdit)
props = (sender as LookUpEdit).Properties;
else
props = sender as RepositoryItemLookUpEdit;
if (props != null && (e.Value is int))
{
object row = props.GetDataSourceRowByKeyValue(e.Value);
if (row != null)
{
e.Value = String.Format("{0} {1}", (DataRowView)row["FirstName"], (DataRowView)row["LastName"]);
e.Handled = true;
}
}
}
Finally, here are some useful pages with more documentation:
BaseEdit.CustomDisplayText Event
RepositoryItemLookUpEdit.GetDataSourceRowByKeyValue Method
i have use it, just like this;
cmb_tip.Properties.DataSource = _dt;
cmb_tip.Properties.ValueMember = "Value";
cmb_tip.Properties.DisplayMember = "Type";
cmb_tip.Properties.PopulateColumns();
cmb_tip.Properties.Columns["Value"].Visible = false;
This is how it works with LookupEditControl in Version 15.2.7 and a Class:
private void lookUpEditPatients_CustomDisplayText(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
{
var edit = sender as LookUpEdit;
var props = edit.Properties;
var pat = (Patients4ComboBoxVm) props?.GetDataSourceRowByKeyValue(e.Value);
if (pat != null)
{
e.DisplayText = pat.Nachname + ", " + pat.Vorname + "; " + pat.Geburtsdatum + "; " + pat.Versicherungsnummer;
}
}