WPF precompiled resources in WinForm application? - wpf

I am working on an application that started out as a WinForm but it is now utilizing WPF windows with UI. The interaction is all working beautifully but when the WPF windows are first shown it takes quite a long time (around 1-3 seconds) for them to show. So long that some wonder if the app has crashed (until the content shows). The second time the same windows are invoked they come up quickly. I need them to come up quickly the first time around.
I am making use of styles and control templates that are located as XAML in the resource folder. In the XAML for the WPF windows I then merge them into the windows resource dictionary. The Build Action for those (in VS 2010) needs to be set to "Resource".
Preferably I want to keep them in separate files for easy maintenance.
As far as I understand if the build action was "Page" the XAML would be precompiled and should load faster but if I set it to Page I cannot merge them into the resource dictionary. Is there a way around that?
I am fairly new to this part of WPF and so far my internet search hasn't been successful.
To be clear: I am not talking about WPF controls being embedded in WinForms. I am talking about entirely separate WPF windows that are spawned from the WinForm context.
Is there a way to precompile the entire app or at least all XAML (it's all static, no dynamic XAML)?
Thanks in advance!
Edit: The UIs are not heavy by any means. The ones in question have between 5 and 20 buttons and the usual containers (basically a grid with 1 or 2 stack panels).
Update:
I tried precompilation with "NGEN install appname" - no effect on WPF window load.
I included all resources and templates into the window.xaml - no effect.
(window.xaml is pre-compiled)
I found this really interesting article about pre-jitting upon app load here:
http://www.codeproject.com/KB/dotnet/pre_JIT.aspx
(I used the improvement suggested by 'ittay ophir')
again: no effect on WPF window load...
The load times simply won't change on first load but they are significantly reduced on all consecutive loads (loads in 20ms or less).
What the heck is going on here?

How about loading the XAML asynchronously using XamlReader.LoadAsync Method ?

Related

Convert wpf application to wpf browser application

Is it possible to convert wpf desktop application to wpf browser application? I want to make my application run from browser.
According to my experience there is no converter available which converts WPF to XBAP.
But I did work with multiple platforms together several time in my project. I do maintain 3 platforms together WPF, Silverlight and XBAP in a single solution having single code base. I keep a common code-base and share files between 3 platforms. To achieve this I suggest you to create a Hello world XBAP application and run it first. You need to have few basic idea about how an XBAP application works. Initially understanding the entry and exit point of the application will be enough for you. Try adding one button in Page and understand how it works. Once it’s done then try to link the existing project files (XAML and CS) one by one into the XBAP project. Understand what you are adding and why are you adding. Yes it's quite a hard work you need to do. But don’t worry XBAP, WPF XAML & C# codes are almost similar. You need to know that Conditional compilation symbols can be set in project properties. So that you will be allowed to write #if XBAP & #endif statement in your code sometimes, because few classes or features may not be supported in XBAP and you need to write specific code for XBAP. As an example Dropshadow related features are not available in XBAP.
Hope this answers your query!

Suggestions for replacing legacy VB6/Flash application with WPF/Blend application

We have a legacy application that utilizes VB6, the Flash ActiveX control, and Flash content to display animated movies to users. For plenty of reasons we're looking to migrate away from this. I'm hoping someone out there can answer a few questions about WPF so that we can make a determination about how best to move forward.
First, a little about our current architecture and needs. The Flash content is set up as separate SWF files, where each individual SWF represents a training module with animated content. We have hundreds of these modules. Users run this software in a disconnected fashion where their local machine may or may not have ALL of these SWF files. The current application gives the user the option of downloading the SWF modules as they're needed.
Here's how we're thinking about setting up a new solution using WPF and Blend. We've written a WPF host application that can dynamically show Blend content based on button presses or whatever. And we've created a few test modules in Blend as WPF custom controls. But there are three nagging questions:
Right now we have the custom controls within the main WPF solution, but we need to make these disconnected. I've read several things about using Application.LoadComponent but I don't know if that will work for our solution.
Each of the Blend custom controls contains one or more storyboards that control the animation. As soon as I add one of the custom controls to a container in the WPF app, ALL of the storyboards automatically start "playing". How can I programatically make it so that I start/stop certain storyboards as needed?
Let's say I want to change a text label in one of the custom controls. If we're dynamically loading the custom control, how would I access one of the text labels to make such a change?
Any tips would be greatly appreciated. Loving WPF so far and hoping we can make this work and say goodbye to Flash forever!!!
There is Manage Extensibility Framework, that is a standard approach for dynamic modules.
Anyway, I haven't used it, so I would answer the questions in other way:
1) No, LoadComponent is ised for xaml files, whereas custom control consist of code and xaml. I mean, the custom control that you can add using Add->New Item->Custom Control(WPF). So you should do something like this, with reflection and ContentControl:
Assembly asm = Assembly.LoadFile(#"C:\SomeLibrary.dll");
Type type = asm.GetType("SomeNamespace.SomeControl");
var control = Activator.CreateInstance(type) as Control;
this.myContentControl.Content = control;
2) It isn't fact. You can put the storyboards into Control.Resources and launch them manually.
((Storyboard)control.Resources["myStoryboard"]).Begin(control);
3)
control.FindName("anyname") as TextBlock;

WPF XAML code-behind management

I have wandered into a WPF application project and have made some good progress, but one thing I am finding is that the code-behind page is now getting longer and longer... since there is only one XAML page to the whole application, the code-behind page that really just takes care of the event handlers and programmatically created controls for the design page, is now over 2000 lines. The VS2010 IDE helps in navigating all the methods, etc, but I am wondering if I am missing something as far as organizing all my controls and code-behind. Is there a way to break out some of the UI of the application into multiple XAML pages, so the code-behind will be more compartmentalized to a specific set of controls. Any search I do on multiple XAML file applications in WPF immediately leads me to XBAPS and I am interested in staying with the desktop WPF. Aside from creating regions in the one code-behind, are there any other strategies I can use to organize this code (in separate XAML files)?
Thanks!
At a minimum, separate out parts of your UI into separate UserControls, instead of including it in a single "view" in a single Window.
That being said, separating our your logic and using a pattern like MVVM will make this much cleaner in the long run. It sounds like you're using lots of event handlers - I wrote a blog series designed to help migrate from this style of development to a more MVVM style. It might be worth glancing at for ideas. It describes how WPF allows you to move away from having lots of event handlers by keeping your application logic separated from your UI code.

Problems when splitting Silverlight App into smaller components

I have a Silverlight 3 App that became quite big over the time. So I began to try to break it in several smaler Applications that will be dynamically loaded in my Main Application on demand. But I run into a strange problems with my VS 2008.
When I add a new Silverlight Application project to my solution and copy User Controls from my old Main Application into this new project it happens from time to time (about twice a day) that the XAML files and their code behind files loose their association. When this happens and I try to build the project, the compiler complains that he cannot find all the Ccontrols like buttons, labels etc. in the code behind files that I added to the class in the XAML-file. And the build fails of course.
The only workaround that I found so far is to add another Silverlight Application project and move all the content from the first added project to it. Than everything works fine for a while until the problem occurs again.
But that's not really a solution.
Any Ideas what happens here and what i can do?
Best Regards,
Rocko
I have seen issues like this before when changing the namespaces on controls in silverlight. The issue crops up when you don't change both the namespace on the control class, and the full name of the class in the x:class attribute on the root element of the control.
Not sure if this fits your situation or not, but it's the only time I've run into similar issues.

What are the issues with running WPF across multiple AppDomains on one UI thread?

We are looking at creating a WPF UI that runs across multiple AppDomains. One of the app domains would run the application while the remaining AppDomains would host a series of user controls and logic. The idea, of course, is to sandbox these User Controls and the logic away from the main application.
Here is an example of doing this using MAF/System.AddIn. What are some of the experiences other have had with this? How does this solution handle RoutedEvents/Commands that might occur inside one user control and do these get properly serialized across AppDomains? What about WPF resources? Can they be accessed across AppDomains seamlessly?
Old question, but nonetheless: You will need to have multiple UI threads - one per AppDomain. Create them like this:
var thread = new Thread(() =>
{
var app = new Application();
app.Run();
});
thread.Name = AppDomain.CurrentDomain.FriendlyName;
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
The biggest challenge is then that you cannot send FrameworkElements between AppDomains (they are not MarshalByRefObject), but you can use the FrameworkElementAdapters.ViewToContractAdapter() and ContractAdapterToView() methods to work around this limitation. See the FrameworkElementAdapters MSDN page for more details.
Then, once you have this in place, the biggest problem IMHO is that you cannot lay anything on top of the FrameworkElement from the "remote" domain (the classical "airspace problem"). See this thread for more info about this.
I answered a simular question here and edited it for WPF also, you can use an intersting property of how the compisition engine operate's to tail-coat a dispatcher Pump, into one of the rendering contexts. It's a really light weight option.
Also, I'm guessing you know about the enterprise library and unity?
There is a WPF application block so using that pattern is not too painful ;) But don't they say, no pain no gain?
There's also CAB (Composite UI Application Block), ties into unity. The WPF SDK folks have crafted a Silverlight & WPF platform. (a.k.a Prism).
Oh right, also, you asked about Resources? I prefer to load reasources manually in the Application class. One thing I've realized, say you have a ResourceDictionary in a sub-folder and you are loading up MergedDictionaries in that ResourceDictionary. So, if in your Application class, you load "my-res-dir/MergedDictionaryLoader.xaml" (by code or xaml), ALL FUTURE LOADS OF MERGEDDICTIONARIES ARE LOADED FROM "my-res-dir".
Sort of insane if you ask me, I would think that as the process current directory has not changed, you should specify "my-res-dir/foo.xaml" for all your additional directories. However this is not the case (I do not believe this is documented anywhere at least very well and should be considered a bug imho).
So remember, WPF resource dictionary loading is going to be based off of the directory from which the current XAML is in. So you specify Source="foo.xaml" from within your "my-res-dir/MergedDictionaryLoader.xaml". I've even played with the URI pack / absolute syntax, however I've never found that too be much more intuative.

Resources