I have a GridView in c# UWP, that has some items in it (let's say, its filled up with 100 items). I want the GridView to support the arrow-keys on the keyboard. In order to select the item above my current item, I need to know how many items are in one row.
How do I get the number of items in a row?
I've encountered a performance issue with the C# DataGridView control, which appears to be the result of the unsharing of a large number of rows. The DataGridView is bound to a bindingsource, which is, in turn, bound to a dataview. I've gone through the laundry list of dos and don'ts from the MSDN info (not using rows.count() etc), but I just can't get it to play the game.
Even if I start with a brand new DataGridView control, on a fresh form, and bind it to a bindingsource that has a basic test table as its source, just showing the form seems to cause all of the displayed rows to become unshared. Then, every single row I select causes that row to become unshared. I'm wondering if I'm wasting my time trying to prevent this?
In my actual DataGridView control, it's necessary for me to have at least one column that is not visible, which contains ID values. It's also necessary for me to search all the values in this column for a matching ID. It would appear that, as soon as I attempt to iterate through the values to find a match, this is causing every single row to become unshared. Is there a way to do this that does not cause all the rows to become unshared as I search?
I have 100 items, from items 1 to items 100. I only want to display 5 items each time and when the user click on the down button once, it will display from item 2 to 6. When I click again, it will display from item 3 to 7.
I was thinking to reset the whole datagridview and redraw it once the arrow is clicked. But I am worried it is too slow. Is there a more suitable control for this application?
Having 100 item in a DataGrid is ok IMHO.
However, if you want the fastest possible solution, I suggest you to use a ListView with the VirtualMode enabled.
I'm working on a MS Office add-in that has a DataGridView with 5 columns. Is it possible to only have as many columns shown as can fit into the sidebar, but then as the user re-sizes the add-in sidebar add more or take away columns as there becomes room for them?
u can use the Resize Event of the Datagridview and Add and Remove (or set visibilty) of all rows that are unwanted.
I guess your columns have a given size and are not sized automatically.
In that case u can:
int columnsToShow = (int)(dataGridView.Size.Width / columnWidth);
now add enough rows to match the wanted number / remove all rows that are too much
or set visibility
With respect to a Virtual ListView control in a Winforms App, what are ALL the functions of RetrieveVirtualItem event?
Scenario: There is a Dictionary object which acts as my ListView cache. And its items are displayed on the ListView. On click of a column, the cache dictionary is sorted in memory and the ListView is Refresh()ed. The effect on UI, the ListView is sorted well. :)
But I want to understand what the role of RetrieveVirtualItem Event is, which gets triggered on Refresh().
In the RetrieveVirtualItem event handler [ Someone else's code, :( ], following are done:
Based on RetrieveVirtualItemEventArgs.ItemIndex, get the message from Cache
Set RetrieveVirtualItemEventArgs.Item = retreived item above
It appears that what's done in the event handler is important because, if I take it out, ListView cries. What is the significance of this event?
EDIT
Or let me re-phrase the question... My concern is, Why, after Sorting (and RetrieveVirtualItem event handler), the selected item remains at the location where it was before sorting. I.e, If I select item #5 and sort, and if sorting makes this item as the last item, I would prefer the LAST item to be selected after Sort. But in my case 5th item is selected after sort. So what is the default behavior of RetrieveVirtualItem WRT selected item?
A virtual ListView should only call RetreiveVirtualItem for the rows currently visible on the screen.
As you navigate in the ListView, for example, you press the page down key, the ListView will calculate what should now be the index of the top row and will then call RetrieveVirtualItem so that your code can provide the item to use at each row index.
Unless you cache or otherwise store the items you are providing via RetrieveVirtualItem, they will no longer exist once they are scrolled out of the listview.
This is what the Virtual in VirtualListView means - there aren't any real rows, the rows are virtual. That is how it could display a list containing hundreds of thousands of rows - because it will ever only actually contain how ever many rows are visible on screen.
In effect, the ListView is like a window that is moving up and down your internal list of data - the RetreiveVirtualItem method is what it calls to move items into that window as it moves along. It says, hey I just moved to row 15 - give me the item for that row. It will proceed to call RetreiveVirtualItem for each row index which would be visible. If the ListView was 5 rows in height on the screen, you would receive 5 calls to RetrieveVirtualItem - even if the actual data backing the listview had 3000 items. Each time the top row of the ListView changed (because of navigation), you would receive 5 calls to RetrieveVirtualItem (this is not always the case, but it is the right idea - for example, if you scroll down one row, it will simply ask you for the new last row - it will also simply discard the data that was used for the old top row that scrolled out of view).
I guess it might be even easier to explain if we assume the ListView was only one row high on the display (meaning only a single row is ever actually visible on the screen) - as you move the ListView up and down your list of data (i.e. the user navigates the ListView), it would call RetrieveVirtualItem exactly one time every time it moves to a new row.
Hope that helps...
Good Luck
Virtual listviews only deal with indices. So, if the 5th item is selected before the sort, the 5th item will still be selected after the sort. The control itself has no way of knowing that the data that used to be on the 5th row is now on the first row.
You will have to program that for yourself in your sorting method:
remember which items were selected (remember: you can't use SelectedItems property when in virtual mode)
do the sort
find the indices of the previously selected item now live
select those indices
You can see all this in action in ObjectListView -- a wrapper around a standard .NET ListView.
The RetrieveVirtualItem event is only used when the ListView is put into virtual mode. Rather than retaining ListViewItems in the Items collection (as when not in virtual mode), it creates the ListViewItems dynamically, when needed.
If you don't handle the RetrieveVirtualItem event then no ListViewItems will be added to your ListView. I've attached some sample code for a typical method written to handle the event:
//Dynamically returns a ListViewItem with the required properties; in this case, the square of the index.
void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
//Check if cache has been instantiated yet, and if so, whether the item corresponding to the index requested has been added to the cache already
if (myCache != null && e.ItemIndex >= firstItem && e.ItemIndex < firstItem + myCache.Length)
{
//Return cached item for index
e.Item = myCache[e.ItemIndex - firstItem];
}
else
{
//When item not in cache (or cache not available) return a new ListViewItem
int x = e.ItemIndex * e.ItemIndex;
e.Item = new ListViewItem(x.ToString());
}
}
This example is taken from MSDN (http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode(v=vs.90).aspx) where further details can be found.