I got a problem with a ListBox in a WinForm application. I have two ListBoxes inside of a tab control and depending on the selection in the first one (lb1), the DataSource of the second one (lb2) changes. This is done in the SelectedValueChanged Event.
private void listBox_ControlUnits_SelectedValueChanged(object sender, EventArgs e)
{
ControlUnit unit = (sender as ListBox).SelectedItem as ControlUnit;
textBox_ProjectNameTab.Text = unit.ProjectName;
listBox_ControlCircuits.DataSource = null;
listBox_ControlCircuits.DataSource = unit.ControlCircuits;
}
lb1 is filled with a DataSource, too.
Now if I select a value in lb1 the selection automatically jumps back to the first item and I can not figure out why. is this some kind of UI update problem?
Even without the SelectedValueChanged event and the connection to the second listbox the issue occures.
Short gif of the problem, sorry for the blurriness
If I select one item more than once it works somehow (as seen in the gif).
Edit:
I found the problem but I do not quite understand what happens.
I have another listBox on another tab of my tab control. This listBox has the same DataSource as lb1. This seems to cause this behavior.
I finally found the problem:
I did not know that if I use the same DataSource for two ListBoxes they share the BindingContext per default.
I created a new BindingContext for the second ListBox and now the selection does no longer change.
listBox_allGroups.DataSource = null;
listBox_allGroups.DataSource = x.y;
listBox_allGroups.DisplayMember = "Name";
listBox_ControlUnits.DataSource = null;
listBox_ControlUnits.DataSource = x.y;
listBox_ControlUnits.DisplayMember = "Name";
listBox_ControlUnits.BindingContext = new BindingContext();
You can use a variable to hold the selected item
object _selecteditem=null;
and check it in ListBox click event.
prive void ListBox1_Click(object sender,EventArgs e)
{
if(ListBox1.SelectItem == _selecteditem) return;
// do ...
}
Related
I have five RadioButton and five ComboBox controls.
Each RadioButton is connected to a ComboBox.
When I activate one RadioButton, the corresponding ComboBox, it gets enabled.
Now when I choose another RadioButton, the information in the previously selected ComboBox should clear but does not!
I have tried with ComboBox.Clear() as well as ComboBox.Reset(), but it doesn't work.
Here is my code for one of the ComboBox and RadioButton
if (radioButtondinner.Checked == true)
{
comboBoxdinner.DataSource = DList.Dwork();
comboBoxdinner.DisplayMember = "dinner";
}
As I said in comment: you can use one Combobox and only to change data sources when you check other RadioButton that should work sure
But If you want to have more Combobox then just type in else statements
comboBox.DataSource = null;
// create a check change event and use this.
private void radioButtondinner_CheckedChanged(object sender, EventArgs e)
{
if (!radioButtondinner.Checked)
{
// if you want to clear only the text or selected item text
comboBoxdinner.Text = String.Empty;
// if you want to clear the entire data source
comboBoxdinner.DataSource = null;
}
}
I have a specific problem with a combobox in visual studio.
I use it to let the user type text in the textbox part of the combobox which immediately starts a SQL requst.
The result should be displayed in the dropdownlist part of the combobox.
(DropDownStyle is set to DropDown)
private void UpdateParent(object sender, EventArgs e)
{
ParentListChange(); //Update the listitems
//prevent from opening at the beginning
if (!ParentSelect.Text.Trim().Equals(""))
{
//my problem
ParentSelect.DroppedDown = true;
Cursor.Current = Cursors.Default;
}
}
But as soon as the drop down opens the first item gets selected and the whole text of it will paste into the textbox.
So if you start to write more then one letter in a row the first one "disappears" because the second typed letter replaces the selected text.
I know there is a similar post but the answeres did not help since they would be to slow (user would have to wait for about a second to type on):
private void comboBox1_TextUpdate(object sender, EventArgs e)
{
var savedText = comboBox1.Text;
comboBox1.DroppedDown = true;
comboBox1.Text = savedText;
comboBox1.Select(savedText.Length, 0);
}
Or would not worke with opening the drop down list, which is essential:
comboBox1.DropDownStyle = ComboBoxStyle.DropDown;
comboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
comboBox1.AutoCompleteSource = AutoCompleteSource.ListItems;
Is there a way to just disable the "select first item" thing?
One way to achieve is to have custom user control.
You can have a TextBox overlapping your ComboBox.
So, user will be interacting with Textbox only, and as per text entered in TextBox(using appropriate Event - key press will be fine), you can query in database and load ComboBox with the result of query.
I have a databound combobox:
using(DataContext db = new DataContext())
{
var ds = db.Managers.Select(q=> new { q.ManagerName, q.ManagerID});
cmbbx_Managers.BindingContext = new BindingContext();
cmbbx_Managers.DataSource = ds;
cmbbx_Managers.DisplayMember = "ManagerName";
cmbbx_Managers.ValueMember = "ManagerID";
}
When the form loads neither item is selected, but when the user chooses an item it cannot be deselected. I tried to add cmbbx_Managers.items.Insert(0, "none"), but it does not solve the problem, because it is impossible to add a new item to the databound combobox.
How do I allow a user to deselect a combobox item?
To add an item to your databound ComboBox, you need to add your item to your list which is being bound to your ComboBox.
var managers = managerRepository.GetAll();
managers.Insert(0, new Manager() { ManagerID = 0, ManagerName = "(None)");
managersComboBox.DisplayMember = "ManagerName";
managersComboBox.ValueMember = "ManagerID";
managersComboBox.DataSource = managers;
So, to deselect, you now simply need to set the ComboBox.SelectedIndex = 0, or else, use the BindingSource.CurrencyManager.
Also, one needs to set the DataSource property in last line per this precision brought to us by #RamonAroujo from his comment. I updated my answer accordingly.
The way you "deselect" an item in a drop-down ComboBox is by selecting a different item.
There is no "deselect" option for a ComboBox—something always has to be selected. If you want to simulate the behavior where nothing is selected, you'll need to add a <none> item (or equivalent) to the ComboBox. The user can then select this option when they want to "deselect".
It is poor design that, by default, a ComboBox appears without any item selected, since the user can never recreate that state. You should never allow this to happen. In the control's (or parent form's) initializer, always set the ComboBox to a default value.
If you really need a widget that allows clearing the current selection, then you should use a ListView or ListBox control instead.
To deselect an item suppose the user presses the Esc key, you could subscribe to the comboxBox KeyDown event and set selected index to none.
private void cmbbx_Managers_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape && !this.cmbbx_Managers.DroppedDown)
{
this.cmbbx_Managers.SelectedIndex = -1;
}
}
In winforms, you need to click the combobox twice to properly activate it - the first time to focus it, the second time to actually get the dropdown list.
How do I change this behavior so that it activates on the very first click?
This is for DATAGRIDVIEW combobox.
I realize this is an old question, but I figured I would give my solution to anyone out there that may need to be able to do this.
While I couldn't find any answers to do exactly this... I did find an answer to a different question that helped me.
This is my solution:
private void datagridview_CellEnter(object sender, DataGridViewCellEventArgs e)
{
bool validClick = (e.RowIndex != -1 && e.ColumnIndex != -1); //Make sure the clicked row/column is valid.
var datagridview = sender as DataGridView;
// Check to make sure the cell clicked is the cell containing the combobox
if(datagridview.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn && validClick)
{
datagridview.BeginEdit(true);
((ComboBox)datagridview.EditingControl).DroppedDown = true;
}
}
private void datagridview_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
datagridview.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
The above code must be tied into the CellEnter event of the datagridview.
I hope this helps!
edit: Added a column index check to prevent crashing when the entire row is selected.
Thanks, Up All Night for the above edit
edit2: Code is now to be tied to the CellEnter rather than the CellClick event.
Thanks, HaraldDutch for the above edit
edit3: Any changes will committed immediately, this will save you from clicking in another cell in order to update the current combobox cell.
Set the following on your DataGridView:
EditMode = EditOnEnter
This is probably the easiest solution and has been the workaround for many users here on SO when this question gets asked.
EDIT :
Per here do the following:
Set the Editmode:
EditMode = EditOnKeystrokeOrF2
Modify the EditingControlShowing event on the datagridview:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox ctl = e.Control as ComboBox;
ctl.Enter -= new EventHandler(ctl_Enter);
ctl.Enter += new EventHandler(ctl_Enter);
}
void ctl_Enter(object sender, EventArgs e)
{
(sender as ComboBox).DroppedDown = true;
}
This will get you your desired results. Let me know if that doesn't do it.
I changed only the EditMode property of the datagridview to EditOnEnter and it's working perfectly.
EditMode = EditOnEnter
If you set the entire grid to EditOnEnter, you can get some pretty funky activity when you are on a text column. Here's my solution, which should be self explanatory. If you did not know the column names, you could just check the cell type on mousemove.
Private Sub GridView_CellMouseMove(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles GridView.CellMouseMove
Select Case GridView.Columns(e.ColumnIndex).Name
Case "Ad_Edit", "Size_Caption", "Demo_Code"
GridView.EditMode = DataGridViewEditMode.EditOnEnter
Case Else
GridView.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2
End Select
End Sub
Set the DropDownStyle property of your combo box to DropDownList...
Perhaps old.. But make sure to set ReadOnly property to false, else the cell wont enter editmode and therefore the EditingControl returns null and casting DroppedDown = true will cast a NullReferencException.
(Scroll down to bottom of post to find solution.)
Got a asp.net page which contains a
Datalist. Inside this datalist, there
is a template containing a
dropdownlist and each time the
datalist is filled with an item, a
ItemCreatedCommand is called. The
itemCreatedCommand is responsible for
databinding the dropdownlist.
I think the problem lies here, that
I'm using ItemCreatedCommand to
populate it - but the strange things
is that if I choose the color "green",
the page will autopostback, and I will
see that the dropdown is still on the
color green, but when trying to use
it's SelectedIndex, I always get 0...
protected void DataListProducts_ItemCreatedCommand(object
source, DataListItemEventArgs e)
var itemId = (String)DataListProducts.DataKeys[e.Item.ItemIndex];
var item = itemBLL.GetFullItem(itemId);
var DropDownListColor = (DropDownList)e.Item.FindControl("DropDownListColor");
//Also tried with :
//if(!isPostBack) {
DropDownListColor.DataSource = item.ColorList;
DropDownList.Color.Databind();
// } End !isPostBack)
Label1.test = DropDownListColor.SelectedIndex.toString();
// <- THIS IS ALWAYS 0! *grr*
I've narrowed down the code a bit for
viewing, but still you can see what
I'm trying to do :) The reason for
why I'm doing this, and not declaring
the datasource for the colors directly
i aspx-page, is that I need to run a
test if(showColors), but I do not want
to clutter up the html-page with code
that I feel should be in the code
behind-file.
EDIT: After trying to alter
SelectedIndexChange - I'm having a
"logical" confusion in my head now -
how am I to alter elements inside the
datalist? Since, as far as I know - I
do not have any way to check which of
the items in the datalist this
particular dropdownlist belongs to...
Or? I'm going to try out a few ways
and see what I end up with ;) But do
please post your thoughts on this
question :)
SOLUTION:
Either bubble the event to ItemCommand, or Handle the event, get the senders parent(which is a datalistItem and manipulate elements in there.
protected void DropDownListColor_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList dropDownListColor = (DropDownList)sender;
DataListItem dataListItem = (DataListItem)dropDownListColor.Parent;
var item = items[dataListItem.ItemIndex];
var color = item.ItemColor[dropDownListColor.SelectedIndex];
var LabelPrice = (Label)dataListItem.FindControl("LabelPrice");
LabelPrice.Text = color.Price;
}
When the DataList is data-bound, the AutoPostBack has not been handled yet, i.e. the values in the ItemCreated event are still the original values.
You need to handle the SelectedIndexChange event of the dropdown control.
Regarding your 2nd question:
I suggest you remove the AutoPostBack from the dropdown, add an "Update" button, and update the data in the button Click event.
The button can hold Command and CommandArgument values, so it's easy to associate with a database record.
some MSDN links with C# examples on bubbling
http://msdn.microsoft.com/en-us/library/system.web.ui.control.onbubbleevent.aspx
http://msdn.microsoft.com/en-us/library/aa719644(VS.71).aspx
http://msdn.microsoft.com/en-us/library/aa720044(VS.71).aspx
Thank You for your solution
protected void ddlOnSelectedIndexChanged(object sender, EventArgs e) {
try {
ModalPopupExtender1.Show();
if (ViewState["Colors"] != null) {
FillColors(ViewState["Colors"].ToString());
}
DropDownList dropDownListColor = (DropDownList)sender;
DataListItem dataListItem = (DataListItem)dropDownListColor.Parent;
Image image = (Image)dataListItem.FindControl("mdlImage");
Label ProductCode = (Label)dataListItem.FindControl("lblprdCode");
Label ProductName = (Label)dataListItem.FindControl("lblProdName");
DropDownList ddlQuantity = (DropDownList)dataListItem.FindControl("ddlQuantity");
Label ProductPrice = (Label)dataListItem.FindControl("lblProdPrice");
Label TotalPrice = (Label)dataListItem.FindControl("lblTotPrice");
//Label ProductPrice = (Label)dataListItem.FindControl("lblProdPrice");
} catch (Exception ex) {
}
}