I'm looking for a workaround to an issue I've noticed in a project that I'm working on. I have a datagrid bound to a list of a class I've created. Whenever a user types in a stock symbol in this datagrid I have the roweditending event set to pull in some information to populate the other fields in the datagrid.
This generally works fine, however I've noticed that the event doesn't fire in some instances. I'm going to try to explain this the best I can... upon data entry if I enter information into a cell and then click another row on the datagrid - focus doesn't shift to the new row but shifts to the row containing the cell I was just entering data into from that cell, then if I select another row or input element the row edit ending event doesn't appear to fire and as such my code to populate the rest of the row doesn't execute.
Everything else is fine, and it's a pretty subtle issue, only one path of input to make it happen, but I was wondering if anyone had run into this or found a work-around?
I've been looking at the selection change event, but I need to be able to grab the row that was selected. In the row edit ending event I use
Dim NewTrade As Trade = e.Row.DataContext
to get the instance of my class that the row represents and to add the additional fields.
I'm not sure I see a way to get the row and it's datacontext for the row I just shifted from using the SelectionChangedEventArgs.
Any ideas for a workaround?
Related
There are two user controls
1. First User control, having only Datagrid views only
2. Second User control, having the Details & operations like addition, modification & deletion button.
Both the user control will be placed in the Main window.
Whenever i am selecting a row in the grid particular data is displayed in the second user control (Using PRISM eventAggregator). But when adding or updating or deleting it is not happening updating the first user control data grid. How to achieve this.
Use the ObservableCollection it represents a dynamic data collection that gives a notification when items get added or removed.
If you are already using this which is not clear from your question, then you should check if you are using the INotifyChanged correctly or give us some code so we can help you.
But with the ObservableCollection and the INotifyChanged you should be able to solve your own question.
I have one ComboBox which is populated on load from populate.txt file. I'm using streamreader for this. So far it works. The ComboBox is properly populated with:
- one
- two
- three
I have one empty TextBox, and a button.
The thing that I'm trying to do is:
Select something from the ComboBox i.e. "one"
Write in the TextBox i.e "50"
Press the button, and to populate the DataGridView first row with:
"One"(cell0) "50"(cell1)
At this point, a new empty row should be automatically added below the filled one. I've searched and searched for hours to no avail. So I decided to make an account and ask the question :)
The reason I'm doing this is that, later on I'll export the filled DataGridView.
I could easily use labels for this, but that's not what I'm aiming for. I'm trying to "dive in" into the more complicated "stuff".
I hope that I explained well enough.
We have the following WPF : a datagrid with row detail template. Selected line on this grid (customer selection) is handled to trigger two queries to retrieve address and contacts data, then row detail template show these data in two tabs, each with a datagrid. All the magic is done with binding, subgrids bind to properties of main Customer object, which we have as an IObservableCollection.
The bug happens when using “move down” arrow on keyboard, selected index changes fast, so fast than queries result “come back late” to interface, thus data is incoherent to what is shown and data update cannot perform. We have an exception. So my question is : how to prevent this in a proper manner ?
Should we have a try-catch the right kind of obscure exception then do nothing (loose data that cannot be applied to interface) ?
We don’t want to wait for data to come back, if user scrolls very quickly, customer selected line should go down and no matter details aren’t shown.
Maybe we should have a delay before selected item details are retrieved ? Thus no query if selected item changes before end of delay ?
Thank you for your ideas.
Gists for code:
Xaml : https://gist.github.com/Xarkam/3b89eb614124bb2f2307
Selected index changed handling : https://gist.github.com/Xarkam/cf28844ce05fd4984807
Edit 10th of July :
I have modified the main datagrid items definition as in following gist : (add https:// prefix, I don't have enough reputation to add more links, sorry) gist.github.com/postb99/d3be79f0ef2544d685f9 (inspired from stackoverflow.com/questions/13374957/datagrid-throws-invalidoperationexception-by-scrolling and proposed answer) but problem still persists...
We've solved it, if I remember well we didn't have observable collections for every collection of objects to display.
In one of our WinForm Apps, we are using a DataGridView with Column Sorting and SortDescriptions enabled.
If the user modifies one of the cells that is being sorted by, the sorting is applied and the grid paints the rows in the new order.
I need to access the DataGridRows BEFORE they are painted, but after they have been sorted. I know I could use DataGridView.RowPrePaint(), but that seems like overkill. It fires when the mouse hovers over certain cells, etc. I just need to get to the Rows when the ordering has changed. I thought maybe I could handle the "Sorted" event on the DGV, but that only fires after the user clicks one of the column headersm but I need to get to the rows when the DGV applies any of the existing Column Sorts or SortDescriptions. Basically, the Rows could be reordered (sorted automatically) after one of the Cells is edited the DGV is sorted on OR after the row is mofified via a RowEdit "Template".
I have googled this quite a bit today and haven't come up with any suggestions.
Any advice? (Other than just handling the DataGridView.RowPrePaint Event....)
I am not sure if it works, but if I were you I would keep the RowPrePaint() event.
Set a flag
bool RowSorted;
Set the RowSorted variable true in the sorting function and again fire the RowPrePaint Event in sorting function after the rows are sorted.
In the RowPrePaint function I would check the flag. If true, paint the rows; if false e.Handled = true;
I found the answer. This is the exact problem I am facing (from msdn):
When a DataGridView control containing both bound and unbound columns
is sorted, the values in the unbound columns can't be maintained
automatically. To maintain these values, you must implement virtual
mode by setting the VirtualMode property to true and handling the
CellValueNeeded and CellValuePushed events.
For more information, see How to:Implement Virtual Mode in the Windows
Forms DataGridView Control. In addition, sorting by unbound columns
in bound mode is not supported.
Hope this helps.
Sincerely, Linda Liu
I am developing a winform application application. I wanted to show sum of columns in last row of each column. This row must always be visible.
At moment I am thinking about adding another datagridview just beneath my datagridview with records, and would show the sum in that bottom datagridview.
If there is a better way to achieve this task?
No, need of adding another datagridview
Solution 1: Please refer to this solution
Solution 2: If the above link is not exactly what you want then,
You can try to manually add last, summary, row in which you can display information that you need. For example, you can try to do the following:
Read data from database and fill System.Data.DataTable
Add one column to the newly created DataTable – that column might be set
to true for the last, summary, row
Programmatically add one extra row that contains suitable summary data
Do the data binding to DataGridView control
Using appropriate event, bold or otherwise graphically distinct summary
row (row that have extra column value
set to true)
You can do it in the same way as you suggest, like placing a datagridview for displaying the sum. you can also handle the Horizontal Scroll with this, if there are more columns.
Another method is there in this link
Another way you can Add Rows to your datasource itself to display the sum.
Even if this question is quite old-ish I'd like to propose an extension to Niraj Doshis answer. His answer holds true for a data bound DataGridView. I recently had the problem to calculate the summary in a user-editable DataGridView, whose solution differs in the details. Anyway It's quite straight-forward too. I am writing my functions on a higher abstraction level, which outlines the workflow, but elides the implementation details.
First of all you'll have to initialize the DataGridView, see
private void InitializeDataGridView()
{
SetColumnTypes();
AddEmptyRow();
AddSummaryRow();
}
I set DataGridView.AllowUsersToAddRows to false for the new row would be located beneath the summary row. Hence I am adding an empty row, which the user may fill with his data. The summary row is set to ReadOnly since we do not want our user to edit it. Whenever a CellEndEdit is raised I am updating the DataGridView with the following method
private void UpdateDataGridView()
{
RemoveSummaryRow();
RemoveEmptyRows();
UpdateRowNumbers();
AddEmptyRow();
AddSummaryRow();
}
First I remove the summary and all empty rows (you'll have to take care. If you are trying to delete the row you just edited an exception will be thrown. I've not yet figured out how to do this, but I just made up the solution. I'll amend when I came up with the solution.) Afterwards I'm setting a running number in each of the rows. This is not really required, but a detail of my implementation. At the end I add an empty row again which the user may use to add further data and then calculate and add the summary row.
As I said before this is not yet a ready-made solution, but rather I concept which works but with some quirks and bugs.