comboBox selected value change - c#

I'd like to give the customer an option to choose a city from COMBOBOX, and once the city's chosen, a list of that city's streets should be in COMBOBOX2. I tried the following code and I got an error, during the first run, maybe someone can explain this to me?
private void Search_by_Apartment_Load(object sender, EventArgs e)
{
List<Cities> city = DAL.cities();
cmBxCity.DataSource = city;//Here he ran the second function, why?
cmBxCity.DisplayMember = "city";
cmBxCity.ValueMember = "cityID";
}
private void cmBxCity_SelectedIndexChanged(object sender, EventArgs e)
{
List<Streets> street = DAL.streets(Convert.ToInt32(cmBxCity.SelectedText));
// List<Streets> street = DAL.streets(Convert.ToInt32(cmBxCity.SelectedValue));
comBxStreet.DataSource = street;
comBxStreet.DisplayMember = "street";
//cmBxCity.ValueMember = "cityID";
}

The SelectedIndexChanged event is fired whenever the selected index is changed programatically or by the user.
As Davide Pirsa points out, when you change the DataSource of cmBxCity, you are programatically changing the selected index, hence firing the 'cmBxCity.SelectedIndexChanged' event at this line:
cmBxCity.DataSource = city;//Here he ran the second function, why?
One possible solution is to use the SelectionChangeCommitted event instead, which is only fired for changes made by the user.

when you assign the DataSource of the cmBxCity control its selectedItem changes from nothing to one item and this triggers the event handler cmBxCity_SelectedIndexChanged.
in the question you are talking about COMBOBOX and COMBOBOX2 but in the code there is only one control which is: cmBxCity.
shouldn't you show the streets in the second control called: cmBxStreet ?

Related

Display cell value on textbox in c#

My problem is that it will only display the contents of datagrid on textboxes when i click on the cells under Price column which has a Money DataType all others except for ItemNo is Varchar(100). Please help, thanks
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DataGridViewRow row = this.dataGridView1.CurrentRow;
txtDsc.Text = row.Cells["Description"].Value.ToString();
txtQty.Text = row.Cells["Qty"].Value.ToString();
txtUnt.Text = row.Cells["Unit"].Value.ToString();
txtPrc.Text = row.Cells["Price"].Value.ToString();
txtRmr.Text = row.Cells["Remarks"].Value.ToString();
}
As the other answer pointed out the code seems to be working fine.
I suspect the event is not firing off. Try putting in a breakpoint and investigate that bit.
I am presuming you need CellClick instead of CellContentClick.
Refer CellContentClick event doesn't always work
Alternatively if you are trying to display the text box values based on the selection on the data grid view, use DataGridView.SelectionChanged Event
I'm not entirely sure why it is only populating when you click that cell; I recreated your code and it works just fine. I did manage to recreate it again using the following code:
private void myDGV_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int row = myDGV.CurrentCell.RowIndex;
txtDsc.Text = myDGV.Row[row].Cells["Description"].Value.ToString();
txtQty.Text = myDGV.Row[row].Cells["Qty"].Value.ToString();
txtUnt.Text = myDGV.Row[row].Cells["Unit"].Value.ToString();
txtPrc.Text = myDGV.Row[row].Cells["Price"].Value.ToString();
txtRmr.Text = myDGV.Row[row].Cells["Remarks"].Value.ToString();
}

ComboBox SelectedIndexChanged event fired twice for items with same DisplayMember

I have a combobox as below with 3 items ("abc", "abc" & "bbb").
The combobox also has AutoCompleteMode "SuggestAppend" & AutoCompleteSource "ListItems" properties. Now I want the text box to show the SelectedIndex of the combobox as below:
http://i.imgur.com/MJ4JdDN.png
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
this.textBox1.Text = this.comboBox1.SelectedIndex.ToString();
}
Everything seems fine until I select the 2nd "abc", the SelectedIndexChanged event will enter for the 1st time & display the index properly on the text box. But when the combobox lost focus, the SelectedIndexChanged event will fire again, causing the index to be displayed wrongly. I found that it only happens to items with the same value. Is there a way I can stop the event from firing twice?
http://i.imgur.com/gEw46xf.png
this.comboBox1.DataSource = dt;
this.comboBox1.DisplayMember = "Description"; //Some descriptive field to be shown in combobox
this.comboBox1.ValueMember = "Code"; //Unique code that user won't understand
this.comboBox1.SelectedIndex = -1;
put comboBox1_SelectedIndexChanged code in comboBox1_ValueChanged and there u'll get index in event arguments(sender i.e your comboBox cast it in combobox).
use comboBox1.SelectedIndex and u'll get the index.

How can I make a ComboBox auto post back in WinForms application?

I have a Windows Forms application for employees and when I select the employee name
from a ComboBox, textboxes should be filled with the data of the selected employee. I remember something like the auto postback property but I can't find it in Visual Studio.
Thanks in advance.
If you're using WinForms, there's no such thing as AutoPostBack, that is for ASP.NET. In your case use the SelectedIndexChanged-event. In this event you can get the selected item and based on this item, get the corresponding data of the employee and fill the textboxes.
More info:
MSDN: ComboBox.SelectedIndexChanged Event
Pseudo-code:
private void YourComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
string item = (string)YourComboBox.SelectedItem;
//Fetch data (dummy method)
Employee emp = GetDataByName(item);
//Write to TextBox
SomeTextBox.Text = emp.Function;
}
Winforms provides the following events:
SelectedIndexChanged Occurs when the SelectedIndex property has
changed. SelectedValueChanged Occurs when the SelectedValue
property changes.
You can read more about them here: MSDN Combobox.
You should use the SelectedIndexChanged event of the Combobox. Normally you'll get it when you double click to the ComboBox on your form.
In order to store a text with a value (suppose ID) and add it to the Combobox, follow this answer:
https://stackoverflow.com/a/11745699/870865
For an Example:
// On load event, add the items to the ComboBox following the above link I have posted...
private void cmbEmployees_SelectedIndexChanged(object sender, EventArgs e)
{
int EmployeeID = ((KeyValuePair<string, string>)cmbEmployees.SelectedItem).Value;
var Employee = SomeClass.getEmployeeByID(EmployeeID); // Write a class or a method to get Employee as an object...
txtName.Text = Employee.Name;
txtEmail.Text = Empolyee.Email;
}
Hope this gives you an idea!

Getting the old selected index in Winform's Combo box

I have a combo box (winform). This combo box has some items (eg. 1,2,3,4).
Now, when I change the selection within this combo, I wish to know the old index and the new index.
How do I get this?
Possible approaches that I wish to AVOID.
Add an enter event, cache the current index and then on selection index change get the new index.
Using the selected text/selected item property received by the sender of the event.
What I ideally want:
In the event args that are received, I want something like:
e.OldIndex;
e.newIndex;
Right now the event args which are received in the SelectionIndex Change event are totally useless.
I don't want to use more than one event.
If C#, does not offer this, can I have my event which passes the old index and new index as event args?
Seems like this is a possible duplicate
ComboBox SelectedIndexChanged event: how to get the previously selected index?
There is nothing built in, you will need to listen for this event and keep track in a class variable.
But this answer seems to suggest a sensible way of extending the combobox to keep track of the previous index
https://stackoverflow.com/a/425323/81053
1-Make a List of integers
2-Bind a Button to switch to previous Screen (button Name "prevB")
3-change the ComboBox Index as Per described in the code
//initilize List and put current selected index in it
List<int> previousScreen = new List<int>();
previousScreen.Add(RegionComboBox.SelectedIndex);
//Button Event
private void prevB_Click(object sender, EventArgs e)
{
if (previousScreen.Count >= 2)
{
RegionComboBox.SelectedIndex = previousScreen[previousScreen.Count - 2];
}
}
You will need to replace the ComboBox with the following control:
public class AdvancedComboBox : ComboBox
{
private int myPreviouslySelectedIndex = -1;
private int myLocalSelectedIndex = -1;
public int PreviouslySelectedIndex { get { return myPreviouslySelectedIndex; } }
protected override void OnSelectedIndexChanged(EventArgs e)
{
myPreviouslySelectedIndex = myLocalSelectedIndex;
myLocalSelectedIndex = SelectedIndex;
base.OnSelectedIndexChanged(e);
}
}
Now you can get the PreviouslySelectedIndex property.
You can use YourComboBox.Tag (or other unused string/int property) to store old selected index...
I use such pair
comboBox.SelectedItem new item
comboBox.SelectionBoxItem old item

DataGridViewCombBoxColumn cell value and different dropdown list

I've a very trivial requirement which makes me go nuts. I've a DataGridView in windows forms application. This contains one databound ComboBox Column. I'm using DisplayMember and ValueMember properties of that combobox.
Now my requirement is ComboBox should show the list of DisplayMembers in drop down list but when user selects one item from it, I should display the part of that DisplayMember in the combobox cell visible to the user. For example.
My display member list looks as below:
"Cust1 - Customer 1"
"Cust2 - Customer 2"
"Cust3 - Customer 3"
and when user selects any one of them from the above list (Say user selected 'Cust2 - Customer 2') then I need to display the value in the combobox column cell as only "Cust2" instead of complete DisplayMember text.
This DisplayMember list is a combination of two fields from the datasource bound to it i.e. First part points to CustomerCode field and second part points Customer name. I need to display only CustomerCode in the ComboBox cell after user selects one item from the drop down list.
How can I do this? Or should I come up with my own control which will have a different AutoCompleteCustomSource and display member value. Even I'm confused with that approach too.
Update: As no one has come up with any solution to my problem. Now I'm starting a bounty for that, also if anyone can suggest me other way to implement the same functionality, it would be great.
I've even tried to come up with my own control and tried to work on simple combobox to display a different value than the selected dropdown list, even that didn't work. Is there any other way to implement this? Any tips and tricks are greatly appreciable.
#Anurag: Here is the code which I've used.
Created a datagridview in the design mode. Created one column of type 'DataGridViewComboBoxColumn' that and named it as CustomerColumn.
In the designer file it looks like below:
private System.Windows.Forms.DataGridViewComboBoxColumn CustomerColumn;
This is the entity class which I've used for datasource
public class Customer
{
public int Id { get; set; }
public string CustCode { get; set; }
public string CustName { get; set; }
public string NameWithCode { get; set; }// CustCode - CustName format
}
In the form load event I'm doing the following:
CustomerColumn.DataSource = GetCustomers();
CustomerColumn.DisplayMember = "NameWithCode";
CustomerColumn.ValueMember = "Id";
I'm answering my own question because I've implemented my own solution to this by using custom control.
This custom control is created by keeping a textbox above combo box in such a way that only drop down button of combobox is visible.
Now I've created a custom column in datagridview deriving the DataGridViewEditingControl from my usercontrol.
I've added a property in Usercontrol which will take drop down list source from the control which is hosting datagridview.
Now in the EditingControlShowing event I'm setting this property as below
private void dataGridView2_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if(dataGridView2.CurrentCell.ColumnIndex.Equals(0) && e.Control is UserControl1)
{
var uscontrol = e.Control as UserControl1;
uscontrol.DropDownListSource = source;
}
}
This drop down list source is used in the usercontrol to set the autocompletesource to the textbox and datasource to the combobox as below:
Whenever I set the DropDownDataSource I'm firing an event in the usercontrol which will do the following. This is to ensure that every time EditingControlShowing event occurs for this column in DataGridView, this source is updated for textbox and combobox in usercontrol.
private void DropDownSourceChanged(object sender, EventArgs eventArgs)
{
textBox1.AutoCompleteCustomSource = DropDownListSource;
textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
comboBox1.DataSource = DropDownListSource;
}
Now whenever user starts typing in the textbox autocomplete source will display dropdown list with 'NameWithCode' values and if user selects one of them then I'll set it to the Text propery overidden in my usercontrol which will be used for the cell value in the DataGridView. Now based on the Textbox text (which is NameWithCode) I can get the code part and set it to the text property.
If user uses combobox dropdown button to select the item then I'll get the combobox selected text and set it in the Textbox which is ultimately used by the cell for getting value.
This way I could achieve the solution I want.
#Homam, solution also works but when I change the ComboBox's DropDownStyle to allow the user to type the value in the combobox it behaves weirdly and not getting up to the mark solution for my requirement. Hence I used this solution.
I know that this is not perfect solution, but I looked for a better one and I didn't find, so I went to a workaround
I did the following:
when the user open the ComboBox, I change the DisplayMember to "NameWithCode"
when the user close it, I return it to "CustCode"
You can Access to the ComboBox control by DataGridView.EditingControlShowing event for the DataGridView.
The code:
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
var comboBox = e.Control as ComboBox;
comboBox.DropDown += (s1, e1) => comboBox.DisplayMember = "NameWithCode";
comboBox.DropDownClosed += (s2, e2) =>
{
// save the last selected item to return it after
// reassign the Display Member
var selectedItem = comboBox.SelectedItem;
comboBox.DisplayMember = "CustCode";
comboBox.SelectedItem = selectedItem;
};
}
Note: You have to start the DisplayMember with "CustCode"
Good luck!
Each time at the offensive of event dataGridView1_EditingControlShowing there is addition of new handlers for events comboBox.DropDown and comboBox.DropDownClosed. It results in the increase of number of these handlers and their repeated calls. This code decides this problem.
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
var comboBox = e.Control as ComboBox;
comboBox.DropDown += comboBox_DropDown;
comboBox.DropDownClosed += comboBox_DropDownClosed;
}
private void comboBox_DropDown(object sender, System.EventArgs e)
{
var comboBox = sender as ComboBox;
if(comboBox != null)
{
comboBox.DropDown -= comboBox_DropDown;
comboBox.DisplayMember = "NameWithCode";
}
}
private void comboBox_DropDownClosed(object sender, System.EventArgs e)
{
var comboBox = sender as ComboBox;
if(comboBox != null)
{
comboBox.DropDownClosed -= comboBox_DropDownClosed;
var selectedItem = comboBox.SelectedItem;
comboBox.DisplayMember = "CustCode";
comboBox.SelectedItem = selectedItem;
}
}

Categories

Resources