Moving Datagrid at runtime WPF - c#

I have a StackPanel of Datagrids that contain data about various things. A user should be able to click on one of those datagrids and that datagrid should expand and take the place of the four datagrids on the screen. Clicking on the expanded grid should return the screen back to the previous display of four data grids.
I have tried replacing the top grid in the backend (I don't think this is a violation of MVVM since it is dealing purely with the display, but I could be wrong) with the selected grid, which doesn't seem to work. I have also tried hiding the grids to see if that would work. I found several topics here and elsewhere talking about moving columns and/or rows around at runtime, but nothing about moving an entire datagrid at runtime.

I would suggest building your UI view as a grid with column/row sizes bound to match their content, and use a backend property to determine whether the various datagrids should be Visible or Collapsed as a result of your clicking. Then the UI will adapt to fit the scenario you want.
Another alternative is to have a couple of views which have the explicit arrangement of controls you want, then have an outer ContentControl whose Content property is changed to one or the other as a result of the clicks.
I'd favour the former though for simplicity if feasible in your layout.

Related

ListView with headers and ItemTemplate

I'm trying to achieve a view similar to this ((Sub)(Sub)Item names not being part of the view - they show how the source data is structured):
EDIT:
As per comment, I'm adding an example of how I want to render the data (2 items):
That is, I have bunch of Items which I want to render in customized way. Those have SubItems that start being part of the grid (possibly spanning multiple cells). And those have SubSubItems with more data to put inside the grid (each on one row).
I want the data that belongs to a grid, to be aligned according to my Column headers.
I manged to make this work using a ListBox with ItemTemplate set to DataTemplate defined in resources. Going down 3 levels of hierarchy, using Grids to layout the content. There were 2 issues with this:
Aligning the data in grid with column headers. I managed to solve this using top level grid as column headers and IsSharedSizeScope/SharedSizeGroup. But it wasn't very nice solution and the alignment proved difficult to achieve.
Drawing borders around cells - since it wasn't just one Grid, but multiple within each other, borders would not connect nicely or have different thickness. I didn't manage to solve this so far.
I tried using ListView instead of ListBox, with GridViewColumn, but that disabled the ItemTemplate rendering.
Is there a way to use both? Or some other way to add the Columns with their default nice style and on-the-fly re-sizing capabilities? What about the cell borders?
Or am I looking at it entirely wrong and I should use different approach altogether?
I did try using DataGrid but that seemed even worse approach.
Note: I need virtualization - working with lots of items.

Change parent of a control in a size trigger in UWP

I'm creating a Windows 10 Universal app, there are two panels in my main page.
In tablet/desktop mode, both are visible at the same time (just two simple Grids, one fills the left side and the other one fills the right side)
However, in phone mode, there's a pivot and user can swipe between panels.
(I could use SplitView and hamburger menus which work easily in both Tablet/Desktop and Phone modes, but a pivot makes more sense in my case)
So, What I currently did is, I have two instances of each panel. PhonePanel1 and PhonePanel2 are two grids inside two pages of my pivot control, and TabletPanel1 and TabletPanel2 are two grids which can be shown side by side. and I use AdaptiveTriggers to detect page width and switch between these two view methods.
However, having two instances of each panel is not a good approach, because those are showing basically the same content.
Is there any better approach to do this? Maybe changing Grid's parent when triggers are changing view mode? or something better?
The only way to change the parent that I can think of is to write some code behind that will render them in the new location. A suitable solution may be to defer the loading of the controls until they are needed.
x:DeferLoadStrategy=”Lazy“
If you add this property to your controls that are duplicated, they will only be loaded when required. So on a phone the PC/Tablet view should never be loaded, unless the user is running in Continuum on an external display.
On a PC you may still end up with both loaded (If the user resizes the window) - On a PC there are usually more resources so it's less of a problem there in most cases.
I looked into the code behind approach to move the controls to a different parent and I think honestly it's premature to do that when it might not even improve performance.
I have gone for the Defer Load Strategy property and found performance to be fine, and it requires very little code. My duplicate controls are sharing the same ViewModel so I pretty much just added the property to ensure resources are only used when essential.
There is nothing wrong in your approach. To reduce memory usage, when adaptive trigger happens for example on the phone, set TabletPanel1 and TabletPanel2 visibility to collapsed.
If all panels use the same datacontext then leave it as is, if not set datacontext for collapsed controls to null.
You could create each of your panels as user controls then you've only need to define the contents once but each control could be included in each of the layouts you want.

Custom caching for ListView with filtering

I have a ListView with a GridView in my C# WPF application. The ItemsSource is bound to a ListCollectionView created on the ViewModel from an ObservableCollection<MyClass>. I use the ListCollectionView for dynamic sorting, filtering and grouping, all of which can be adjusted or turned on/off from the View.
When I alter the filter or turn the grouping on/off, all of the visual list view items are recreated, which causes the UI to freeze for about a second. Since I have about 250 items displayed and there are about 10 columns (some of which have cell templates with a progressbar), this comes as no surprise.
Now, I know that the obvious answer is to enable virtualization. This however, brings some undesirable effects, such as scrolling becoming jerky or the scroll-bar changing its size as you scroll (this happens with grouping on, since the groups vary in height and so the virtualizing stack panel can not calculate the total height properly at first).
What I would like to do is to have the ListView keep a visual element for every item in the raw list (un-filtered and un-sorted, i.e. the ObservableCollection<MyClass>) and then only add to or remove from the visual tree depending on the changes in the ListCollectionView.
I hope this solution should boost my app's performance, since I rarely change the raw list, but I often alter filtering, sorting and grouping.
Do I need to create a custom control inheriting from ListView (or GridView) to do this, or is there another way?
Try to use DeferRefresh, this delay automatic refresh until the defer cycle is existed. See if that helps.
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(SomeListView.ItemsSource);
using (view.DeferRefresh())
{
view.GroupDescriptions.Clear();
view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
}
http://blogs.msdn.com/b/matt/archive/2008/08/28/collectionview-deferrefresh-my-new-best-friend.aspx

Need a "grid" of stackpanels to be used as a calendar

Ultimately, my aim is to have a grid (by grid I mean rows and columns, however it's achieved) of small stack panels to represent time intervals throughout a day. Not too disimilar from the following I suppose (simple calendar-type layout on the right):
(source: msdn.com)
I need a way of creating this grid dynamically and naming the panels appropriately for whenever an event is fired (to be specific - a drop event, each panel's drop event will be wired to the same method in which I must distinguish what panel (i.e. at what point in the day, and on what row) the item was dropped on).
Thanks a LOT for any help!
Dan
You probably won't get the full code to do that from here, but I can point you in the right direction.
You are probably going to want to use nested ItemsControl. I have done something like this in the past where my outer ItemsControl for the Calendar was a Grid, and grid cell contained an inner ItemsControl with a StackPanel of TaskItems.
The most important part is getting your data layer right. I used CalendarDayModel classes, which had a Date property and an ObservableCollection<TaskModel> list. It also had Commands to handle user events, such as double-click events.
My outer ItemsControl was bound to the ObservableCollection<CalendarDayModel> and the inner ItemsControl were bound to the ObservableCollection<TaskModel>
I have some examples of an ItemsControl here, but take note of the last example that uses a Grid.

Datagrid with large number of rows

In my WPF application, I've got a screen with a tab control. Five of these tabs contain datagrids which need to display a large number of rows (at least 5000). The tables are bound to ObservableCollections of Part objects. Each row displays around 20 points of part data. My problem is that, after the user enters the information they require and generate the data, clicking on a tab causes the application to hang for 30-60 seconds. After this the datagrid finally loads, and with the right virtualization settings, they perform at an acceptable rate (not exactly fast, but not too slow). If I disable virtualization, the program uses up way too much memory, and the loading time isn't really affected.
The most offensive tables consist of about half a dozen template columns. Each template contains controls inside a stackpanel or a grid; basically each row is split into two, like a double-row. This layout is a requirement, and paging is probably not something that the customer is willing to accept.
This is the most important screen in my application and I'm pretty much at a loss about making this work. Is there anything I can do to speed up this process? Perhaps ObservableCollection is the wrong choice?
Can you please provide more insights...
Can you check how much time is spent in "generating" the 5 collections of 5000 rows each? (this is what I assume you are saying)
With virtulaization "on" what is the UI loading time "after" we assign the collection to the items source?
What happen if you bind "ItemsSource" to the respective datagrid only when the tabItem is actually Visible \ Selected?
Do you datagrids have default sort member path? Grouping? Filter Paths?
These are a few things I would target to start on the issue.

Categories

Resources