Title: Changing heavy UserControls in WPF Window
Tags: c#;wpf;optimization;user-controls
Question: I have read a lot of subjects on the matter, on how to replace the displayed UserControl in WPF.
Suggestions tend towards Databinding of Content Control, and Kent Boggart answer to this question.
Anyways, the first problem is that my User Controls involve heavy graphical display, and are using common resources, not accessible at the same time.
What I mean by heavy graphics, on the OtherControl, there is a couple of videos plus a 3D model, reacting to dynamic events. The BallControl has an ellipse with TranslateAnimation, and a Margin reacting to events. I believe the whole project is a bit heavy due to the dynamic events rendering the pages.
So my solution was not ideal : I am clearing the content in the Grid, and replacing it with the needed User Control (the Grid takes the whole page).
The difference with the post above is that I would like (if possible) to keep my User Control as is.
The problem is that, these controls need to be switched very often, and after 1 or two hours using it, this Exception show up (line specified in the code):
System.ArgumentException : Specified Visual is already a child of another Visual or the root of a CompositionTarget class.
System.Windows.Threading.Dispatcher.Invoke(Action callback, DispatcherPriority priority, CancellationToken cancellationToken, TimeSpan timeout)
My code is obvisously wrong and I wished a cleaner solution. What's more, I've understood that there is only one UI thread, and pre-load already constructed Controls before diplaying them was not possible.
To be more precise, a bit of code is more than welcome :
MainWindow.xaml :
<Window x:Class=&quot;Testing.MainWindow&quot;
xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
xmlns:local=&quot;clr-namespace:Testing&quot;
xmlns:h=&quot;http://helix-toolkit.org/wpf&quot;
Title=&quot;MainWindow&quot; Height=&quot;1080&quot; Width=&quot;1920&quot; WindowStartupLocation=&quot;CenterScreen&quot; WindowStyle=&quot;None&quot; MinHeight=&quot;1080&quot; MinWidth=&quot;1920&quot; ResizeMode=&quot;NoResize&quot;&gt;
<Grid x:Name=&quot;Griddy&quot;&gt;
</Grid&gt;
MainWindow.xaml.cs :
BallControl _boule;
OtherControl _otherControl;
public MainWindow()
InitializeComponent();
Mouse.OverrideCursor = Cursors.None;

EventReceive.Subscribe(this);
// Instanciate both UserControls
_boule = new BallControl();
_otherControl = new OtherControl();
panelToDisplay = Turn.Ball;
Griddy.Children.Add(boule);
/// <summary&gt;
/// Event coming from panels to notify which one is to be displayed
/// returning value is an Enum
/// </summary&gt;
public void Receive<T&gt;(T arg) where T : EventArgs
var casted = arg as EventArriving;
if (casted != null)
{
PanelToDisplay = casted.TurningTable;
}
private Turn panelToDisplay;
public Turn PanelToDisplay
get { return panelToDisplay; }
set
{
if (panelToDisplay != value)
{
panelToDisplay = value;
if (panelToDisplay == Turn.Other)
{
try
{
this.Griddy.Dispatcher.Invoke((Action)(() =&gt; Griddy.Children.Add(_otherControl))); //Where the exception shows up
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
try
{
this.Griddy.Dispatcher.Invoke((Action)(() =&gt; Griddy.Children.Remove(_boule)));
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}

}
if (panelToDisplay == Turn.Ball)
{   // Bad Pattern where I remove a control to display another one.
try
{
this.Griddy.Dispatcher.Invoke((Action)(() =&gt; Griddy.Children.Add(_boule))); //Where the exception shows up
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
try
{
this.Griddy.Dispatcher.Invoke((Action)(() =&gt; Griddy.Children.Remove(_otherControl)));
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
}

}
To summarize a little :
How do I replace/change/add &amp; remove a User Control from the MainWindow in a clean way?
How do I make it look like it doesn't have to load back up each time it changes, even when the controls are graphically heavy?
Comment: Can you post a screenshot of your usercontrol, and further explain what heavy loading you're doing here?

Comment: *"It crashes"* With what exception? On what line?

Comment: I'd add some logic to catch the exception and display it in that case, it would be helpful to know what it is complaining about.

Comment: Actually in debug it never does, only when I test the .exe

Comment: @RonBeyer You were absolutely right, please see my updated answer

Comment: @HighCore I would love to be more precise, but the project belongs to my company and they want it under the radar for the moment. What I could tell you is that on the Other page, there is a couple of videos plus a 3D model reacting to a lot of events.
On the Ball page there is a simple ellipse but with Translate Animation and Margin movement reacting to events. Is it enough? In the meantime, I am adding these elements in the question.



{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 0, 'CommentCount': 6, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2015:00:11/06/15', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<c#><wpf><optimization><user-controls>', 'Title': 'Changing heavy UserControls in WPF Window', 'ViewCount': 245, 'id': 33569094, 'user_AboutMe': '', 'user_AccountId': 5389225.0, 'user_DisplayName': 'LePingu', 'user_Reputation': 79.0, 'user_Views': 50.0, 'user_id': 4292263.0}}