Hi i am trying to fill a combo box but the value member is the same as the displaymember
this is my code:
private void Form1_Load(object sender, EventArgs e)
{
refresh();
}
public void refresh()
{
using (var context = new AppDbContext())
{
var piece = context.piece.Select(d => d.quantity);
comboBox1.DataSource = piece.ToList();
comboBox1.DisplayMember = "quantity";
comboBox1.ValueMember = "quantity";
}
}
I receive this error message: system.argumentexception 'cannot bind to the new display member. parameter name newdisplaymember'
having only the DisplayMember and the valuemember as = "" I don't get any problem, but I need to show and save the same data, what is the problem with my code?
Have you tried to not set ValueMember? Maybe if you don't set that, the value will be the same as the display one.
Related
I am working with WinForm in this i have 3 RadioButton one ComboBox and have three BindingSource
I want that when I check any of the RadioButtons, the values from the particular DataSources get bound to the ComboBox's ValueMember and DisplayMember.
The program has a SQL query where I want to send value based on the checked radio button.
private void rdbMed_CheckedChanged(object sender, EventArgs e)
{
cmbStock.DataSource = null;
cmbStock.DataSource = this.medicinesBindingSource;
this.cmbStock.DisplayMember = ""; //i want to bind "Med_ID" from medicinesBindingSource
this.cmbStock.ValueMember = ""; //"Med_Name"
}
private void rdbCat_CheckedChanged(object sender, EventArgs e)
{
cmbStock.DataSource = null;
cmbStock.DataSource = this.categoriesBindingSource;
this.cmbStock.DisplayMember = ""; //"category_Name"
this.cmbStock.ValueMember = ""; // category_ID"
}
private void rdbPharm_CheckedChanged(object sender, EventArgs e)
{
cmbStock.DataSource = null;
cmbStock.DataSource = this.pharmaceuticalBindingSource;
this.cmbStock.DisplayMember = "";// "Pharma_Name"
this.cmbStock.ValueMember = "";// "Pharma_ID"
}
Bellow are the parameter of the Query. It will help you to understand what I want to achieve.
if (rdbMed.Checked)
{
con.cmd.Parameters.AddWithValue("#Med_ID", cmbStock.ValueMember);
con.cmd.Parameters.AddWithValue("#category_ID", "");
con.cmd.Parameters.AddWithValue("#Pharma_ID", "");
}
else if (rdbCat.Checked)
{
con.cmd.Parameters.AddWithValue("#Med_ID", "");
con.cmd.Parameters.AddWithValue("#category_ID", cmbStock.ValueMember);
con.cmd.Parameters.AddWithValue("#Pharma_ID", "");
}
else if (rdbPharm.Checked)
{
con.cmd.Parameters.AddWithValue("#Med_ID", "");
con.cmd.Parameters.AddWithValue("#category_ID", "");
con.cmd.Parameters.AddWithValue("#Pharma_ID", cmbStock.ValueMember);
}
Easiest and the least pain way of doing this is resolving it inside SQL command and way to do it is cast your columns with AS VM and AS DM and make your DisplayMember = "DM" and ValueMember = "VM", so if you have sql query like SELECT USERID AS VM, NAME AS DM or SELECT PRODUCTID AS VM, NAME AS DM it will both work.
Problem later is if you do something with code and you may make mistakes trying to get USERID from databinding but it is instead VM. To avoid this you could "double select" values in query like SELECT USERID, NAME, ...., USERID AS VM, NAME AS DM this way you will have VM and DM for your controls but still hold original columns.
I have added a DataGridViewComboBox to a bound DataGridView (grdBOOK), the DataGridViewComboBox will replace column 3 to allow for user selection. I'm struggling to set the default of the DataGridViewComboBox equal to the value of column 3 so user selection is not required if the value is correct.
I pulled the code below from the net, but I get an error:
DataGridViewComboBoxCell value is not valid.
I thought a ComboBox cell could be treated as a normal DataGridView cell, but (see code below) an error is generated when a string is added to the ComboBox column? I've trawled the net and SO for a few days but nothing works, any suggestions please?
public void BOOK_COMBO2()
{
DataGridViewComboBoxCell cb_cell = new DataGridViewComboBoxCell();
DataGridViewComboBoxColumn cb_col = new DataGridViewComboBoxColumn();
// Contract field
cb_col.Items.AddRange("YEARLY", "MONTHLY", "");
cb_col.FlatStyle = FlatStyle.Flat;
cb_col.HeaderText = "newCONTRACT";
cb_col.Width = 50;
cb_col.ValueType = typeof(string);
// Add ComboBox and test
grdBOOK.Columns.Insert(5, cb_col);
grdBOOK.Rows[14].Cells[4].Value = "zzz"; // No error adding string to normal dgv column
grdBOOK.Rows[14].Cells[5].Value = "xxx"; // Error adding string to dgvcombobx column
//copy old values to new combobox and set as default
foreach (DataGridViewRow item in grdBOOK.Rows)
{
item.Cells[5].Value = item.Cells[3].Value;
}
//hide original column
grdBOOK.Columns[3].Visible = false;
}
After more research on the net, IMHO using a ContextMenuStrip is a better method of achieving this. Link here. A ContextMenuStrip has better methods, events, properties etc. I hope this helps others looking for a solution.
private void dataGridView1_DataError(object sender,
DataGridViewDataErrorEventArgs e)
{
// If the data source raises an exception when a cell value is
// commited, display an error message.
if (e.Exception != null &&
e.Context == DataGridViewDataErrorContexts.Commit)
{
MessageBox.Show("");
}
}
private void Form1_Load(object sender, EventArgs e)
{ dataGridView1.DataError +=
dataGridView1_DataError;}
public void DD_Location()
{
var ctx = new LCCDB_EF();
var query = ctx.tbl_Location;
CB_Location.DataContext = query.ToList();
}
private void CB_Location_DropDownClosed(object sender, EventArgs e)
{
textbox_test.Text =CB_Location.Text;
}
Output in Textbox
System.Data.Entity.DynamicProxies.Location_5E43C6C196972BF0754973E48C9C941092D86818CD94005E9A759B70BF6E48E6
Try this
if(null != CB_Location.SelectedItem)
textbox_test.Text = CB_Location.SelectedItem.ToString();
Without seeing your XAML I can't be sure, but are you sure you've bound the list correctly? Try setting the Items property of combobox to your list, rather than the data context. Depending on what the type is and what you'd like to bind the text to, you may need to set the DisplayMemberPath property as appropriate, too.
One article has Name and Price properties. I use Name property to display articles inside combobox cmbDataList like this
public Form1()
{
InitializeComponent();
cmbDataList.DataSource = GetData();
cmbDataList.DisplayMember = "Name";
}
After user selected the preffered article I want to use it's Price property to assign to textbox on the same form. So, how to access to that Price property?
private void cmbDataList_SelectedIndexChanged(object sender, EventArgs e)
{
//var sel = cmbDataList.SelectedItem;
}
You have to cast SelectedItem to proper object.
private void cmbDataList_SelectedIndexChanged(object sender, EventArgs e)
{
var sel = (YourObject)cmbDataList.SelectedItem;
txt.Text = sel.Price.ToString();
}
Unless all names are unique, you're going to need a unique identifier to reference, for example an articleID.
From here, set the ComboBox's ValueMember like so;
cmbDataList.ValueMember = "ID";
then you can get your value on the event handler;
private void cmbDataList_SelectedIndexChanged(object sender, EventArgs e)
{
var sel = cmbDataList.SelectedValue;
//From here you're going to need to find your article with that particular ID.
}
Alternatively. You could have your DisplayMember as the article name, and the price as the ValueMember, then get it in the event handler for SelectedIndexChanged in the same way i put above. SelectedValue will then return the price;
cmbDataList.ValueMember = "Price";
private void cmbDataList_SelectedIndexChanged(object sender, EventArgs e)
{
var yourSelectedPrice = cmbDataList.SelectedValue;
}
Assuming GetData() returns a table, you need to write the ValueMember also... like this:
InitializeComponent();
cmbDataList.DataSource = GetData();
cmbDataList.DisplayMember = "Name";
cmbDataList.ValueMember = "Price";
Now, your selected display will be synced with the value and you will be able to use it..
Get more info in here:
Populate combobox
You Need to set ValueMember You can set in this way
cmbDataList.ValueMember = "ID";
then you write the code on cmbDataList_SelectedIndexChanged Event
May be this will help you
var sel = cmbDataList.SelectedValue
I'm trying to bind separate ComboBox cells within a DataGridView to a custom class, and keep getting an error
DataGridViewComboBoxCell value is not valid
I'm currently assigning the data source for the cell to an IList<ICustomInterface> from a Dictionary I've got. Upon setting the data source however, the index for the ComboBoxCell isn't set, so it has an invalid value selected.
I'm trying to figure out how to get it to select a real value, e.g. the 0th item within the list it has been given to remove this error, or find another way to solve the problem. Anyone have any suggestions?
I managed to find the solution not long after posting the question. For anyone else:
The problem was that I was trying to assign the DataGridViewComboBoxCell.Value to an object, expecting that because the Cell was bound to a data source that it would automatically find the object in the source and update.
This wasn't actually the case, you actually need to set the value equal to that of the ValueMember property for it to correctly update the value and binding. I believe I was using a property 'Name' for both ValueMember and DisplayMember (controls how the renders in the cell) so setting the Value to interface.ToString() (rather than the interface instance) works for the majority of cases. Then I catch and ignore any DataError exceptions that occur while I'm changing the source around.
Here's my simple solution when using enums
ColumnType.ValueType = typeof (MyEnum);
ColumnType.DataSource = Enum.GetValues(typeof (MyEnum));
you can do that just after "InitializeComponent();"
Afters hours of trials, I finally found a solution that works.
// Create a DataGridView
System.Windows.Forms.DataGridView dgvCombo = new System.Windows.Forms.DataGridView();
// Create a DataGridViewComboBoxColumn
System.Windows.Forms.DataGridViewComboBoxColumn colCombo = new
System.Windows.Forms.DataGridViewComboBoxColumn();
// Add the DataGridViewComboBoxColumn to the DataGridView
dgvCombo.Columns.Add(colCombo);
// Define a data source somewhere, for instance:
public enum DataEnum
{
One,
Two,
Three
}
// Bind the DataGridViewComboBoxColumn to the data source, for instance:
colCombo.DataSource = Enum.GetNames(typeof(DataEnum));
// Create a DataGridViewRow:
DataGridViewRow row = new DataGridViewRow();
// Create a DataGridViewComboBoxCell:
DataGridViewComboBoxCell cellCombo = new DataGridViewComboBoxCell();
// Bind the DataGridViewComboBoxCell to the same data source as the DataGridViewComboBoxColumn:
cellCombo.DataSource = Enum.GetNames(typeof(DataEnum));
// Set the Value of the DataGridViewComboBoxCell to one of the values in the data source, for instance:
cellCombo.Value = "Two";
// (No need to set values for DisplayMember or ValueMember.)
// Add the DataGridViewComboBoxCell to the DataGridViewRow:
row.Cells.Add(cellCombo);
// Add the DataGridViewRow to the DataGridView:
dgvCombo.Rows.Add(row);
// To avoid all the annoying error messages, handle the DataError event of the DataGridView:
dgvCombo.DataError += new DataGridViewDataErrorEventHandler(dgvCombo_DataError);
void dgvCombo_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
// (No need to write anything in here)
}
That is all.
I had the same problem.
In my case the solution was to fill the data adapter of the Foreign key table. This was not being automatically filled and this was the cause of the problem.
In the Page_Load Event:
Me.TblUserTypesTableAdapter.Fill(Me.DonateDataSet.tblUserTypes)
For the sake of people not struggling as much as i did.
When binding the combo you are setting a DisplayMember (what the user will see)
and ValueMember (what your application will get).
After setting up these you need to set up the Value and this is where it fails.
Basically the TYPE of the value needs to be the same TYPE as the ValueMember.
So if your value member is an ID obviously its of type INT and you need to set your value to int for example Cell.Value = 1;.
I am having the same problem. After populating my ComboBox column in the (unbouod) DataGrid, I solved my problem by setting the ValueMember property of the DataGridViewComboBoxColumn
Apparently, just relying on the ToString() property of the objects in the ComboBox is not enough.
Actual code:
/// <summary>
/// Populate the dataGridSplitVolumes data grid with all existing qualifications for the plan.
/// </summary>
/// <param name="bonus"></param>
private void PopulateDataGridSplitVolumes(Bonus_Group bonus)
{
try
{
List<Qualification> qualifications = Qualification.Load(this.groupBonus.PlanID, this.ConnectionString);
foreach (Qualification qual in qualifications)
{
DataGridViewComboBoxColumn col = (DataGridViewComboBoxColumn)this.dataGridSplitVolumes.Columns[0];
col.Items.Add(qual);
}
SplitVolumeGrid_QualificationColumn.ValueMember = "Name";
}
catch (Exception ex)
{
#if DEBUG
System.Diagnostics.Debugger.Break();
#endif
throw ex;
}
}//PopulateDataGridSplitVolumes
use DataError Event handler,
private void shahriartableDataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
//You don't have to write anything here !
}
and your DisplayMember and ValueMember data type should be the same, in my case I have CountryName for both. Everything works fine for me...!!
Here's a complete example with a basic form and DataGridView added via the designer:
Setup and bindings:
private void Form1_Load(object sender, EventArgs e)
{
var colors = new List<Code>()
{
new Code() {Value= "R", Text = "Red"},
new Code() {Value= "G", Text = "Green"},
new Code() {Value= "B", Text = "Blue"}
};
var users = new List<User>()
{
new User() {Name = "Briana", FavoriteColor = "B"},
new User() {Name = "Grace", FavoriteColor = "G"}
};
var colorCol = new DataGridViewComboBoxColumn();
colorCol.DataSource = colors;
colorCol.DisplayMember = "Text";
colorCol.ValueMember = "Value";
colorCol.DataPropertyName = "FavoriteColor";
dataGridView1.Columns.Add(colorCol);
dataGridView1.DataSource = users;
}
Some classes:
public class Code
{
public string Value { get; set; }
public string Text { get; set; }
}
public class User
{
public string Name { get; set; }
public string FavoriteColor { get; set; }
}
Set a null value to the cell:
dataGridView.CurrentRow.Cells[NAME].Value = null;
I was having the same problem. The message was 100% spot on. The values for the combobox were like: Exact, StartsWith... and I was trying to set the value Exactă (not Exact). This was happening automatically as I was reading the DataTable for the DataGridView from an .xml file with DataTable.ReadXml(...). The values in the .xml file were off.