I'm trying to set a specific item as selectedItem in a DataGridComboBoxColumn. However a lot of research, I couln't find the right answer for me yet.
My scenario:
I have a programatically created a DataGrid which has an ObservableCollection<> as ItemsSource. As a last column, I want to add a DataGridComboBoxColumn to give the user a selection to choose from. Since such data can already be stored in the database, I need to "preset" the value from the collection stored in the database.
private void ManipulateColumns(DataGrid grid)
{
...
DataGridComboBoxColumn currencies = new DataGridComboBoxColumn();
//Here come the possible choices from the database
ObservableCollection<string> allCurrencies = new ObservableCollection<string>(Data.AllCurrencys);
currencies.ItemsSource = allCurrencies;
currencies.Header = "Currency";
currencies.CanUserReorder = false;
currencies.CanUserResize = false;
currencies.CanUserSort = false;
grid.Columns.Add(currencies);
currencies.MinWidth = 100;
//Set the selectedItem here for the column "Currency"
...
}
I found many tutorials for setting the selected item for normal ComboBoxes, but not for DataGridComboBoxColumns. I already tried it with currencies.SetCurrentValue(), but I can't find a suitable DependencyProperty from DataGridComboBoxColumn.
Can someone please help me out?
Thanks in advance.
Boldi
Building a DataGrid like that with C# code is messy. You should really take a look at using Data Binding instead. If you want to continue with building it in C#, then you are going to have to set the value per Row. There isn't a way to set a default for all the rows in a column. Say my DataGrid is bound to a collection of type Book. I can use the DataGrid SelectedItem property to get the Book object for the selected row, then set it's currency property. You're going to have to figure out what row you need to set the value for, get your object for that row, then set its currency property. This isn't a complete answer but it will get you started. Essentially, you are going to have to set it for each item in the DataGrid, not the column.
public class Book
{
public decimal price;
public string title;
public string author;
public string currency;
}
private void ManipulateColumns(DataGrid grid)
{
DataGridComboBoxColumn currencies = new DataGridComboBoxColumn();
//Here come the possible choices from the database
System.Collections.ObjectModel.ObservableCollection<string> allCurrencies = new System.Collections.ObjectModel.ObservableCollection<string>();
allCurrencies.Add("US");
allCurrencies.Add("asdf");
allCurrencies.Add("zzz");
currencies.ItemsSource = allCurrencies;
currencies.Header = "Currency";
currencies.CanUserReorder = false;
currencies.CanUserResize = false;
currencies.CanUserSort = false;
grid.Columns.Add(currencies);
currencies.MinWidth = 100;
//Set the selectedItem here for the column "Currency"
//currencies.
((Book)grid.SelectedItem).currency = "US Dollar";
}
Related
I'm having an issue when I select an item from a DataGridComboBoxColumn. The cell wont display the name of the item I've chosen after I move focus to the next cell. This is the code I have:
DataGridComboBoxColumn cb1 = new DataGridComboBoxColumn();
cb1.ItemsSource = listOStrings;
cb1.TextBinding = new Binding("listOfStrings");
e.Column = cb1;
e.Column.Header = "SomeTitle";
Where listOfStrings is a list that is being updated by the user. I have another DataGridComboBoxColumn that has its ItemSource set to a list of strings that isn't being updated. That one displays the text just fine, although the code for the two is the same. I'm wondering why my cb1 combo box wont display the values after leaving the cell but the other one does?
When a binding in WPF is hooked up to a non-static source, the underlying source needs to implement iNotifyPropertyChanged. In your case you may want to use an ObservableCollection as answered here: Why does a string INotifyPropertyChanged property update but not a List<string>?
In your case, it would look something like:
private ObservableCollection<string> _listOStrings = new ObservableCollection<string>();
public ObservableCollection<string> ListOStrings
{
get
{
return _listOStrings;
}
set
{
_listOStrings = value;
OnPropertyChanged("ListOStrings");
}
}
For more information on iNotifyPropertyChanged from MSDN, see:
See: https://msdn.microsoft.com/en-us/library/ms743695(v=vs.110).aspx
I've never done binding the way you are doing it - have you considered moving the UI to the XAML and databinding to a ViewModel? Here is an awesome step by step example on databinding comboboxes. You would just have the combobox be a column within the DataGrid also - similar to this.
I am trying to make a program that has a data grid that shows on each row, List of Ingredients the pizza has, the pizza name, and the price of the pizza. I can get the data grid to show the name and price, but i am having trouble getting it to show the list of ingredients. The data grid's datasource is a binding list of a class called Pizza.
class Pizza
{
private List<Ingredients> ingredientList_;
private string pizzaName_;
private decimal retailPrice_;
public Pizza(List<Ingredients> ingredientList, string pizzaName, decimal retailPrice)
{
ingredientList_ = ingredientList;
pizzaName_ = pizzaName;
retailPrice_ = retailPrice;
}
It has the basic get and set properties.
I also have an Ingredient class.
class Ingredients
{
private string name_;
private int servingSize_;
private int energyValue_;
private decimal purchasePrice_;
private bool isVegetarian_;
public Ingredients(string name, int servingSize, int energyValue, decimal purchasePrice, bool isVegetarian)
{
name_ = name;
servingSize_ = servingSize;
energyValue_ = energyValue;
purchasePrice_ = purchasePrice;
isVegetarian_ = isVegetarian;
}
Has the basic get and set properties.
In my form code, I have:
private BindingList<Pizza> pizzaList_;
pizzaList_ = new BindingList<Pizza>();
dataGridViewPizzaMenu.DataSource = pizzaList_;
Now my problem is that i am trying to use a combo box column to show the ingredients in a pizza when i click on it. But i can't seem to create a bound column for the Ingredients, only the pizza name and pizza price. Am i missing something or is what i am trying to do not possible?
Everything you've done appears correct. The problem I think is the way the DataGridView is setup at Design or Runtime.
If you head over to this answer you can see the steps you need to take:
Add all elements of array to datagridview rows except one
The trick with binding the 1st combobox column is a BindingSource. In design time > right click on the DataGridView > choose Edit Columns > select the first column > choose DataSource > click Add Project DataSource > choose Object > then tick the Ingredients class and click Finish.
Remeber to set the 1st ComboBox columns DataMember to ingredientList, you will need to select the IngredientsDataBindingSource control that was added (slightly below the Form Design's surface - in the gray area)
2nd and 3rd add two TextBox columns for pizzaName and retailPrice and set there DataPropertyName accordingly.
pizzaList_ = new BindingList<Pizza>();
//Insert code to populate the List of Pizza's and Ingredients
dataGridViewPizzaMenu.AutoGenerateColumns = false;
dataGridViewPizzaMenu.DataSource = pizzaList_;
ingredientsDataBindingSource.DataSource = pizzaList_.ingredientsList_;
ps There is a downloadable sample in the link I referred to above.
You can make a comboBox and set this event, next, with Datagridview1.Row.Add method insert a row in Datagridview. But before it, you should a DatagridviewRow with some cells, that own cell of this row is DataGrifViewComboBoxCell.
Good Luck...
In order to put combo box to third field you have to create first two as a datagridview items:
DataGridViewRow RowSample = new DataGridViewRow();
DataGridViewComboBoxCell pizzaItem = new DataGridViewComboBoxCell();
pizzaItem.DataSource = pizzaList_;
pizzaItem.Value = pizzaList_[0];
DataGridViewCell pizzaName = new DataGridViewTextBoxCell();
pizzaName.Value = pizza.pizzaName; // creating the text cell
DataGridViewCell pizzaPrice = new DataGridViewTextBoxCell();
pizzaPrice.Value = pizza.pizzaPrice;; // creating the text cell
RowSample.Cells.Add(pizzaName);
RowSample.Cells.Add(pizzaPrice);
RowSample.Cells.Add(pizzaItem);
SampleGridView.Rows.Add(RowSample);
Now RowSample added to you datagridview with 3 field, and the third one is combobox.
On the form load event
ingredientList_ = context.Ingredients.OrderBy(p => p.ingredientName).ToList();
FillCombo();
//Create a method to fill combo
private void FillCombo()
{
IngredientBindingSource.DataSource = ingredientList_;
}
I have table with 4 primary key fields. I load that in to drop down list in my WinForm application created by using C#.
On the TextChanged event of drop down list I have certain TextBox and I want to fill the information recived by the table for the certain field I selected by the drop down list.
So as I say the table having 4 fields. Can I get those all 4 fields into value member from the data set, or could you please tell me whether is that not possible?
Thank you.
Datatable dt=dba.getName();
cmb_name.ValueMember="id";
cmb_name.DisplayMember="name";
cmb_name.DataSource=dt;
this is normal format.. but i have more key fields.. so i need to add more key fields..
You can use DataSource property to bind your source data to the ComboBox (e.g. a List of Entities, or a DataTable, etc), and then set the DisplayMember property of the ComboBox to the (string) name of the field you want to display.
After the user has selected an Item, you can then cast the SelectedItem back to the original row data type (Entity, DataRow, etc - it will still be the same type as you put in), and then you can retrieve your 4 composite keys to the original item.
This way you avoid the SelectedValue problem entirely.
Edit:
Populate as follows:
cmb_name.DisplayMember = "name";
cmb_name.DataSource = dt;
// Ignore ValueMember and Selected Value entirely
When you want to retrieve the selected item
var selectedRow = (cmb_name.SelectedItem as DataRowView );
Now you can retrieve the 4 values of your PK, e.g. selectedRow["field1"], selectedRow["field2"], selectedRow["field3"] etc
If however you mean that you want to DISPLAY 4 columns to the user (i.e. nothing to do with your Table Key), then see here How do I bind a ComboBox so the displaymember is concat of 2 fields of source datatable?
cmb_name.DisplayMember = "name";
cmb_name.DataSource = dt;
DataRowView selectedRow = (cmb_name.SelectedItem as DataRowView );
The result will be here:
MessageBox.Show(selectedRow.Row[0].ToString());
MessageBox.Show(selectedRow.Row[1].ToString());
MessageBox.Show(selectedRow.Row[2].ToString());
MessageBox.Show(selectedRow.Row[3].ToString());
.....
If you want to get some data from a ComboBox in to a List you can use something like this
List<string> ListOfComboData = new List<string>();
ListOfComboData = yourComboBox.Items.OfType<string>().ToList<string>();
I have no real idea if this is what you mean as the question is very poorly structured. I hope this helps...
Edit: To put the selected text in to some TextBox use
yourTextBox.Text = youComboBox.Text;
in the SelectedIndexChanged event of your ComboBox.
You could follow the approach here with the following class:
public class ComboBoxItem
{
public string Text { get; set; }
public object[] PrimaryKey { get; set; }
}
private void Test()
{
ComboboxItem item = new ComboboxItem();
item.Text = "Item text1";
item.PrimaryKey = new object[] { primaryKey1, primaryKey2, primaryKey3, primaryKey4};
comboBox1.Items.Add(item);
comboBox1.SelectedIndex = 0;
MessageBox.Show((comboBox1.SelectedItem as ComboboxItem).Value.ToString());
}
I believe this question is kinda new-bie, but I can't solve it in correct way.
Brief description:
I have an inherited from ComboBox class that does some data bindings in constructor:
var mdl = new Model();
ValueMember = "id";
DisplayMember = "unit";
DataSource = mdl.getUnits();
All good here. The combobox is filled by required data.
Then I have another form with a function editIngridient. The function is following;
public bool editIngridient(int id)
{
currentId = id;
var row = mdl.getIngridient(id);
txtIngridient.Text = (string)row["ingridient"];
cmbUnit.ID = (int)row["unitId"];
numNotifyQty.Value = (int) row["notifyQty"];
ShowDialog();
return true;
}
Now, when the form popups, textbox and number box filled by needed values, while combobox is filled by first value.
If I will run the combobox data bind function as the first line inside editIngridient function - all works good.
Please point me to my stupidity.
Thanks a lot!
YOu didnt say what is your dataSource, but I assume thats DataTable, so you can do it:
DataRowView rowData = comboBox1.SelectedItem as DataRowView;
int id = Convert.ToInt32(rowData["id"]);
string name = rowData["unit"].ToString();
This may have been already asked but I can't seem to find this specific question, so here goes...
I have a form in C# where every textbox is bound to a field in a row. Rows can be cycled through by some buttons on the bottom but all the data displayed at a time in the from is from one row. Any changes that are made get updated back to the database when the user clicks "update"
One field (class) is an enumeration (0,1,2) where only the value is stored in the database, but doesn't mean much to the user. I was asked to make this more obvious to the user, so I decided to go with a dropdown style combo box. Since the database didn't have any reference to what the values meant, I decided to use the DataBindings instead of DataSource so I could just use the index as the data bind, but it seems that SelectedItem or Value are not the way to do this.
Here is my goal:
1 exists in database, so "B" is selected in combo box.
User selects "C" and updates the database, 2 is now stored in the database.
Any thoughts on what I need to get this working?
I assume you have a BindingSource on your form to bind to the data. You can bind the SelectedIndex property of the ComboBox as follows:
comboBox.DataBindings.Add("SelectedIndex", bindingSource, "PropertyInTheDataSource");
Actually I was able to bind it to a custom Object. It's a little too much work for such a simple task. But you have complete control on Display/Value pairs. Anyway, I thought I'd share and you decide:
Create a new class (say CustomItem) with 2 fields:
Public int Value{get;set;}
public string Title {get;set;}
Then in you form:
var item1 = new CustomItem() { Title = "A", Value = 10 };
var item2 = new CustomItem() { Title = "B", Value = 20 };
var item3 = new CustomItem() { Title = "C", Value = 30 };
var lst = new List<CustomItem>();
lst.Add(item1);
lst.Add(item2);
lst.Add(item3);
comboBox1.DataSource = lst;
comboBox1.DisplayMember = "Title";
comboBox1.ValueMember = "Value";
Now You have a databound combobox in case you don't have BndingSource in your form.
Just remember to define your class's Title and Value as properties otherwise it wouldn't work.