Master/Detail UI Best Practices? - wpf

We have a WPF app that has a master/detail window, both being WPF Datagrids. When you select a row in the upper datagrid, the details are shown in the lower datagrid. I was wondering if there are any best practices from a UI perspective on how to deal with things such as:
When the window first opens, no datarow is selected in the upper datagrid, and so no data can be displayed in the lower grid. Is this normal? Or is there typically an initial (top) row selected in the upper datagrid?
When a row is selected and then deleted - does another row become the selected row? Or are you going to go to a no row selected state?
If multiple rows can be selected, when happens in the lower datagrid? Show the last one selected? Or if delete is selected for these multiple objects, where is focus set? Or what row is selection?
I know there are a lot of different ways these things might be handled depending on how the app is written, but I wondered if there is some standard best practices? Or if there is some default operations for how the WPF datagrid might handle these cases?
thanks!
Bill

I think the first two considerations can come down to preference. I'd prefer to have the first row selected and its details shown when the window first opens -- this tells me, as a user, how this window works. Not sure how it works in WPF, but in Windows Forms, the datagridview pre-selected the top row by default (and getting it to stop doing that requires tricks).
When I remove a row, I personally prefer to go to a "no row selected" state, but I don't have much to back that up with in terms of "this is why you should do it". I just like seeing the empty "detail" view and lack of selection as confirmation that I did successfully remove the selected row.
The last point, however, I think is more clear-cut. If you have a master/detail relationship in views, you should not allow multiple selection. If you need the user to be able to perform actions on multiple rows of the master gridview, you can add some checkboxes to the rows to allow the user to pick a subset of rows to act on. But for the purposes of showing details, only one row must be selected at a time.

Related

WPF DataGrid loses virtualization when sorted by specific columns

I am using a WPF DataGrid that is bound to a custom ItemsSource that implements IList (and NOT IEnumerable). The custom ItemsSource performs data virtualization and only loads pages of items as needed. MyDataGrid actually inherits from DataGrid and overrides the handling of the DataGrid sort methods so that I can maintain data virtualization while sorting. I have UI Virtualization turned on for MyDataGrid.
When I run the application, MyDataGrid displays just fine, tells me I have roughly 20,000 items, and only asks my ItemsSource for the first 20 or so items. I then can click on column headers to sort various columns and again my ItemsSource only has to reload the first page of 40 items because MyDataGrid has asked to refresh only the first 20 or so.
BUT, when I click on my Last Name column to sort, MyDataGrid loses its UI Virtualization and asks my ItemsSource to load every single item even though it only needs the first 20 or so. I can watch as it asks for every single item by index (this[0]).
I've tried researching ICollectionView, UI Virtualization, and Data Virtualization and the only thing that I've read that seems it may apply is regarding multiple row selection (at DataGrid row request patterns with data virtualization I've set MyDataGrid's SelectionMode to Single so this shouldn't apply.
Another hint may be that, prior to sorting by Last Name, the first item in MyDataGrid has a last name that starts with the letter V (very late in the alphabet), and that I can actually sort the list in Descending order by last name without losing virtualization. The same thing happens with my Title column which has a first item that starts with the letter S. I don't have the problem with any of the other columns.
Any ideas?
FIGURED IT OUT!!! Looking through the call stack, it appeared that the problem was happening during the MeasureOverride of the VirtualizingStackPanel and I noticed it was calling the SyncUniformSizeFlags method. So I then went into the default style for the DataGrid and set the RowHeight to a fixed amount and it no longer causes the problem.
So, it appears that the DataGrid can lose its virtualization when a fixed RowHeight is not set. Still don't know why opting to sort in ascending order by Last Name or Title caused it to want to resync the row heights, but I can work around that one.

How to find out when DevExpress XtraGrid row visibility changes?

Is there easy way to find out when DevExpress XtraGrid rows visibility changes?
I am using WinForms DevExpress XtraGrid. I need to know which rows are visible. I can find out which rows are visible at the moment, but I do not want to calculate it every time. So I calculate it when needed, store it, and invalidate if operation that can change visibility occurs. Which is scroll, resizing control, sorting, grouping, expanding or collapsing group, filter change, add or remove of item in data source, or change to item in data source when grid is sorted or filtered.
As you can see it became pretty ugly. Is there easier way to notice changes of visibility of rows? Is there event when row changes visibility or moves for any reason?
Unfortunately there is no event able to handle behaviour you've described - you have to handle number of events (sorting,grouping, etc.) and call function recalculating set of visible rows in each of them.
Regards,
Maciej Nowicki

Can the WPF ListView/GridView display multiline items?

My application uses a ListView/GridView control to display data records that the user can select and edit. This is based on http://www.switchonthecode.com/tutorials/wpf-tutorial-using-the-listview-part-3-in-place-edit. Now I have a case where the number of columns is larger and there's a text description on every line that indicates what object the user is editing in the line.
To save horizontal space, can that text description for each item be displayed above the other columns, in a separate row, spannng multiple columns, but still be included in the item selection when an item is selected? While all other columns are editable when selected, that info text is only static and cannot be edited by the user.
Here is a screen mockup as I felt it is necessary to understand what I mean. The red rectangles are only for highlighting the area of interest, they are not displayed in the application. This is based on the screenshot of the above mentioned link and the application behaviour is otherwise exactly the same. I just want that additional row to be displayed in each item.
Edit 2: Now as I think about what I've painted, it looks like the grouping from ListViews in Explorer. Those group headers are not included in the selection though, but as they are also unselectable and skipped in keyboard selection, that would be okay, too, I think. I'm just continuing my search in that direction to see what I can find.
Please ask in the comments if anything is unclear.

WPF DataGrid - Setting RowDetails programmatically

I'm using the WPF DataGrid, and I'd like to know if there is any way I can access the DataGridRow's RowDetails programatically.
For example, when the user selects the row, I'd to grab some data from somewhere (say, a database), and display it in the RowDetails.
All of the examples I've seen tend to just display some extra bound data that isn't included in the columns for the row.
You could display some extra data but lazy-load it on SelectionChanged.
It usually is not easy to work directly with the WPF controls, they are not really meant to be used without a backing databound model.
If you have all the data in list of objects (or something similar) then you can do all sorts of fun things. I'm using a WPF Datagrid in this manner, and when a user selects a row, I think populate an editor control above the grid with the row item plus additional details.
That said, there's nothing stopping you from adding in additional information in the grid that's normally hidden and a trigger on row selection to show the additional data
you can use the following code
DataRowView row = (DataRowView)MyDataGrid.SelectedItem;
string strName = row.Row["Name"].ToString(); //where "Name" is the column name

Is there a way in the WPF Toolkit datagrid to have a header below the column headers but above the first row

I looking for a way to create an area that indicates a user is at the top row of the WPF Toolkit datagrid. (Showing the scrollbar scrolled down is not enough for the user). I need something that sticks out and says "this is the top row" basically. Messing with the entities that that the grid is bound to will not work for me because I have several grids with different filters over the same collection of entities. Also this underlying collections is changing while the app is running.
Is there a way to add a control of some sort between the column headers and the first row of the datagrid? Maybe a separator of some sort?
Thanks!
Jon
A possible solution is to create your own Template for the column headers with ColumnHeaderTemplate and show whatever you need in there. This way you'll have full control of what your header looks like.
Another hackish solution could be you change the Style of the header to achieve the desired effect, like setting the bottom margin to a higher value so that there is a space between the header and the first row.

Resources