Composite Application Block Region injection slow - wpf

Im building a wpf app with the composite application block ("prism") V2, and Im having an issue where a user control that is injected by a module is very slow in rendering. The user control contains a datagrid with some 2000 rows in it and there is considerable lag in the control rendering to the screen. Initially I thought the slowness was due to the wpf toolkit datagrid control itself but this is not the case. When I move the control containing the datagrid (TestControl) out of the external module and into the shell project and load it straight from there the control renders immediately without any problems.
Im using the following code in the implementation of IModule in my module to inject the wpf user control into the shell
this.regionManager.RegisterViewWithRegion("mainRegion", typeof(TestControl));
Is there performance issues when loading controls from other modules in a prism app? Whats the most optimal way to load them in?
Thanks

the problem here seemed to be wpf being slow to update when the UI is being updated vai the dispatcher from a background thread. I took up the conversation on codeplex and got it more or less sorted.
http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=64113

It's likely this is an artifact of the lifecycle events. Your shell is going to display well before your modules start to load and register themselves. If you do this it will "appear" to take longer because your UI will appear with a big fat hole in it until the module initialization code fires.
A lot of the samples have you doing something like "Shell.Show();" in your CreateShell method of your bootstrapper, but you might consider moving the references to the Shell to a private member of your bootstrapper class and calling .Show() on it in, like this:
public class Bootstrapper : UnityBootstrapper
{
Shell shell;
protected override DependencyObject CreateShell()
{
shell = Container.Resolve<Shell>();
return shell;
}
protected override void InitializeModules()
{
base.InitializeModules();
shell.Show();
}
I tried this just now and it definitely felt like my app got a performance boost, so I think I'll make this change myself.
If your modules take a really long time to load, you also might want to show a splash screen between CreateShell and after InitializeModules.

Related

WPF - Display usercontrol dll's name as they load in splash screen

I am in the process of writing a WPF application that hosts 10+ usercontrols I have written. What I would like to do is modify the code from "Wonko the Sane"'s answer in this post
Is there a way to show a splash screen for WPF application?
to dynamically show the name of these usercontrol dll's as they load.
I have not been able to find anywhere how to get the names of dll's as they load.
Any assistance would be appreciated.
Thanks, Jim
Sorry, but you won't be able to do that. The WPF Framework loads before your program starts executing. The best that you'll be able to do is to add the names of the relevant DLLs into a string collection and then loop through them, displaying each one temporarily. Even if you could display what was being loaded, the chances are that they'd actually load so quick that you wouldn't see anything anyway.
It's also worth pointing out that it is only really worth having a splash screen in a WPF Application if you have a real lot of initialisation loading to do. In that case, you can show what the application is doing, but you'll probably find that in most cases, the loading is still done too fast for the UI to update in time.
You can get the current application domain and then use AssemblyLoad event to get loaded Dll name.
AppDomain MyDomain = AppDomain.CurrentDomain;
MyDomain.AssemblyLoad += new AssemblyLoadEventHandler(SplashControllerObject.LocalEventHandler);
private void LocalEventHandler(object sender, AssemblyLoadEventArgs args)
{
//use sender.LoadedAssembly.FullName for DLL name loaded
}

Prism application with no initial shell

I've been creating a WPF application that initially loads as a task bar icon and then when clicked opens an appropriate window. This was a prototype and I want to move over to Prism and having watched the (superb) videos by Mike Taulty (channel9.msdn.com/niners/mtaulty) I have the feeling that what I need to do is create an application with a custom bootstrapper that does all the service registration but does not create an initial shell but instead simply loads the modules and perhaps identifies a module to Run. Has anyone anyone done something similar, if so how much work am I in for?
OK I bit the bullet and just tried it. I should first state that I was using the Autofac version of the Bootstrapper.
I returned null to CreateShell
I marked the apps ShutdownMode="OnExplicitShutdown" in the declaration at the top of App.Xaml (important otherwise it closes the application when you close the last window)
I created a module (IModule derived) that loaded the WPF notify icon by Philipp Summi (http://www.codeproject.com/Articles/36468/WPF-NotifyIcon)
In response to a command from the context menu on this icon I simply create the window and it's view model and show it.
This all works just as I had hoped. The only thing I have yet to do is see how to use regions with these temporary windows although other articles appear to have this covered. I'm not convinced the Autofac bootstrapper gives me any great advantages but I had developed a very early prototype using Autofac and stuck with it because it went smoothly. I will probably go with Unity or MEF in the long run just to avoid compatibility problems and to allow dynamic module loading from external plugins.

Performing unit tests in a code behind file

I'm implementing a WPF application using the MVVM pattern.
The application is basically a communications panel (comms panel) with control widgets laid on top of it (e.g., dial pads, intercom lines, etc). The control widgets have also been implemented using the MVVM pattern, as this allows us to easily test them on an individual basis.
A few hours ago, I posted here because I was having problems in order to link things between a DialPad and CommsPanels viewmodels. After a long chat with another SO member, I managed to get the link working. However, in doing that, I made heavy modifications in the DialPad code, such as getting rid of its model and moving the viewmodel code to the codebehind file. The problem is, not my unit tests are not working, mainly because NUnit is throwing an exception everytime I tried to instantiate a DialPad codebehind's class, which inherits from UserControl. Is there any way to write unit tests for a class that inherits from a WPF class (such as UserControl)?
Thanks in advance!
One option would be to take the important code from the code behind and put it in it's own class (that does not inherit from UserControl), which is then wrapped by the code behind.

WPF Prism - load view dynamically in pop up window

We have multiple project solution based on MS Prism in WPF. For ease of understanding lets take we have project shell, and project usercontrol. The usercontrol project has numerous views for various functions. We have a pop up window in shell project which is called from main shell window, what i want is to load different view into pop up window region manager based on requirement. Any help/suggestion through flow explanation or some code samples will be highly appreciable.
Regards
You can use the PopupRegionBehavior that comes with the Prism-v2 RI to achieve what you are trying to do in a decoupled way. You can read more about it here.
Please let me know if this helps.
Thanks,
Damian
Using a Dependency Injection Container (such as Unity which can also be obtained from the CompositeWPF Microsoft page), you'll be able to pass around an instance of IRegionManager to your various modules/pop-up windows...
For example, in the view you wish to inject another view into, you could have a named ItemsControl:
<ItemsControl cal:RegionManager.RegionName="Modules" />
To fill it with your custom view, all you'd have to do from code is:
_regionManager.Regions["Modules"].Add(view);
(Where _regionManager could be an instance variable populated via Dependency Injection to the constructor of the class it's in). Don't worry about registering the IRegionManager interface with the container, that's done by the UnityBootstrapper during configuration.

Proper cleanup of WPF user controls

I am relatively new to WPF, and some things with it are quite foreign to me. For one, unlike Windows Forms, the WPF control hierarchy does not support IDisposable. In Windows Forms, if a user control used any managed resources, it was very easy to clean up the resources by overriding the Dispose method that every control implemented.
In WPF, the story is not that simple. I have searched for this for several hours, and encountered two basic themes:
The first theme is Microsoft clearly stating that WPF does not implement IDisposable because the WPF controls have no unmanaged resources. While that may be true, they seem to have completely missed the fact that user extensions to their WPF class hierarchy may indeed use managed resources (directly or indirectly through a model). By not implementing IDisposable, Microsoft has effectively removed the only guaranteed mechanism by which unmanaged resources used by a custom WPF control or window can be cleaned up.
Second, I found a few references to Dispatcher.ShutdownStarted. I have tried to use the ShutdownStarted event, but it does not seem to fire for every control. I have a bunch of WPF UserControl's that I have implemented a handler for ShutdownStarted, and it never gets called. I am not sure if it only works for Windows, or perhaps the WPF App class. However it is not properly firing, and I am leaking open PerformanceCounter objects every time the app closes.
Is there a better alternative to cleaning up unmanaged resources than the Dispatcher.ShutdownStarted event? Is there some trick to implementing IDisposable such that Dispose will be called? I would much prefer to avoid using a finalizer if at all possible.
I'm afraid that Dispatcher.ShutdownStarted really does seem to be the only mechanism WPF provides for disposing of resources in UserControls. (See a very similar question I asked a while ago).
Another way to approach the problem is to move all of your disposable resources (if at all possible) out of the code behind and into separate classes (such as the ViewModel when using the MVVM pattern). Then at a higher level you could handle your main window closing and notify all the ViewModels via a Messenger class.
I am surprised you don't get the Dispatcher.ShutdownStarted event. Are your UserControls attached to the top-level window at the time?
The IDisposable interface has (almost) no meaning under WPF, because the mechanism is different from Winforms. In WPF, you must bear in mind the visual and logical tree: that's fundamental.So, any visual object generally lives as child of some other object. The base of the WPF building mechanism is to attach the visual object hierarchically, then detach and destroy when they aren't useful.
I think you may check the OnVisualParentChanged method exposed since the UIElement: this method is called either when a visual object is attached and when is detached. That could be the right place to dispose the unmanaged objects (sockets, files, etc).
I was looking for this too and after testing differents options I implemented the solution of venezia
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
if (oldParent != null)
{
MyOwnDisposeMethod(); //Release all resources here
}
base.OnVisualParentChanged(oldParent);
}
I realized that when parent call Children.Clear() Method and had already items added to Children, DependencyObject had a value. But when parent added an item (Children.Add(CustomControl)) and children was empty DependencyObject was null.
While others have given you really useful information about this problem, there is a little bit of information that you may not have that will explain a lot about why there is no IDisposable. Basically, WPF (and Silverlight) makes heavy use of WeakReferences - this allows you to reference an object which the GC can still collect.
I've got this difficult when I'd used some connection to the database, using some IDbConnection implementation driver or Entity Framework.
I've found in these cases the recommendation is to keep one object connection/context per window, to be able to track changes/transactions. (link)
So I've overridden the OnClosing:
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
this._context.Dispose();
}
The context can be my ViewModel/Control which implements IDisposable to clean resources.
Sample use of OnClosing to dispose of resources (link)

Resources