I have a WinForm. At this form I show data from table row.
I have tables Comments and Users:
Comments :{ ID(int),Text(NVarchar), UserId(int) }
Users: { ID(int), Name(NVarChar) }
At a form I have TextBox and Combobox. In Textbox I won't show "Text" from Comments (user can edit this field, data must be saved in a table) and Name from table Users (where Comments.UserId = Users.ID).
I have following code:
FormDataClassesDataContext dc = new FormDataClassesDataContext();
_comment = (from comment in dc.Comments
where comment.ID == 1
select comment).FirstOrDefault();
_user = (from users in dc.Users
where users.ID == _comment.UserId
select users).FirstOrDefault();
textBoxComment.DataBindings.Add("Text", _comment, "Text"); // <-OK
comboBoxAssessor.DataSource = dc.Users;
comboBoxAssessor.DisplayMember = "Name";
comboBoxAssessor.ValueMember = "ID";
comboBoxAssessor.DataBindings.Add("SelectedItem", _comment, "UserId");
and then
dc.SubmitChanges();
but I become "Unable to pass "MyApp.Forms.User" to "Int32"
The selected item of a combobox is the current object in its data source, in this case: a User. You must use SelectedValue:
comboBoxAssessor.DataBindings.Add("SelectedValue", _comment, "UserId");
which returns the value of the property you define in the ValueMember.
SelectedItem should be of type User if I don't make a mistake. And you bind Comment.UserId (int) to it.
Related
How can I save the correct ValueMember of a ComboBox to the entities/db?
My Winform has ComboBoxes that take Values from Entities of a Lookup Data tabel, as in the following code:
private void FillComboBoxes()
{
chargedToComboBox.Invalidate();
ModelCS ctx = new ModelCS();
var query1 = from a in ctx.LuDatas
where a.Category == "Charged To" && a.IsActive == true
select new { LuValueMember = a.LuValueMember,
LuDisplayMember = a.LuDisplayMember };
var chargedTo = query1.ToList();
chargedToComboBox.DataSource = chargedTo;
chargedToComboBox.DisplayMember = "LuDisplayMember";
chargedToComboBox.ValueMember = "LuValueMember";
string ch = chargedToComboBox.SelectedValue.ToString();
MessageBox.Show(ch); // variable ch shows the CORRECT
// ValueMember
chargedToTextBox.Text = ch; // variable ch show the UNDESIRABLE
// DisplayMember
this.Refresh();
}
On SaveChanges() I get the following error:
'System.Data.Entity.Validation.DbEntityValidationException' occurred in EntityFramework.dll
To find out what is happening, I added a TextBox to the form, and attempted to store in the what I thought was the ComboBox.ValueMember. To do this, I stored the the ComboBox.SelectedValue in a variable (ch) and and stored this variable in the TextBox.Text. What shows up in the TextBox.Text is the DisplayMember of the Combo, not the ValueMember.
To test why, I added a MessageBox to the code to see the vaslue of 'ch'; it shows the corresct value of the ValueMember.
How can it be that in the MessageBox 'ch' has one value and in the TextBox.Text it has another?
All I wanted was to extract a lookup list from the LuData entities, show the choices by name in the ComboBox and store the value by a code in the database.
Try this:
chargedToTextBox.Text = chargedToComboBox.SelectedItem.ToString();
I am new in Winform application, here i am using Entity framework, when i binding values to a combobox from sql table, i need to set first combobox item as "Please select", how can i set this..?
var qry = context.Tbl_EmployeeDetails.Where(x => x.IsDeleted == false).ToList();
if(qry!=null)
{
drpname.ValueMember = "RecordId";
drpname.DisplayMember = "Name";
drpname.DataSource = qry;
}
how can i set this first item as "please select" and value '0'
another suggestion in winform that..
how can i set value in a datagridview linkbutton column when i set 'Edit', 'Delete' columns are as linkbutton
You can insert that item in the beginning of the list.
Code:
var items = db.Tbl_EmployeeDetails.Where(x => x.IsDeleted == false).ToList();
items.Insert(0,new Tbl_EmployeeDetail() { RecordId= 0, Name = "[Please Select an Item]" });
drpname.DropDownStyle = ComboBoxStyle.DropDownList; //optional
drpname.ValueMember = "RecordId";
drpname.DisplayMember = "Name";
drpname.DataSource = items;
drpname.SelectedIndex = 0;
Screenshot:
Note
To have a hint in ComboBox without adding an item, take a look at following post:
Set hint or watermark or default text for ComboBox without adding it as item:
After you load your var qry which will be a List<string>
you want to do the following
var qry = context.Tbl_EmployeeDetails.Where(x => x.IsDeleted == false).ToList();
if(qry!=null)
{
drpname.ValueMember = "RecordId";
drpname.DisplayMember = "Name";
drpname.DataSource = qry;
drpname.Items.Insert(0, "--Please Select--");
drpname.SelectedIndex = 0;
}
Or you could have easily added it to qry since you are returning the data ToList()
for example
var qry = context.Tbl_EmployeeDetails.Where(x => x.IsDeleted == false).ToList();
qry.Insert(0, "--Please Select--");
if(qry!=null)
{
drpname.ValueMember = "RecordId";
drpname.DisplayMember = "Name";
drpname.DataSource = qry;
drpname.SelectedIndex = 0;
}
Your combobox cannot contain additional items if you are binding it to a data source. You have a few options here:
Don't bind it to a data source, i.e. populate it manually from your data set by looping through the items in your query and adding them individually to the combobox; this will allow you the opportunity to first add your "Please Select" item. This can be complicated because you will actually have to add the string names as the items in the combobox, and then you can set the item's Tag property to the actual query row to reference it later.
Include a fake item returned from your query that has a display member of "please select". Note, I don't recommend this approach because you're allowing your presentation logic to leak into your data/business layer.
Use a third-party control instead of the win forms combobox. I've used Infragistics and they have the ability to display a "suggestion" that's not actually in the list when nothing is selected.
I am using C# windows application. My code is as below
var categoryList = _objCategoryManager.GetAll();
cmbCategory.DisplayMember = "Name";
cmbCategory.ValueMember = "Id";
cmbCategory.DataSource = categoryList;
Here categoryList is of type IEnumerable. I want to insert item in ComboBox at 0 index i.e."--SELECT--"
You cannot insert item to your ComboBox after data binding. Instead insert the item in a copy of your data source before, then do the binding.
If categoryList is IEnumerable<T> and not a List<T> then you should copy it to a List<T> so that you can add your default value at the first index:
var categoryList = _objCategoryManager.GetAll().ToList();
categoryList.Insert(0, new Category {Id = -1, Name = "--SELECT--"});
Simply insert it into your list, so something like
var categoryList = _objCategoryManager.GetAll().ToList();
cmbCategory.DisplayMember = "Name";
cmbCategory.ValueMember = "Id";
categoryList.Insert(0, new Category() { Name = "--SELECT--"} );
cmbCategory.DataSource = categoryList;
categoryList.ToList().Find(o => o.ID == Convert.ToInt32(0)).Name = "--SELECT--";
Using LINQ, you can find the object you want to change (after binding) and modify that item.
Otherwise if you are adding an object into the list:
categoryList.ToList().Add(obj); // This should show the new item in the combo box
Ultimately your .GetAll() method should have returned the first one to be "--SELECT--" instead of trying to modify it afterwards.
I have a datagridview which I fill it as below :
var q= repository.GetStudents();//
dataGridView1.DataSource = null;
dataGridView1.Columns.Clear();
dataGridView1.DataSource = q;
dataGridView1.Columns.RemoveAt(1);
//Remove IsActive
//Cause I want to have my own implementation
dataGridView1.Columns[0].DataPropertyName = "StudentID";
dataGridView1.Columns[0].HeaderText = "Studunet ID";
dataGridView1.Columns[1].DataPropertyName = "IsActive";
dataGridView1.Columns[1].HeaderText = "Status";
The "IsActive" property is of boolean Type. When the "IsActive" cell is being displayed, it show true/false. I want to replace it with my own custom value.
I read this and this posts but I could not resolve my problem.
You can use the CellFormatting event of the DataGridView, e.g.:
void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
var grid = (DataGridView)sender;
if (grid.Columns[e.ColumnIndex].Name == "IsActive")
{
e.Value = (bool)e.Value ? "MY_TEXT_FOR_TRUE" : "MY_TEXT_FOR_FALSE";
e.FormattingApplied = true;
}
}
EDIT (as per comment):
It's very similar to what you're doing now, just remove the bound column and add a new column of the desired type and set the DataPropertyName properly e.g. :
this.dataGridView1.Columns.Remove("COL_TO_CUSTOMIZE");
var btnCol = new DataGridViewDisableButtonColumn();
btnCol.Name = "COL_TO_CUSTOMIZE";
btnCol.DataPropertyName = "COL_TO_CUSTOMIZE";
var col = this.dataGridView1.Columns.Add(btnCol);
Note that this append the column at the end, but you can decide the position of the column by using dataGridView.Columns.Insert method instead of Add.
One of the funky things about a DataGridViewComboBoxColumn is that you can give it one data source that has a column of values to lookup and a column of values to show, and you can bind it to another column of values and then it will perform the lookup for you
So, suppose your collection q of Students (or whatever they are) has an IsActive true/false and you want this to show as "All the time", or "Not a chance".. Let's hash together a combobox that does this:
var cb = new DataGridViewComboBoxColumn();
cb.DisplayMember = "DisplayMe"; //the related text to show in the combo
cb.ValueMember = "ValueToLookup"; //the name in the combo's lookup list
cb.DataPropertyName = "IsActive"; //the name of your property on Student, to look up
cb.DataSource = "All the time,Not a Chance"
.Split(',')
.Select(s => new { DisplayMe = s, ValueToLookup = (s[0] == 'A') } )
.ToList();
It doesn't really matter how we generat the combo's datasource; here I've made a string into a List<anonymous_string+bool> by splitting, then selecting a new anonymous type with the two property names I need; you can use anything that has some named properties - a List of KeyValuePair, Tuple, whatever..
The critical thing is that the combo can read the q.IsActive bool you cited in DataPropertyName, look that bool up in its list in the property named in the ValueMember, then display the property named in the DisplayMember. It works for editing too, so the user can choose a new item from the combo and the translation works back the other way - "what does the user choose? what is the value of its property named in ValueMember, put that value into the student IsActive property named in DataPropertyName".. And it doesnt stop at bools either; the value member can be anything - an int, date etc
I can't get value from ComboBox in WinForms using C#.
I have a ComboBox populated with a list of values and I have set ValueMember and DisplayMember.
Now, I have to find the value of the selected ComboBox item and select the matched item in UI.
Here is what I mean:-
I loaded the ComboBox like this :-
var list = (from l in db.Loc
orderby l.LName ascending
select l).ToList();
list.Insert(0, new Loc { ID = "-1", Name = "--Select--" });
cmb1.BindingContext = new BindingContext();
cmb1.DataSource = list;
cmb1.DisplayMember = "Name";
cmb1.ValueMember = "ID";
Now on an event, I am trying to match value (ID) and select the item. It's easy if I match Text property:
cmb1.Text = data.Name;
But How to match the value?
Something like this:-
cmb1.Value = data.ID;
If you only know the ID of the item you can also use:
cmb1.SelectedValue = data.ID;
This should work:
cmb1.SelectedValue = data.ID;
Why would you like to assign you "matched" value to the ComboBox Value property?
As soon as you have correctly set DisplayMember and ValueMember and you DataSource implements both as properties the values will be autoamatically "matched", e.g. you can read the Value property in you event handler to get this "matched" value.
data must be in the list binded to the combobox, then:
cmb1.SelectedItem = data
or, if it's not (you retrieved another instance from somewhere):
cmb1.SelectedValue = data.ID
First of all: cmb1.Text = text; changes the text of the ComboBox to the specified value. It doesn't select the item with the text that matchs the specified value.
Use cmb1.SelectedValue = value; to select the item with the speciefied value.
You can get the index using Combo1.SelectedIndex property. You can get the item using either Combo1.SelectedItem or Combo1.Items[Combo1.SelectedIndex]