I'm using a DataGridView with bounded List of objects in my application. So I have:
grid.DataSource = Files.Instance.List;
in my form load event and than I want to have two buttons - for adding and removing items from the list (so also from the grid), I though it should be as simple as:
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Files.Instance.List.Add(new DelphiFile { FilePath = openFileDialog.FileName });
grid.Refresh();
}
I'm only setting up the start path here, I wanted the rest parameters to be set by user in the grid view.
The item is added correctly but unfortunatelly it doesnt appear on the list, why?
I also have issues with deleting items:
foreach(DataGridViewRow row in grid.SelectedRows)
{
Files.Instance.List.Remove(row.DataBoundItem as DelphiFile);
}
grid.Refresh();
items are deleted correctly but again the grid doesn't seem to refresh and I'm even getting an exception because the last item in the grid doesn't have a value than :O .
What am I doing wrong?
I guess you declared Files.Instance.List as of type List<DelphiFile>, so when the collection is changed, the dataGridView doesn't know about that, use BindingList<DelphiFile> instead.
Related
In a C# WinForms project I'm querying a database to get a list of values to populate a listbox with. The query populates a List and then I iterate through that to add the list items to the listbox.
lsNewValuesList = dbGetNewValueInfo.GetNewValuesDgvData(strNewValuesQuery);
foreach (string strItem in lsNewValuesList)
{
lsBxNewValues.Items.Add(strItem);
}
After that's done, I need to manually add an item to the top of the list, which I'm doing via, lsBoxNewValues.Items.Insert(0, "DELETE");. But when I run it I get the message,
Items collection cannot be modified when the DataSource property is set.
Here is a screenshot of the error (to clarify some questions):
Looking into that I'm understanding that error arises when the listbox is populated with a datasource, but I'm just populating it from a string list. Is that, technically, a datasource then?
How do I accomplish what I'm trying to do?
[UPDATE]
Okay, I've done some fiddling around, albeit without resolving my issue, and I've tried the following:
lsNewValuesList = dbGetNewValueInfo.GetNewValuesDgvData(strNewValuesQuery);
lsNewValuesList.Insert(0, "DELETE");
lsBxNewValues.DataSource = lsNewValuesList;
//foreach (string strItem in lsNewValuesList)
//{
// lsBxNewValues.Items.Add(strItem);
//}
Instead of inserting "DELETE" in the ListBox (which is what I was originally trying and was causing the error), I inserted it at index 0 of the List, the datasource of the ListBox, and then set the ListBox's datasource. "DELETE" is showing up in the ListBox, but it's getting alphabetized along with the rest of the items. I'm not doing any sorting of the list or the ListBox - I'm using ORDER BY in the database query, however. CyberZeus suggested I use Refresh() on the ListBox, but that didn't have any effect.
Yes, a list of strings is a datasource.
You have to add the data retrieved from the database to the datasource of the ListBox. You may need to refresh the ListBox.
Every time this Dropdown is showing first Item Blank
ComboBox cb;
List<string> namesCollection=new List<string>();
namesCollection.Add("---- Select ----");
namesCollection.Add("ABC1");
namesCollection.Add("ABC2");
namesCollection.Add("ABC3");
namesCollection.Add("ABC4");
foreach(string pname in namesCollection)
cb.Items.Add(pname);
Does anyone have solution for this ?
You appear to be defining the ComboBox right there in your code, so I'll assume it's actually displayed somewhere in your form / window.
It's normal for the ComboBox to display a blank line initially.
Specify the item you want to display, immediately after populating the ComboBox with data:
cb.SelectedIndex = 0;
You probably have a line feed in your items collection. Hard to see. Adding a cb.Items.Clear() before populating is probably a good idea anyway and will get rid of the problem, if you can't locate it.
i have been strugeling with this for some time now and its driving me crazy. This is the situation:
I have a bounded DataGridView i designed this with the visual studio designer. All the information shows accordingly.
in my DataGridView i have 2 ComboBoxes in here the data is also correctly displayed. I want that if i click on the ComboBoxea list of options shows.
Because the DataGridView is bounded to a source i can not use the ComboBox.Items.Add() method. So i created another Datasource in the designer and in runtime i change the datasource for that specific combobox. Now the list shows shows the options that i want, yeey !
Now, i want to save this newly added or changed row to the database.. so i use the following method for this (i call the method on the RowLeave event from the DataGridView):
if (tasksDataSet.HasChanges()
{
try
{
tasksBindingSource.EndEdit();
tasksDataSet.GetChanges();
tasksTableAdapter.Update(tasksDataSet);
}
catch (Exception ex)
{
}
}
This won't work for the ComboBoxes since this is another datasource.
So basicly what i want is:
Use a datasource for the DataGridView
Change/Add items to the DataGridViewComboBox
Save the changed made to the (complete) DataGridView to the database
How can i make this work ?
if your problem is to save current data which is given to Grid view.
than i suggest try to use session . while binding data to DataSource assign it to
session["SomeID"] . if your changing binding then again assign same session to it.
next step convert session to what ever you want to save.
ex:
//Datasource.
list<User> DataBoundSource = new list<User>();
DataGrid.DataSource = DataBoundSource;
DataGrid.DatBind();
//Assign to Session where you are binding this
//every time
Session["SameID"] = lsDataBoundSOurce;
//your code.
...
...
...
//covert that session to Datasource you want to save.
list<User> saveData = (list<User>) Session["SameID"];
this is the basic idea i got. i hop this will help you.
please give it +1 if it help you
I have a DataGridView with DataSource set to a BindingSource control, that is bound to an ObservableList of entities.
I use this grid as a read only grid, for searching purposes.
When an item is selected, another BindingSource is updated with the current selected item.
No issues until here.
The issue is when creating a new item and I want to select the new item in the DataGrid, as after saving user is supposed to be able edit some data of the just created record.
How can I do that?
I can only provide the entity itself or the ID, but I can't figure out how to do that.
I'm not quite used working with Windows Forms, so I'm sure I'm missing some trivial solution.
You should bind the SelectedItem property of the grid to a property where you can set what entity you wish to be selected. Not sure but you might need to trigger a refresh on the grid because it might not automatically refresh it's View.
Ok, after some research and inspecting the "row" object, I've found this solution that perfectly meet my needs.
If anyone find any flaw with this approach, please let me know.
Once the new item is saved, I get the entity updated with the new primary key, then I call the following function:
private void SelectDataGridItem(Model.MyEntityType selectedItem)
{
foreach (DataGridViewRow row in MyDataGrid.Rows)
{
var boundItem = (Model.MyEntityType) row.DataBoundItem;
if (boundItem.Id == selectedItem.Id)
{
row.Selected = true;
break;
}
}
}
In my code I need to remove rows from the DataGridView after a recurring interval, and so I call the following function when a timer expires:
private void removeRows(DataGridView dgv) {
foreach (DataGridViewRow row in dgv.Rows)
{
// if some condition holds
dgv.Remove(row);
}
dgv.Refresh();
}
I know the rows are successfully deleted from the DataGridView, though they still remains in the display for whatever reason. Any tips on what I might be doing wrong?
Don't you need to rebind the data grid?
dgrv.Datasource = [whatever data source];
dgrv.DataBind();
?
Sometimes refreshing the data gridview is not enough and its containing parent should be refreshed too.
Try this:
dgv.Refresh(); // Make sure this comes first
dgv.Parent.Refresh(); // Make sure this comes second
You could also edit your source and attach the new datasource to the control.
this code could be useful:
dataGridView.DataSource = null;
dataGridView.Update();
dataGridView.Refresh();
dataGridView.DataSource = SomeDataSource;
Hope this helps.
If you have bound your datagrid to an Observable Collection (if not then you should) then you will need to implement INotifyCollectionChanged interface so that listeners are notified of dynamic changes, such as when items get added and removed or the whole list is refreshed.
HTH
If I understand you correctly, you want to delete rows selected by a user from your DGV.
Use the DataGridViewRowCollection of your DGV rather than the DataRowCollection of the DataTable. The DataGridViewRow has the Selected property that indicates whether a row is selected or otherwise.
Once you have determined that a row is to be deleted, you can use the Remove method of the DataGridViewRowCollection to delete the item from the grid, e.g. YerDataGridView.Rows.Remove(row)
Note that at this point, although the item is removed from the DGV, it still has not been deleted from the Access DB. You need to call the TableAdapter Update method on your DataSet/DataTable to commit the deletions to the DB, e.g. YerTableAdapter.Update(YerDataSet)
I normally would call Update once to commit the changes only after having removed all the items to be deleted from the DGV.
If it's a data-bound grid, you should be working on the binding source itself instead of the grid.
Try removing the actual items from your binding source instead.
I had same problem and I have find out the root cause.
all you have to do initialize you database context object in before reload and see the magic .