ComboBox has its old value after Clear() - c#

I have two comboBox cb_Brand and cb_Model on a winForm.
cb_Model populates values on brand Select.
the problem is: if we select the brand any and select the any model under that brand, cb_Model does not loose the value of previous model selected.
for example: If we select the brand Audi and model A3
and the select the Brand Ford, when I click on cb_Model to select the model, it displayed the A3 as selected model, but still other models in list are belong to ford.
my code is:
private void cb_Brand_SelectedIndexChanged(object sender, EventArgs e)
{
// Clear Current Data
cb_Model.Text = "";
cb_Model.Items.Clear();
CarModel _carmodel = new CarModel ();
// Get Selected Car Brnad
int CarBrandID = _carmodel .GetCarBrandID(cb_Brand.Text);
//Enable choice of Model
SortedList<int, Model> colM;
colM = Model.ReadModel(CarBrandID);
cb_Model.DisplayMember = "ModelText";
foreach (Model objM in colM.Values)
{
cb_Model.Items.Add(objM);
}
}
Any Idea Please..
Thanks
unable to find the reason but sorted out with a temp fix:
private void cb_Model_Click(object sender, EventArgs e)
{
cb_Model.Text = "";
}
Thanks a lot guys
cheers

Instead of adding the items manually like this:
foreach (Model objM in colM.Values)
{
cb_Model.Items.Add(objM);
}
Let .NET take care of it for you and replace it with this:
cb_Model.DataSource = colMValues;
Which will bind the data to the list and refreshes the comboboxes items automatcially when a data source is set.
You will also not need these lines anymore:
// Clear Current Data
cb_Model.Text = "";
cb_Model.Items.Clear();
Have a read of this for more info on binding lists (and other data sources) to ComboBoxes:
How to: Bind a Windows Forms ComboBox or ListBox Control to Data (MSDN)

#w69rdy suggests an excellent solution.
The reason cb_Model did not change it's value is because you never changed the value. cb_Model.Items.Clear() does not change the selected index; only the items are removed from the combo box.
Using the code sample provided in your question:
// Clear Current Data
cb_Model.Text = "";
cb_Model.Items.Clear();
cb_Model.SelectedIndex = -1; // would effectively clear the previously selected value.

i had same problem now and Combobox's ResetText method solved the problem for me

This would work
combobox.ResetText();

I've tried your example. For me it worked as it should have.
You could try setting the cb_model.SelectedText to "" or SelectedItem to null

I found that keeping the scope of the data source near the loading of the combo box worked for me. I had a datatable with class level scope and it did not clear but then I brought it into function level scope and had it clear after the load and this worked.

I have a similar problem,tried cmb.resettext it clears text but not value.In my load form I have the below code:
Dim cmd As New SqlCommand("SELECT stud_id,name FROM student_details WHERE stud_id NOT IN (SELECT stud_id FROM student_details WHERE hostel_id!=0)", sqlcont.Conn)
Dim dr As SqlDataReader = cmd.ExecuteReader
Dim dat As New DataTable
Dim j As Integer
For j = 0 To dat.Rows.Count - 1
dr.Read()
Next
dat.Load(dr)
cmbstud.DisplayMember = "name"
cmbstud.ValueMember = "stud_id"
cmbstud.DataSource = New BindingSource(dat, Nothing)
dr.Close()
In my btnhostel click event I have the below code:
frmallocateHostel_Load(Nothing, Nothing)
this I put in attempt to reload my dataset and thus my comboboxes.Using cmbstud.resettext simply clears the text not the value.

I have same problem then I used
combobox1.SelectedIndex=-1
and it works.

Related

how to display custom text in data bound GridViewComboBoxColumn

I am working on RadGridView of telerik. I have a "GridViewComboBoxColumn" with a list of strings as data source.
Now the problem is that when I populate the grid view with data, it is possible that the value in data is not available in the strings data source for that column which results in blank value.
I tried setting DropDownStyle to RadDropDownStyle.DropDown but that doesn't change anything. And I just need to display the data even if that is not present in the drop down list.
Here is some code to help you understand it better.
Dim lstValues As New List(Of String)
lstValues.Add("Approved")
lstValues.Add("Declined")
lstValues.Add("Pending")
Dim col5 As GridViewComboBoxColumn = RadGridView1.Columns("column2")
col5.DataSource = lstValues
col5.DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDown
Now the row being added would be following.
RadGridView1.Rows.Add("Application Name", "Processing")
As you can see that column2 has no item named "Processing" so it is not displayed and showing as blank.
Thanks in advance for the help.
Regards
You can use the formatting events and set the cell text to whatever you need, however, note that the cell value will not be changed by this, but this is what you need as far as I can understand.
void radGridView1_CellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e)
{
if (e.Column.Name == "column2" && e.Row.Cells["someColumn"].Value == something)
{
e.CellElement.Text = "some text";
}
else
{
e.CellElement.ResetValue(LightVisualElement.TextProperty, ValueResetFlags.Local);
}
}

Filling two nested drop dwon list when editing an entry in c#

i have two nested drop down list.
one drop down show group,the other show sub group.
i have coded data source of subgroup drop down list on group drop down list selected indexed change event.
What I'm trying to do is set a drop down list to be whatever its value is in the database when editing an entry.
i have used data row.
i have two tables.documentgroup(GroupId,parentId,groupTitle,subGroupTitle) and documents(DocID,GroupID,Title,url)
in my drop down lists i have added list item like this
<asp:ListItem Text = "--select group--" Value = ""></asp:ListItem>
when i click on editing a document,i have this.
protected void grdDocuments_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "DoEdit")
{
GC.Collect();
GC.WaitForPendingFinalizers();
int DocID = Convert.ToInt32(e.CommandArgument);
ViewState["DocumentID"] = DocID;
ViewState["EditMode"] = "Edit";
DataTable dtDocuments = DataLayer.Documents.SelectRow(DocID).Tables["Documents"];
if (dtDocuments.Rows.Count != 0)
{
DataRow drDocuments = dtDocuments.Rows[0];
txtDocTitle.Text = drDocuments["DocTitle"].ToString();
txtDocPubYear.Text = drDocuments["DocPubYear"].ToString();
ddlDocGroupTitle.SelectedValue = drDocuments["ParentID"].ToString();
ddlDocSubGroupTitle.SelectedValue = drDocuments["DocGroupID"].ToString();
ViewState["DocCurrentUrl"] = drDocuments["DocUrl"].ToString();
mvDocuments.SetActiveView(vwEdit);
}
}
but i get this error
'ddlDocSubGroupTitle' has a SelectedValue which is invalid because it
does not exist in the list of items. Parameter name: value
and this is the same for ddldocgroupTitle.
i have made an inner join between two tables.
what should i do?
I could not really grasp your question, but it looks like you want to have 2 dropdown, and upon selection in the first, the second gets populated/filtered correct?!?
I recommend that you use javascript/Jquery to do so. Upon page load, issue a ajax get request to fill the "main" dropdown, and upon selection on the first one, you issue a second ajax request to fetch the possible values of the second one...
A alternative is to fetch the items for the first dropdown AND all the values possible for the second, storing the result in some hidden-field data. Then upon selection of the first value, you can only filter + display relevant data.

Adding custom options in bound dropdown in asp.net

I have a bound dropdown list populated with a table of names through a select, and databinding. it shoots selectedindexchanged that (through a postback) updates a certain gridview.
What happens is, since it runs from changing the index, the one that always comes selected (alexander) can only me chosen if you choose another one, then choose alexander. poor alexander.
What I want is to put a blanc option at the beginning (default) and (if possible) a option as second.
I can't add this option manually, since the binding wipes whatever was in the dropdown list and puts the content of the datasource.
Set the AppendDataBoundItems property to True. Add your blank, then data bind.
ddl.AppendDataBoundItems = true;
ddl.Items.Add("Choose an item");
ddl.DataSource = foo;
ddl.DataBind();
The AppendDataBoundItems property
allows you to add items to the
ListControl object before data
binding occurs. After data binding,
the items collection contains both the
items from the data source and the
previously added items.
protected void SetAddrList()
{
TestDataClassDataContext dc = new TestDataClassDataContext();
dc.ObjectTrackingEnabled = false;
var addList = from addr in dc.Addresses
from eaddr in dc.EmployeeAddresses
where eaddr.EmployeeID == _curEmpID && addr.AddressID == eaddr.AddressID && addr.StateProvince.CountryRegionCode == "US"
select new
{
AddValue = addr.AddressID,
AddText = addr.AddressID,
};
if (addList != null)
{
ddlAddList.DataSource = addList;
ddlAddList.DataValueField = "AddValue";
ddlAddList.DataTextField = "AddText";
ddlAddList.DataBind();
}
ddlAddList.Items.Add(new ListItem("<Add Address>", "-1"));
}
I created this code example using adventure works to do a little practice with Linq and it is very similar to the previous answer. Using linq still shouldn't matter for the answer the last dddlAddList.Items.Add is what you need. "Add Address" = first selected option and -1 = the value.

C# datagridview setting cell value stays null

I'm dynamically adding rows to a datagridview this way:
Question question = new Question();
List<Question> questions = question.GetQuestionsByQuestionnaire(questionnaireId);
if (questions != null)
{
dgvQuestions.Columns.Add("Question", "Vraag");
dgvQuestions.Columns.Add("QuestionType", "Vraag type");
dgvQuestions.Columns.Add("Category", "Categorie");
for (int i = 0; i < questions.Count; i++ )
{
int row = dgvQuestions.Rows.Add();
dgvQuestions.Rows[row].Cells["Question"].Value = questions[i].Question;
dgvQuestions.Rows[row].Cells["QuestionType"].Value = questions[i].QuestionType;
dgvQuestions.Rows[row].Cells["Category"].Value = questions[i].Category;
dgvQuestions.Rows[row].Tag = questions[i];
}
}
I don't get any errors, but the cell value stays null and I'm 100% sure that Question, QuestionType and Category contains data. What am i missing here?
I'm not sure about why this is the case, but I'd go for a mix of dynamic data but typed dataset.
What you'd do is:
Create a typed DataSet, add a "Questions" table with the columns you need
Put an instance of your DataSet from the Toolbox on your form (must recompile before that), name it for example myDataSource.
Put a BindingSource on your form, assign the myDataSource to the DataSource property and select your table for the DataMember property.
Assign the binding source to the DataSource property of your DataGridView
Add data to the data source by using for example myDataSource.Questions.NewQuestionsRow() and myDataSource.Questions.AddQuestionsRow(...).
I've just encountered something similar. You might want to make sure EnableViewState is set to True for your GridView.
Make sure VitualMode is set to False for your GridView.

SelectedItem/Index/ValueChanged events not raised when DataSource is Databound on ComboBox

I am trying to implement the following:
Two combo boxes on a Winforms form, the first has a list of parent categories, the second is children of the parent, the child list changes contents depending on the selection in the parent.
I'm trying to do this properly using databinding but I'm finding a strange quirk with the ComboBox control.
I set the datasource of the parent manually:
cboParent.DataSource = ParentDataSource where ParentDataSource is IList<ParentDTO>.
I can then bind the seletedItem to the DTO thus:
cboParent.DataBindings.Add(new Binding("SelectedItem", bindingSource, "Parent", true, DataSourceUpdateMode.OnPropertyChanged)); binding to Parent a ParentDTO object on my overarching DTO.
All pretty standard so far. This works and writes back the change to my DTO object as soon as I select anything new in the list, great!
I then bind the child combo box datasource to a list in the overarching DTO:
cboChild.DataBindings.Add(new Binding("DataSource", bindingSource, "Children", true, DataSourceUpdateMode.OnPropertyChanged)); where Children is an IList<ChildDTO> on the overarching DTO.
This also works fine and as soon as I change the parent selection the presenter changes the list Children on the DTO and the values shown in cboChildren changes, fantastic I hear you cry (and I did myself)!
Unfortunately it seems that if you're using databinding to set the datasource on a ComboBox the SelectedItemChanged, SelectedIndexChanged and SelectedValueChanged events don't fire at all, ever! This means that OnProperyChanged databinding won't work for the second combobox. OnValidation does work but it seems a little odd to me and I was wondering if anyone had encountered this before and if they'd worked out how to make it work?
Thanks in advance
Stu
I have derived the ComboBox for a few reasons, for example to support binding to null DTO's.
This helped me to insert this functinulity to fix the problem that Binding is not updated:
public new object SelectedItem
{
get
{
return base.SelectedItem;
}
set
{
base.SelectedItem = value;
if (value == null || value == System.DBNull.Value)
{
this.SelectedIndex = -1;
}
**foreach (Binding binding in DataBindings)
{
if (binding.PropertyName == "SelectedItem")
{
binding.WriteValue();
}
}**
}
}
You may want to do so also if property name is SelectedValue or selectedIndex.
If this helped someone please post back!
Best Regards,
Efy
well still need help? you need to create bindingSources and a aux textbox for a filter and use the handy property bindingSource.filter
Here is how:
Dim ds As New DataSet
Dim bind1 As New BindingSource
Dim bind2 As New BindingSource
'' here I add data to the dataset.. you MUST do your own populate way
ds.Merge(GetProducts) ' returns a dataset filled with products
ds.Merge(GetCategories) ' returns a dataset filled with categories
'' after the ds has data
' create binds
bind1.DataSource = ds
bind1.DataMember = "products"
' crete binds
bind2.DataSource = ds
bind2.DataMember = "categories"
txtMaster.DataSource = bind1
txtMaster.DisplayMember = "product_name"
txtMaster.ValueMember = "product_id"
txtDetails.DataSource = bind2
txtDetails.DisplayMember = "category_name"
txtDetails.ValueMember = "category_id"
txtAux.DataBindings.Add("Text", bind1, "product_id") ' bind1 contais products data
' this perform a filter on bind2... that contains categories data
Private Sub txtMaster_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMaster.SelectedIndexChanged
bind2.Filter = "product_id = '" & txtAux.Text & "'"
End Sub
hope it help

Categories

Resources