I thought I had a simple task; add "Select..." to several dropdown lists.
However I am not getting the results I want and I am getting more and more confused if I should be using the dataBound or dataBinding event in my Gridview edit mode.
My code is pretty simple;
protected void ActivityList_DataBinding (object sender, System.EventArgs e)
{
DropDownList ddl2 = (DropDownList)(sender);
var act = Eval("myactivity").ToString();
if (act != "") { ddl2.SelectedValue = act; }
ddl2.Items.Insert(0, new ListItem("Select..", "-1"));
}
This checks if a value has already been selected, and would hopefully jump to the selection if it has been, still adding a Select item to the list.
Using the dataBound event works in the sense it addes my Select, but does not go to the selected value if there is one. Also it is creating odd behavior, jumping to the top of my page upon selection, rather than staying on the row I am editing.
Using dataBinding does not show my added items at all.
All advice welcome!
Alex (Lost in CodeLand)
Set your AppendDataBoundItems=True in your DDL. If you are calling the databind method in code you will want to clear the items and readd the new listitem before databinding.
Related
I have a ComboBox bound to a List via a DataSource. For some reason, when the datasource items change, the items in the combo box don't seem to automatically update. I can see in the debugger the datasource contains the correct items.
There are lots of answers on StackOverflow about this, but most are either unanswered, don't work for me, or require changing from using Lists to BindingLists which I cannot do this instance due to the volume of code which uses methods BindingLists don't have.
Surely there must be a simple way of just telling the ComboBox to refresh it's items? I can't believe this doesn't exist. I already have an event which fires when the Combo needs to be updated, but my code to update the values has no effect.
Combo declaration:
this.devicePortCombo.DataBindings.Add(
new System.Windows.Forms.Binding("SelectedValue",
this.deviceManagementModelBindingSource, "SelectedDevice", true,
DataSourceUpdateMode.OnPropertyChanged));
this.devicePortCombo.DataSource = this.availableDevicesBindingSource;
Code to update the combobox:
private void Instance_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "AvailableDevices")
{
// Rebind dropdown when available device list changes.
this.Invoke((MethodInvoker)delegate
{
devicePortCombo.DataSource = AvailableDevicesList;
devicePortCombo.DataBindings[0].ReadValue();
devicePortCombo.Refresh();
});
}
}
You are not binding the DataGridview's DataSource to same BindingSource object in your case this.availableDevicesBindingSource which bound first time. but later you are binding to different object AvailableDevicesList. again you are using another binding source for SelectedValue i.e this.deviceManagementModelBindingSource.
use one BindingSource only, may solve your issue
Uses: VS 2012;
I've a combobox attached to a datasource in my form. And things work fine. When I run the form, again everything works fine; I can select an item in the dropdown list and it updates to the datasource as well. My problem comes when I need to deselect/revert what I have selected after I saved or Remove what I have select (basically should go as null for that field value).
Our legacy system was built in Delphi 3 & 5, and users got a feature of right-clicking on the dropdown list and get a small popup like button named
Blank
which blanks what have been selected. I could not find anything that will do the same what ever user have selected in .NET's combo box.
You can add a new item in dropdown named -Select-( or something similar name) by using following code:
drp.DataSource = dataSet;
drp.DataBind();
// do it after binding
drp.Items.Insert(0, new ListItem("-Select-", "NA"));
If you are binding in xaml then on page_load event you can write only this line
drp.Items.Insert(0, new ListItem("-Select-", "NA"));
Now if user want to deselect choice, he/she will simply select -Select- item.
Whilst thanking all of your Answers and suggestions, I used #V4Vendetta's idea and composed my solution.
Similarly to deleting a record in a datagridview where you click Delete key, I took the same concept and associated my solution with Delete Key.
What I did was created a handler for ComboBox's Keypress Event like:
private void comboBox_KeyPress(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
(sender as ComboBox).SelectedIndex = -1;
}
}
And linked to every ComboBox's available
ComboBox1.KeyDown += new KeyEventHandler(comboBox_KeyPress);
ComboBox2.KeyDown += new KeyEventHandler(comboBox_KeyPress);
Now when user clicks Delete key while the ComboBox selected/active, it gets blank.
I am setting up a ComboBox to use the AutoComplete feature with AutoCompleteMode = Append and AutoCompleteSource = ListItems. When I load my form the Item list of the ComboBox is empty, and then I keep adding new values from the ComboBox.Text on a specified event (when a specific button is pressed).
Bottom line is that when the ComboBox's Items property is populated dynamically from an event, the AutoCompletion does not work as expected. My first entry into ComboBox.Items, always completes properly, but the later ones don't. If I click the arrow to dropdown the list, then all the Items so far entered autocomplete properly. If I Alt-Tab into another application and come back to the combobox, all the Items entered so far autocomplete properly.
It comes across to me that internally the combobox reloads its autocomplete list based on some event, but so far I have tried calling
ResumeLayout(true);
Refresh();
Invalidate(true);
Update();
DroppedDown = true;
DroppedDown = false;
but to no avail
Can someone enlighten me on how to dynamically add entries in the ComboBox.Items list and still have auto-complete with ComboBox.AutoCompleteSource = ListItems work correctly.
btnExecute is the default button on the form which contains the combobox. So the below function is invoked on pressing enter on the combobox
private void btnExecute_Click( object sender, EventArgs e ) {
cboCommand.SuspendLayout();
cboCommand.Items.Add(cboCommand.Text);
cboCommand.Text = "";
// Make some call here, so combobox reloads its cache for autocompletion
}
relevant portion from the auto generated winforms code
this.cboCommand.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Append;
this.cboCommand.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.cboCommand.FormattingEnabled = true;
I am using .NET4 Client profile on Windows Vista. May be it plays a role here
Anyone?
I have a DataGridView that has MultiSelect turned on. When the SelectionChanged event is fired, I'd like to know what items were newly selected and which items were newly deselected. For instance, if you have multiple items selected (by Ctrl-clicking) and then you release the Ctrl key and select a single item, I'd like to know which items were deselected. I could keep track of the previous selected items collection, but I just wanted to make sure I wasn't thinking too hard.
The event does not tell you exactly which things changed. If you need to know for some reason, you will have to keep track of the previous selection.
What are you trying to do in response to this event? There may be a much easier way to accomplish your real goal.
That information should be in the event arguments.
Use the RowStateChanged event. the DataGridViewRowStateChangedEventArgs will contain the row that was clicked. If a user selects/deselects multiple rows, the event will be called once for each row selected/deselected.
e.Row.Selected will yield whether the row is now selected or deselected.
This information is not inherently available for a DataGridView. However you could write a wrapper around the DataGridView which provides this information.
public static void OnSelectionChanged(
this DataGridView view,
Action<List<DataGridViewRow>,List<DataGridViewRow>> handler) {
var oldSelection = view.SelecetedRows.Cast<DataGridViewRow>.ToList();
view.SelectedChanged += (sender,e) {
var newSelection = view.SelectedRows.Cast<DataGridViewRow>.ToList();
handler(oldSelection,newSelection);
oldSelection = newSelection;
};
}
Use Case
void HandleSelectionChanged(List<DataGridViewRow> oldRows, List<DataGridViewRow> newRows) {
..
}
void FormLoaded() {
myDataGridView.OnSelectionChanged(HandleSelectionChanged);
}
I'm getting the following message when I try to remove the last item in a datagridview.
DataBinding cannot find a row in the list that is suitable for all bindings.
I have my binding setup as follows.
ExtendedBindingList<MyClass> bl = new ExtendedBindingList<MyClass>(GetDataFromDB());
BindingSource bs = new BindingSource();
bs.DataSource = bl;
dgv.DataSource = bs;
ExtendedBindingList is just something simple I threw together to implement sorting and filtering and some basic state persistence. dgv is the DataGridView. GetDataFromDB returns a List of MyClass.
The issue only arises when I try to remove the last item from the datagridview using:
bs.RemoveCurrent();
which works at all other times. My only hint for a solution is to remove all bindings and reapply them but this doesn't seem like an ideal solution.
EDIT
The exception only gets thrown after the BindingList successfully removes the last item in question. It get's thrown in external code so I can't tell exactly what is throwing it.
So, here I am, asking SO for some help :).
Thanks in advance,
Justin
Here is how I remove selected row from a grid:
private void btnDelete_Click(object sender, EventArgs e)
{
if (grid.CurrentRow == null) return;
var selectedItem = grid.CurrentRow.DataBoundItem as PartGroup;
if (selectedItem != null &&
UIHelper.ShowQuestion("Are you sure you want to delete selected row?") == System.Windows.Forms.DialogResult.Yes)
{
groups.Remove(selectedItem);
}
}
groups is my BindingListEx(Of T).
Hope it helps.
[Sorry, not really an answer but I feel this is valuable since no answer was given.]
I was getting the exact same situation using .NET Compact Framework 2.0. Testing traced it to the point where a NumericUpDown.DataBindings.Add() was used to bind the control to the source. After this point, using RemoveCurrent() would produce the error if the item was the last one in the source. Prior to that binding (or if it was skipped), the error would never appear.
Other controls were bound to this same source -- TextBox and ComboBox -- but they did not cause this behavior. Only the NumericUpDown control.