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

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.

Related

How can I write WPF efficiently?

When I first learned about Microsoft's then-new framework for developing desktop applications, WPF, I thought that one of the biggest benefits of it would be its efficiency. After all, I already know what the GUI controls and elements were that I wanted to use--I just have to slap them all on the page and then wire up all my bindings right, and I'll be done. After that, I learned about the MVVM pattern, which promised clean separation of concern within my WPF app.
I thought this was going to be great! I got into creating several different admin and data entry WPF apps with my team at work, and thus I began to crank out working software with robust but simple GUIs, right?
Not so fast, there, cowboy coder. My experience is that writing WPF is S-L-O-W.
Well, at least the way I do it. You see, after I have a picture of my GUI on a whiteboard, I code up the XAML with the controls that I want. This part, as expected, is fast--laying out the whole of a window is pretty quick. After that, its all the little stuff you want these elements to do takes awhile. I always seem to want to make this text bold in some cases; show a red error box in these other cases.
Then things unravel: this binding isn't working right over here--I have to write a converter and adjust the layout for the right values. Whoops, I forgot that extra NotifyPropertyChanged there. Oh, and I want to use a different template in this state vs. that, so I have to figure out what I can use to swap the templates in certain situation. This data is coming in asynchronously, so I need to make sure the right thing is happening on the right thread and that Property gets NotifyChanged as well. Crap, when I maximize my window, it doesn't stretch like I thought it would--must be because its container height isn't defined, but I don't want to define that, so I have to make it stretch in its parent. Oh, now I really want to make a user control out of this stuff over here, so I better implement some dependency properties...
On and on I go, spending hours and days on stuff that just feels so small and minor. I soon resort to cutting usability features and look-and-feel enhancements because this is taking just too darn long.
Does anyone have any tips or principles I need to try in order to write WPF efficiently?
A couple of things that have saved a lot of time for me:
Use DockPanel as your default panel for layout unless you have a good reason not to.
Keep a folder full of useful classes: a ViewModelBase class that implements INotifyPropertyChanged, a RelayCommand class, etc. There's no need to get fancy and try to make this a separate assembly that you build into your project; just write reasonably good implementations and copy/paste them into your new projects.
Get Resharper and use it. Use templates for creating dependency properties, properties that do change notification, and commands.
Find or build a good library for asynchronous task management.
I find that even for very simple applications I get more done faster with WPF than I did with Windows Forms. For applications that aren't very simple, there's absolutely no comparison.
For the most part, WPF applications are a lot of work to develop because it's harder to make the case for cutting out UI features. You can't just say, "Oh, that's not possible," because it probably is possible (whatever "it" is).
Write your own library, or find an existing one.
WPF is great, but out of the box it is missing some things that would make coding faster. I got tired of writing the same things repeatedly, so I ended up creating my own library full of things like converters, visual tree helpers, attached properties, custom controls, etc., and since then, my development time has sped up considerably.
In addition to my own library, I've also started using Microsoft's Prism and Galasoft's MVVM Light Toolkit. Both contain useful objects that I use all the time and are better than what I could code on my own. (Most used are NotificationObject from Prism, RelayCommand from MVVM Light Toolkit, and EventAggregator or Messenger from either one depending on the project, etc.)
Another thing I've done to speed up coding time is to take advantage of Visual Studio's macros. For example, to create a property with Change notification, I write the private property, hit Ctrl+E, Ctrl+R which generates the public version, then run a macro which automatically sets up the PropertyChanged notification in the setter method.
I almost never change the setter methods from the default macro'd one, and instead use the PropertyChanged event to handle any changes that should occur on the setter. This not only makes it easier to track application flow, but also greatly reduces the time I used to waste browsing through my public properties to alter a setter method.
I believe the right answer isn't for WPF at all, but it can fit what you're looking for.
Most of the times, when you want to leverage a new technology there's a time while you're not efficient, productive and your solutions aren't that impressive, innovative or just doesn't look like others.
What will give you more efficiency is working with WPF itself.
It's more about project management topics than programming. After finishing some project, your team and you should go to some room and discuss:
Success stories.
Problems during development.
Pros and cons.
Fails in the application architecture.
Communication problems within the team and customer.
... and so on.
If everyone shares their knowledge, project manager or team leader does a good job documenting each project story, finally everyone will have a "know-how".
In addition, it's important that you won't need to reinvent the wheel for every new project: if some pattern worked fine, do the same way next time, even if it's not the best way of doing it. And try to enhance it, if possible.
Design patterns, technologies, paradigms, languages, companies, colleagues and nothing are a silver bullet: Microsoft said WPF is a step-forward in Windows client developments, and it is that: a more modern approach to provide shinny user interfaces and a programming paradigm that fits nowadays' desired approaches, easing the relation between coders and designers, as WPF has XAML, which allows not only separation of concerns, but separation of professionals by area (designers, UI programmers, business programmers, ...).
Finally, as I said above, WPF won't be your silver bullet: learn from your own success and read a lot, see sample applications, download open source solutions, listen your colleagues, drink a coffee and, after all, after some headaches, some day in the near future, you'll leverage these technologies (and many others).
EDIT
I'd like to add that a good way of using the know-how is creating a Visual Studio guidance pack, so you can automate a lot of tasks like creating managers, views, models and other things just in the way your team would do by hand.
For example, you can create a guidance pack for a WPF CRM-like application and you can automate module creation. When you want to add a new module, guidance pack starts a process which adds all the necessary classes to start development this new module, and it can create a sample form already associated with a navigation manager, controller or whatever (it's just an example).
Guidance pack and T4 would be both good tools for automating tedious or repetitive tasks in everyday's tasks:
http://msdn.microsoft.com/en-us/library/ff631854.aspx
http://msdn.microsoft.com/en-us/library/bb126445.aspx
I have been using WPF since 2008 and can honestly say to do it right and clean does take more time than the same thing in WinForms would take to develop. I have written a lot more WPF than Winforms. That being said - if I need a simple internal utility - it is ALWAYS Winforms. If I have something forward facing to a client - it is always WPF. Why? Winforms are cheap and dirty and you get a lot for free. What you don't get is the fit and polish that WPF can provide. The flexibility with WPF does come at a cost - but in the longer run it's worth it for public facing software.
Yes WPF is a hurdle but it also has rewards. You are on the right track with a design pattern such as MVVM. Sounds like you have not even gotten to the "rewards" of dependency properties or event bubbling. But the control over the UI is great. Almost everything is a content control. In forms I was always writing custom controls to get the UI I wanted. In WFP I have never had to write a custom control for UI and doubt I ever will. The syntax is new but it is compact - I rewrote a Form app in WPF and the WPF has 1/3 the lines and more features. Read a whole book on WPF just to get grounded - I like PRO WPF in C# 2010. You could also say LINQ is complex but man does it do a lot in just a few key strokes. WPF is not something you just pick up on the fly as you next application.

WPF, MVVM, Shell and UserControls

I am building a WPF app that is based on the MVVM pattern (using MVVM Light). It has an outer "shell" to it that gives the main look to the app (status bar, etc.) and then all the content is contained in various user controls that I swap out with the Telerik RadTransitionControl. My two questions related to this are as follows:
I am building my ViewModels using the ViewModelLocator part for Blendability purposes. This involves a basic static class that returns a new instance of a ViewModel for binding and instances are essentially shared as long as the app is running. The question for this is whether I should use a concept such as a "ViewLocator" in that it is a static class that has a static property for all of my views (the app has ~10 so it's not huge) and when I need to transition to a new view I just pull from the static set. The pros of this are ease of use, but are there cons? Is there a better way to pursue this?
What is the best way to transition views? Currently I am passing an enum to my shell view (via messaging) to indicate which view I need, but this seems really hacky and doesn't support passing certain views arguments. I toyed with a custom class, but I would almost need a different one for every view and it seemed like it might be overkill. What is the standard practice executed by WPF devs for this process?
Thanks in advance for the help. I'm fairly new to WPF so I want to make sure I learn the industry standards and avoid hacks wherever possible.
I work on an application that uses the same pattern. We have a static locator and reference the same ViewModel every time we switch to a different part of the application (details view, list view, map view, etc.) We have had a lot of success with the ViewModelLocator pattern - it is pretty easy to understand. We have not done significant testing with running the application for multiple hours.
We use a TabControl with the tab styling removed to transition between the main screens of the application. This gives us one point of entry (the selected index property that we bind on the "naked" Tabcontrol) to change the major screens of the application. For now, we do not use animations.

Silverlight Composite application

I'm trying to figure out what would be best solution to the problem I'm facing. I have a Silverlight application which should be composed from different modules. I can use Prism, place regions and load modules and fill regions with loaded modules but this is not enough in my situation. Here's what I want to accomplish:
For most views that gets loaded from different xap files, I should place an element somewhere in the shell, which will perform navigation to the dynamically loaded view.
That element (which links to dynamically loaded view) should support localization and should have dynamically assignable data templates, different module links should have different content/data template (I'm thinking writing data templates in xaml files on the server and reading them from silverlight via XamlReader, maybe there's a better way?).
Uri mapping and browser journal should work with navigation. Silverlight default navigation mechanism better suits my needs than the one found in Prism.
The architecture should support MVVM.
I think thats all. I just couldn't think of a good architecture which will satisfy all my needs. Any help would be greatly appreciated.
I do not know of a single product/solution that would cover all your requirements, so here are some comments on each:
If one area of the shell has a region that supports multiple items, you just register a control of type link/button etc with the same region name in each module. For example we register views based on the Telerik TadRibbonTab (instead of UserControl) with a region named "views" which is a RibbonBarTab with a region named "views". Every module then adds its its own button to the list. You can do the same thing with any multi-item container.
Localisation is a completely different issue and can be solved in a number of ways. See my answer here: Load Resources ".resx" from folder in Silverlight
A custom navigation mapper can be made to behave like the standard one, without messing up the support for Prism regions. The one we created encodes GUI information such as current selections (current view and item selections etc) into the URL. That means we are in total control of the state and the URL controls the state.
Hardly anything stops you using MVVM as that is one small feature for separating views from code-behind data.
I will be interested in what other solutions are proposed as we are always looking for new ideas too.

How to avoid visual artifacts when hosting WPF user controls within a WinForms MDI app?

When hosting WPF user controls within a WinForms MDI app there is a drawing issue when you have multiple forms that overlap each other that causes very distinct visual artifacts. These artifacts are mostly visible after dragging one child form over another one that also hosts WPF content or by allowing the edges of the child form to be clipped by the main MDI parent when dragging it around. After the drag and drop of the child form is completed the artifacts stay around generally but I've found that setting focus to a different application's window and then refocusing back on to my application window that it is redrawn and all is good again until the child forms are moved once again. Please see the image below which demonstrates the problem.
Those at Microsoft insist that the WinForms MDI is already a sufficient solution for MDI and doesn't need reinventing in WPF although I find it hard to believe they tried creating a WPF app this way because of the obvious shortcomings.
UPDATE: A few extra notes that I left out is that if I create these Forms without setting the MdiParent they are created as regular forms and this issue doesn't happen. This issue seems unique to the WinForms MDI scenario. Also I've currently running on Windows 7 Enterprise and I'm aware the results may be quite different on Windows XP but I haven't been able to test this.
UPDATE: I've found a few other related resources on this issue that I thought I should share.
elementHost repaint problem in MDI
application
elementHost repaint problem in MDI application on Tech Archive
It appears that another workaround is to revert to software rendering as opposed to taking advantage of hardware acceleration. This was the suggestion by Marco Zhou on the MSDN Forums.
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
this.Loaded += delegate
{
var source = PresentationSource.FromVisual(this);
var hwndTarget = source.CompositionTarget as HwndTarget;
if (hwndTarget != null)
{
hwndTarget.RenderMode = RenderMode.SoftwareOnly;
}
};
}
}
I've tested this and this solution seems to work very well and so far is the only solution that I've found for solving this problem within a FoxPro interop scenario which is very similar to the WinForms one I posted about originally. For now I'm planning to use my original Refresh on the MDI Parent solution for my WinForms project but then for my other native interop applications such as when my WPF controls are hosted in Visual FoxPro I'll use this solution. That is unless of course if a more elegant solution is discovered for either of the cases.
Also it's important to note that from what I'm aware software rendering is the only option on XP systems and normally Visual FoxPro nore WinForms normally take advantage of the same type of hardware acceleration that native WPF apps do on Vista OS and up. So using this option may not be as bad as it sounds when you do have to deal with interop. Currently I'm not aware of any related side effects when using this solution but if there are any those would have to be taken into serious consideration.
Well, I may have found a solution although it feels like a bit of a hack. It appears that if you call the Refresh method on the MDI parent whenver a child MDI Form is moved that the noted artifacts go away. Visually things appear a bit jittery when dragging a window but it seems much more acceptable than the example I showed in my original post.
private void Form1_Move(object sender, EventArgs e)
{
this.ParentForm.Refresh();
System.Diagnostics.Debug.WriteLine(string.Format("Form Moved to: ({0},{1})", this.Left, this.Top));
}
I've tried many combinations in the same vein such as refreshing just the child window that was being moved by calling methods such as Update(), Invalidate(), Refresh() and also I've tried these same methods on the MDI parent as well as Dispatcher.Invoke(DispatcherPriority.Render, ...) and InvalidateVisual() on my hosted WPF control but none of those other methods worked accept for calling Refresh() specifically on the MDI parent.
I realize that this probably isn't the optimal solution since I'm forcing the whole main application window to refresh every time a child window moves a few pixels but as for right now it's the only reasonable solution that I found that works. If anybody else has any alternative solutions or any improvements upon this I will gladly accept your answer instead.
Check video drivers and try disabling hardware acceleration. Most artifacts are caused by bad drivers, failing video card, or insufficient time to complete the refresh.
First troubleshooting step: Update video drivers. Obvious, I know.
I had similar issue, checking my video card settings (NVidia Control Panel) showed global setting set very high causing a longer refresh interval which may be aborted if taking too long. Setting my settings back to defaults resolved most of the issue. But I also run hashing programs which use the GPU intensely so this is likely the cause of my remaing artifact issue which is very seldom now and mostly shows its ugly face in Visual Studio.
Another troubleshooting step I ran across is to disable hardware acceleration for WPF, this can be done in 'HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avalon.Graphics', or maybe an application can do it BUT this is only for troubleshooting; never set these within an application because it will disable for ALL WPF applications. I do not have this registry setting nor did I add it so I am not sure of the success with it, but many say this resolved their issue. Also note some applications have this option available, try disabling it if available.
Another troubleshooting step is to make sure the video card is a proper tier level for rendering. Any card that supports DX9 or greater should be sufficient, but other factors are involved (as is my case) so just because it is on the list does not mean it is adequate for your purpose.
Finally, you can use the Visual Profiler (part of Windows SDK), and other tools, to help determine what is going on more precisely with WPF lacking performance in relation to graphics ability.
Rendering Tier level notes and WPF Performance information --> http://msdn.microsoft.com/en-us/library/vstudio/ms742196(v=vs.90).aspx
Hope this helps someone.
--Ryan Strassburg
Your usercontrol or window loaded event ;
this.WindowState = System.Windows.WindowState.Minimized;
this.WindowState = System.Windows.WindowState.Normal;
it may seem bad solution. no need to hit your head against the wall.
A Turkish proverb says: the best code is the code is running :)

Recommendations on developing a WPF application without using MVVM or similar

We were building out the next version of an in-house thick-client application using WPF/Prism (Composite Application Library). As we were nearly done with the client our team was put under new management and shortly thereafter:
We were then directed to drop the Prism framework to keep things simple. This includes not using any type of Inversion of Control.
We were directed to build out the WPF application without using MVVM or similar; and more along the lines of a traditional WinForm application. The idea is that if a developer sees a control in Visual Studio’s designer view, then (s)he should be able to click on the control and see exactly what it's doing without having to traverse through a view-model (or similar).
We have now been tasked with building out the WPF application using one primary Window, use a Frame Control to contain the content, and use a Ribbon outside of the frame for the menu items. Reason we were provided to use Frame Control:
a. We will show a view in the Frame with a Page (not a user control) and then load the page in the Frame.
b. When a new view is to be shown in the Frame, the current view (Page) will be closed/disposed and the new view (Page) will take its place in the Frame.
c. When a developer looks at the Page in design view, (s)he will be able to click on any control and see exactly what is being done.
Given the restrictions of 1 and 2 above, we’d like to present another method of building out the application that:
Can be presented as an alternative to using the “Frame Methodology” (item 3 above) but still provides the same type of functionality.
Does not use MVVM (see #1 and #2 above).
Provided the direction we’ve been given, any suggestions as to an alternative we can present? I’d request that the responses be kept on the professional level and thank you in advance.
I'd personally try to argue to use Martin Fowler's Presentation Model. (That's a joke, btw...)
Basically, you're being given a restriction that says "Use WPF, but don't use any of the features that make WPF usable." It really sounds like your requirements are such that you would be much better off explaining, reasonably, the advantages of patterns like MVVM.
It sounds like the weird requirements are really boiling down to this:
The idea is that if a developer sees a control in Visual Studio’s designer view, then (s)he should be able to click on the control and see exactly what it's doing
If that's the main issue, and the reason you're avoiding MVVM and other similar patterns, I would seriously take the time to educate the management. Looking at a Command, by name, instead of an event, by name (which is what you see in the designer) is really no more difficult.
However, in a large scale application, the separation of concerns is key. Even a properly designed Windows Forms application requires a clean separation of concerns - but with event based programming, this becomes much more difficult, especially from the designer. If you try to develop a large scale, clean, application using an event approach, you'll have event handlers, but those event handlers will all eventually need to delegate their work to a separate component.
This is actually adding an extra level of effort, from an understandability and maintenance point of view, on top of what you get with MVVM. With MVVM, you only look to the ViewModel, which is very discoverable.
BTW - The "rationale" for using a Page instead of a UserControl doesn't make any sense. You can do exactly the same thing you're describing with UserControls... The only reason to use a Frame and Page is if you want to take advantage of navigation, in which case, you can't dispose the old pages directly (or they get regenerated constantly). Also, the navigation tools probably wouldn't be used with a ribbon - the two conceptual models are quite different.
There are criticisms of MVVM which may be applicable to your project; however having unreasonable dictates of programming methodology is always a recipe for disaster.
One of the reasons that we have frameworks and spending time building layers and separation is to avoid the coding mess that always results when you can "simply click on the button in visual studio to see the code that is being executed".
There may not be a way of achieving what you've been asked to do without something similar to MVVM, because anything that has an architecture may well be labelled as being too similar.
However I have been using a system for many years that provides simple inter-object plumbing currently called Emesary you may want to read my C# .NET Emesary walkthrough.
But basically it allows my buttons to be implemented thus:
private void addButton_Click(object sender, RoutedEventArgs e)
{
GlobalTransmitter.NotifyAll(new Notification(NotificationType.CreateRecipe));
}
This may be an answer to your problem. It's under hyped, small and so simple but it just works well.
I've achieved a solution to the second question by using a Window, a user control for the ribbon bar (the user control contains the listview), and another user control for the Frame part. This second user control obvious is built using other user controls using a very simple view class. All views and controls are connected using Emesary.
As a school project I had to develop a WPF client which allowed for multiple people to make use of it at the same time. And I used Pages. My verdict: Save yourself a huge amount of effort, and use UserControls instead.
Sometimes the Page Navigator (which you'll use to scroll through) tends to bug out and cause you a lot of problems. Maybe it was my crappy coding, but who knows?
Though I must say, the control being called "Pages" is somewhat misleading... I went "Eureka!" when I found them, and swore at them thereafter.
I totally agree with #2 (MS bigs take note!). It would be cool if you could double-click a Control and it would take you straight to its command (or event if its command is lacking). However till then, make sure that you organize your Views and ViewModels in separate folders.
Having a dual screen (or a very wide one) will allow you to have two instances of VS open on the project, one focused around the View and the other around the ViewModel (my personal choice was having Expression Blend on the View).
Although not a very big application, I managed to convert my project to proper MVVM (ie. ViewModel for every UI element, RelayCommands and Mediator) in a matter of days, so once you understand it it's not too complicated to implement. Plus, there are tools out there (such as Josh Smith's RelayCommand and Marlon Grech's Mediator - totally free, by the way) which make MVVM half as difficult, and twice as powerful.
Using WPF without MVVM is like trying to eat rice without a fork. You'd be better off using WinForms if you're not going to take advantage of what WPF has to offer. My 2 cents.
I wish I could say your management is totally wrong.. but I cannot say that as it will not be the most accurate truth. I guess that the main reason to the changes you described is either because the new manager is not comfortable with the concept of MVVM being the new messiah of UI development or/and another reason could be the cost of educated sophisticated developers vs. cheap developers which can be instructed to get the things done as fast as possible, a concept which is widely known as lean development.
So, putting all I wrote so far under "not what you asked for", here is what I suggest:
you can still use object oriented pure approach, meaning you can have a model object which already have method to show UI information. so every object will be a window derived object, that way you will loose on SOC but you still going to be OOP/OOD.
But LOL, The next phase will bring you to seperation of model from view in order to not repeat the same code in many derrived windows which relay on the same data... so your management will endorse MVC/MVP as good solution .. and the distance from it to MVVM is kinda of short if they want WPF.
Conclusion: you will have to teach your manager why it is better to go for MVVM, unless the project is very short.

Resources