Resource management when changing window content - wpf

First of all, I do not feel completely educated on how to navigate between multiple "pages" of a window.
For example, I have a Window called MainWindow. Inside of this, I have a header and a footer. In the middle is a panel which contains content.
This panel will originally contain content A. Upon clicking something in A, I want to remove A from view and show a new panel with content B. However, I want B to be shown in the same window (i.e., not hide the window and open a new one). Is hiding/showing these panels the correct way to go about it?
If using the panel switching mechanism is the correct way, then I am worried about resource management. If I set panel A to not be visible, and panel B to be visible, will I still have resources from both panels loaded? If I have a large number of panels to switch between, I would not want to load content for all of them, but rather the active one.
How would I go about making sure that I am correctly handling resources and memory between these different views?
If I have the completely wrong idea about how to switch views within a single window, please let me know.
Thanks.

Instead of toggling visibility off and on, you should put a contentControl and switch it's contents to different UserControls.
That way there's no reference to the UserControl that's offscreen, and you can handle memory issues better.

One alternative is to just use a single ContentPresenter, and put your individual "panels" in there, but only one at a time.
Instead of flipping visibility, you could use Data Binding to change the bound content within the ContentPresenter. This would only leave a single "view" in place at a time, preventing the neeed for "a large number" of panels to be loaded.

Related

How do I get a UserControl or View to refresh, redraw, repaint, etc.?

I have a situation whereby codebehind in a UserControl populates a Grid object with child Grids containing 1 ColumnDefinition and N Row Definitions. Each row definition contains various user controls.
When the code is done creating the control layout, something is being left over in that controls that have been removed are still appearing on top of the controls that should be there.
I think all I need to do is somehow force a repaint of the screen but how is that done?
I've tried UpdateLayout, InvalidateArrange, InvalidateMeasure, etc etc, nothing will force the layout to refresh.
You don't need any call anything to trigger a re-draw, only to trigger re-layouting and that usually only if you write your own panels.
If you see something, it's in the visual tree.

WPF contentcontrol extend beyond the bounds of its parent control

This is a sort of extension of this question I asked yesterday (the question gave me a contentcontrol that can overlay the current control). I now have a contentcontrol that can be overlayed on the current control via bindings (a modal type window). This works well and I am happy with this. One great feature would be if I could get the overlay to go over its parent.
currently the overlay will go into "My Control" control. What I would like is if I can still define it in that control (as that is were it is needed), but when it is displayed it can cover the whole main content area and / or the main window.
is this even possible?
Thanks
Sure it's possible, just wrap it into a Popup! :) You might have to manually stretch it though, but Popup is the control which will let you go outside the bounds of the parent view.
Another way is to host the MainContent in a grid and add a collapsed content control after the MainContent.
To show the popup: put it in the collapsed content control and make it visible.
To hide the popup: collapse the contentn control and remove the popup.

Showing Infragistics UltraTabControl's shared content even with no tabs

We have a screen that shows a grid inside a tab control. There's one grid instance, and it needs to always be visible, regardless of which tab you're on. (We repopulate its content when you switch tabs, but it's always the same grid instance.) The UltraTabControl has a "shared controls page" that seems perfect for this, and most of the time it works great.
However, when the tab control has no tabs at all, Infragistics does not show the shared controls. We need the grid to be visible even if there are no tabs at the top of the tab control.
Is there a way I can get the shared content to show, even when there are no tabs?
Apparently there's no way to do this directly. I wound up working around it by re-parenting the content when there are no tabs.
For example, suppose I have a panel (panel1) that contains the tab control (ultraTabControl1), whose shared page (sharedPage1) normally contains a grid (grid1). I run code like this every time I change the list of tabs:
var anyTabs = ultraTabControl1.Tabs.Count > 0;
ultraTabControl1.Visible = anyTabs;
grid1.Parent = anyTabs ? sharedPage1 : panel1;
Inelegant, but at least it works.
A better way may be to use the UltraTabStribControl.
That's basically just the header of a TabControl without the content Panels.
With that you just need to place a Tabstrip on top and the grid below. But ff you have other controls which are shown dependent on the tab then you would have to hide/show them manually or stick to the full TabControl.

Re-using Buttons in WPF

I have a bunch of different objects that are commonly edited in the same TabControl using different DataTemplates, but I want each DataTemplate to have a common look and feel with Ok and Cancel buttons at the bottom right of each tab that will close the tab or save the content and then close the currently selected tab. What's the best way to place buttons on each tab ? Is there a way to do it without copying and pasting the buttons and stack panel across all of my data templates ?
Sure, you can create your own OkCancelSaveControl. In WPF, creating a "user control" is much easier than it sounds. Here is a tutorial. In a nutshell, you
create a new user control,
create properties in the user control that give the your control the information it needs to perform its duties (e.g. the tab that it's supposed to close or the data object that it's supposed to save),
if necessary, create events that the user control raises (OkClick), in case some tab requires special treatment.
I would make a custom control, lets call it MyCoolTabItem, that inherits from the TabItem class, and just throw your buttons into the control. Then just add a MyCoolTabItem instead of a TabItem to all of your TabControls and it will have all of your buttons on it.
You could make a base view class that held those buttons. Views that needed the buttons would inherit them and common functionality.

Can I make WPF grid controls opaque at design time?

So I'm just starting out with WPF, and I'm really annoyed by the fact that if I lay two Grids on top of one another, the top Grid isn't opaque. It makes designing extremely annoying. Can this be turned off somehow?
I'm just building your standard Winforms STYLE application, but in WPF. I'm just trying to start bridging the gap here. In Winforms(and VB) you'd always have group boxes or something on your form, and then depending on some user context, one of those group boxes would be on top. Its how I've designed forms since time immemorial. One of two things must be true here:
A) This is not the recommended way to design Windows going forward with WPF, but I don't understand what you're supposed to do
B) There is some property to make the Grids opaque so I can build the Window in the style that I'm used to.
I'm fine with answers that solve either A or B. If I'm not doing things the right way because they've changed, then please enlighten me.
Update: So it turns out, I can make the grid opque by setting the background color, but now it seems like I'm locked into a White background as opposed to sticking with the system colors.
You could use SystemColors to make the control background colour match (rather than being white).
I don't understand why you want to put one grid on top of another though. In WPF you generally use a single grid to stack multiple visual elements within one region. Can you explain why you want to hide things in the background with foreground elements?
It sounds a little like you're implementing a tab control -- switching between pages of controls depending on focus. Have you experimented with the new TabControl?
I'm moving from WinForms to WPF development wherever possible and have found that in doing so it's taken some readjustment. WPF has a completely different way of laying things out and now that I'm more comfortable with it, I think it's superior. I'm guessing you just need to ride the learning curve a little longer.
Hope that helps.
EDIT: In response to your comment, I imagine you can have a tab control without tabs, though I haven't tried it myself (might be worthy of another question on SO). Tab controls are headered controls, meaning that they have a header item and a content item. In this case, the header is the tab button, the content is the page item. You can specify a ControlTemplate that details how these items should be displayed relative to one another.
Interestingly, many other types of common GUI element are also headered controls:
Menu items - The menu item text/icon is the header, and the optional submenu is the content
Tree view - Each node is the header, and optional children are within the content
Group box - The header is, well, the header and the content is, well, the content :)
Note that in the case of menu items and tree views, the type may recursively nest within itself. This is quite elegant and can give some wildly different presentation options over the same logical model with only changes to the control template.
For more information read about HeaderedContentControl and HeaderedItemsControl
You could use the following:
<Grid Background="{DynamicResource {x:Static SystemColors.WindowBrush}}">
<!-- content -->
</Grid>
This will respond to changes in the system colors on the fly (the DynamicResource does this).

Resources