Getting current value of comboBox in SelectedValueChange event - c#

I follow this instructions to create multi select combobox
So I have something like this:
var empList = db.GetTableBySQL($"exec getTaskAssignableEmployeeList");
checkBoxComboBox1.DataSource = new Utility.ListSelectionWrapper<DataRow>(empList.Rows, "Abbreviation");
checkBoxComboBox1.DisplayMemberSingleItem = "Name";
checkBoxComboBox1.DisplayMember = "NameConcatenated";
checkBoxComboBox1.ValueMember = "Selected";
checkBoxComboBox1.Tag = empList.Rows;
checkBoxComboBox1.SelectedValueChanged += ComboEmployee_SelectedValueChanged;
As you can see I have ComboEmployee_SelectedValueChanged Event. So when I click into one checkbox I want to retrieve value of comboBox as:
private void ComboEmployee_SelectedValueChanged(object sender, EventArgs e)
{
var db = new SQLConnMgr();
var employeeComboBox = sender as CheckBoxComboBox;
var taskDataRow = employeeComboBox.Tag as DataRow;
var taskTypeName = taskDataRow["Name"] as string;
}
But I'm getting error because taskDataRow is always null, then when it try to execute var taskTypeName = taskDataRow["Name"] as string; I'm getting:
Object reference not set to an instance of an object.'
Why I cant retrieve taskDataRow fro\m comboBox? Regards

If you want to know which items are selected, you have two options:
Use the CheckBoxItems property on the ComboBox which is a list of items wrapping each item in the ComboBox.Items list. The CheckBoxComboBoxItem class is a standard CheckBox, and therefore the bool value you are looking for is contained in Checked.
Or if you stored a reference to the ListSelectionWrapper<T>, you could use that to access the Selected property of the binded list.
-
if (ComboBox.CheckBoxItems[5].Checked)
DoSomething();
OR
if (StatusSelections.FindObjectWithItem(UpdatedStatus).Selected)
DoSomething();
You are getting Null Reference exception because you have saved table.Rows in the tag of the combobox not the DataRow in the below line that why you are getting exception.
var taskDataRow = employeeComboBox.Tag as DataRow;
To resolve the issue, Iterate through CheckBoxItems and there you can
get the selected item text. After that filter the data rows on the
basis of selected item text or value.

Related

Adding data only to a specific Column

I'm trying to find a way to add data from one datagrid to another and for that data to be inserted to only one column at a time in my second datagrid. The specific column is created each time the Add button has been clicked.
My coding so far:
private void btnFeedbackAddSupplier_Click(object sender, RoutedEventArgs e)
{
dgFeedbackSelectSupplier.Items.Clear(); //So that my rows do not stack each other on every add
DataGridTextColumn columnSupplier = new DataGridTextColumn();
columnSupplier.Binding = new Binding("Supplier");
DataGridTextColumn columnFeedbackSupplierItem = new DataGridTextColumn();
//The 'Item' column is binded in XAML
columnSupplier.Header = (cmbFeedbackSelectSupplier.SelectedItem as DisplayItems).Name;
columnSupplier.IsReadOnly = true;
dgFeedbackAddCost.SelectAll(); //Selects all the rows in 1st datagrid
//Casts selected rows to my 'ViewQuoteItemList' class
IList list = dgFeedbackAddCost.SelectedItems as IList;
IEnumerable<ViewQuoteItemList> items = list.Cast<ViewQuoteItemList>();
var collection = (from i in items let a = new ViewQuoteItemList { Item = i.Item, Supplier = i.Cost }
select a).ToList();
//Adds both the column and data to the 2nd datagrid
dgFeedbackSelectSupplier.Columns.Add(columnSupplier);
foreach (var item in collection)
dgFeedbackSelectSupplier.Items.Add(item);
}
My reason for wanting to add the data to only one separate column at a time is because the data is different each time I want to add it to my 2nd datagrid and it overwrites any previous data that was entered in older add's.
EDIT: I Here are some images of what my current problem is
Here I add the first company and it's values. Everything works fine
Here I add the second company with it's new values, but it changes the values entered with the first company. This is my big problem. So you can see how my values are changed from the first to the second image
I think your problem here is that all your columns are bound to the same property: Supplier. Since you're updating that property everytime, all columns are assigned the same value. In the end, there's only one Supplier property for each row, so you can't show a different value for that single property on each column since everytime you change that property's value, the Bindings get notified and update themselves.
Maybe you could try using a OneTime Binding instead of a regular one. That way, the cells would retain the value they had when you first added them to the DataGrid. But for that to work, you should avoid clearing the DataGrid's items list, since re-adding the items would force them to rebind again.
Another option would be having a list of suppliers in your Supplier property, and have each column bind to an index of that list.
private void btnFeedbackAddSupplier_Click(object sender, RoutedEventArgs e)
{
// ...
columnSupplier.Binding = new Binding(string.Format("Supplier[{0}]", supplierColumnIndex));
// ...
var supplierCosts = new List<int>();
// ...
// Fill the list with the Costs of the Suppliers that correspond to each column and item
// ...
var collection = (from i in items let a = new ViewQuoteItemList { Item = i.Item, Supplier = supplierCosts }
select a).ToList();
//Adds both the column and data to the 2nd datagrid
dgFeedbackSelectSupplier.Columns.Add(columnSupplier);
foreach (var item in collection)
dgFeedbackSelectSupplier.Items.Add(item);
}

how to set the default value to the drop down list in C#?

DataSet dsCurrency = new DataSet();
dsCurrency = ParamCurrency.SelectCurrencys();
ddCurrencyField.DataSource = dsCurrency;
ddCurrencyField.DataTextField = "CurrencyName";
ddCurrencyField.DataValueField ="CurrencyCode";
ddCurrencyField.DataBind();
How to select a default value to the dropdownlist control using C#?
If you know the value will exist:
ddCurrencyField.FindItemByText("YourDefaultText").Selected = true;
else
ListItem selectedListItem = ddCurrencyField.Items.FindItemByText("YourDefaultText");
if (selectedListItem != null)
{
selectedListItem.Selected = true;
};
You can also find item by value :
ListItem selectedListItem = ddCurrencyField.Items.FindByValue("YourDefaultValue");
if (selectedListItem != null)
{
selectedListItem.Selected = true;
};
I assume in your datasource object (dsCurrency) is not parsing the default value for the dropdown.
So first you will have to add the default item. After binding the datasource do the following.
ddCurrencyField.Items.Insert(0, new ListItem("-- Select --",0));
With the above code you will have a default/first item selected as "--Select--". If it does not select the first item then simply set the SelectedIndex to 0.
There are 2 ways to set the default item after populating a dropdown.
you can use the "SelectedValue" property
you can use the "SelectedIndex" property
Most of the code samples are given in the previous answers. But I prefer to use the "FindByValue" method.
ddCurrencyField.SelectedIndex = ddCurrencyField.Items.IndexOf(ddCurrencyField.Items.FindByValue(myValue));
If you want to write a safe code please use the second option.
If this dropdown list is a combobox, use this:
ddCurrencyField.SelectedIndex = ddCurrencyField.Items.IndexOf("Wanted Value");

How to get listbox selected item value

I am working with C# .NET 4.0
I am trying to get the value of a single selected item in a listbox.
This is how I populate the control:
this.files_lb.DataSource = DataTable object
In my designer, I have specified file_name as the DisplayMember and file_id as the DisplayValue
After selecting an item in the listbox, I tried the following to get the value:
this.files_lb.SelectedValue.ToString()
But all it returns is "System.Data.DataRowView".
At this link : Getting value of selected item in list box as string
someone suggested -
String SelectedItem = listBox1.SelectedItem.Value
However, 'Value' is not an option when I try this.
How can I get the ValueMember value from a single selected item in a listbox?
var text = (listBox1.SelectedItem as DataRowView)["columnName"].ToString();
Replace columnName with the name of the column you want to get data from, which will correspond with a column in your datasource.
Also watch out for nulls if there's no selected item.
It really should be this easy; I have the following in a click event for button to make sure I wasn't over simplifying it in my head:
private void button1_Click(object sender, EventArgs e)
{
string selected = listBox1.GetItemText(listBox1.SelectedValue);
MessageBox.Show(selected);
}
And the result:
Edit
It looks like your issue may be from not setting a property on the control:
Select the ListBox control
Click the little arrow to show the binding / items options
Select Use Data Bound Items
If I deselect that box, I get the exact same behavior you are describing.
var selectedValue = listBoxTopics.SelectedItem;
if (selectedValue != null)
{
MessageBox.Show(listBoxTopics.SelectedValue.ToString());
}
You may need to set the DataValueField of the listbox.
NewEmployeesLB.DataSource = newEmployeesPersons.DataList.Select(np => new
ListItem() { Text = np.LastName + ", " + np.FirstName, Value = np.PersonID.ToString() }).ToList();
NewEmployeesLB.DataTextField = "Text";
NewEmployeesLB.DataValueField = "Value";
NewEmployeesLB.DataBind();

Delete row from datatable based on condition

In my DataGrid I used a ComboBox in the first column, so it will fetch some data from the database using the DisplayMember and ValueMember concepts. Now I want to remove the value from the ComboBox which is previously selected.
Populating the ComboBox code is given below:
dTable = getDummyTable.GetDummyTble("Dummy", "DNO", "All");
dCmbData = dTable;
cmbDeno.DataSource = dTable;
cmbDeno.DisplayMember = "dyName";
cmbDeno.ValueMember = "dyRemarks";
The next row of selection there should not be a duplicate value in the ComboBox.
How can I achieve this?
Can anyone help me with this?
well try this one out. You have the DataTable which you are using to bind all combos (correct me if I'm wrong). Now all we need to do is that when an item is selected from any combo, we need to remove that item from all the other combos). You will need to declare a class level dictionary to store which combo had what value stored previously:
IDictionary<ComboBox, DataRow> _prevSelection;
//Please don't mind if syntax is wrong worked too long in web
comboBox.OnSelectedIndexChanged += fixItems;
private void fixItems(object sender, EventArgs e)
{
var cbo= sender as ComboBox;
if(cbo==null) return;
var prev = _prevSelection[cbo];
var row=<GET ROW FROM DATATABLE FOR CURRENT SELECTED VALUE>;
_prevSelection[cbo] = row;
UpdateOtherCombos(cbo, prev, cbo.SelectedItem.Value);
}
private void UpdateOtherCombos(ComboBox cbo, DataRow prev, object toRemove)
{
foreach(var gridrow in <YourGrid>.Rows)
{
var c = <FIND COMBO IN ROW>;
if(cbo.Id == c.Id) continue;//combo that triggered this all
var itemToRemove=null;
foreach(var item in c.Items)
{
if(item.Value == toRemove)
{
itemToRemove = item;
break;
}
}
//or you can get index of item and remove using index
c.Items.Remove(itemToRemove);
//Now add the item that was previously selected in this combo (that
//triggered this all)
c.Items.Add(new ComboBoxItem{Value = prev["ValueColumn"],
Text = prev ["TextColumn"]});
}
}
This is just to give you an idea that may help you to find an optimal solution rather than iterating over all combos as it will slow down if you have too many rows in grid or too many items in combos. Still even with this you need to put up some functions/code to make it working. Also please note that I have not worked on WinForms for some time and you need to check if things like ComboBoxItem etc. and any functions called on them exist. :)

Add 2 or more field to value member of C# coding

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());
}

Categories