When we create a WPF project in Visual Studio (2010), it automatically creates a MainWindow.xaml, whose code-behind contains a MainWindow class with an InitializeComponent() in it. I know superficially that, somewhere in the project files, there is an actual main() function equivalent for the presentation, so that when the application GUI is loaded the GUI events are handled "downwards" the application layers - as soon as they exist.
I plan to develop something in the lines of Model-View-Presenter application, and I am already mocking very rudimentar domain-logic and application façade.
My doubt is: when I have my domain logic, how should I connect the Presenter with the Application Façade, or more pragmatically, WHERE and how (in the project files) I should start to "flesh out" the application from a blank WPF Application created in Visual Studio. I have made something like Add Existing Project, but than staled.
(EDIT: From a design patterns book: "An application facade is opened with a particular object in the domain model as the subject. This subject acts as the starting point for all the manipulations that are done by the facade." That seems a good start for the initiated...)
Is there any common, obvious or best-practice way of doing it?
(also, if someone could suggest / edit a better title for this question, I'd appreciate that)
Thanks for any help!
This guide from Microsoft (though a bit old) explains the layers and parts of a Rich Gui application rather well: http://msdn.microsoft.com/en-us/library/ee658087.aspx
How you're actually structuring your projects and files is really up to you. You can build a stand-alone application in one project. You won't be able to re-use that code very easily, but your WPF application won't notice.
You can group your classes in multiple ways. By Namespace, by assembly (project), nested class etc... When to use which is usually up to re-use or distribution over different machines.
When you build a UI part and a webservice part, you'll probably stick each in a different project.
When you want to re-use your business classes in a website and a windows app and a phone app, you'll probably want to stick them each in a different project.
Separating into projects prevents you from creating circular dependencies between classes.
Usually you'll get a chain of projects from the UI referencing the Business Layer referencing the Data layer etc. And you'll often see a couple of cross cutting concerns (logging and security for example) that are references from each of these 'layers'.
In the end, a layer can map to a Project (assembly) or a Namespace (within a project). Which one you choose is up to you.
In a WPF project the application entry point is specified by the App.Xaml. You'll find a reference to the main Form to load in there.
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"> <-- Start up here -->
<Application.Resources>
</Application.Resources>
</Application>
The actual entry point is defined in your project settings:
You can start any initialization code in the App.xaml.cs. The simplest way is by subscribing to the OnStart event or the OnLoadCompleted event. You can also start your logic in the MainWindow.xaml.cs code. Place the actual logic in a separate class and reference that from your OnStart or OnLoadCompleted events.
And add your own code there
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
}
}
A better, more object oriented and unit testable way is to use Prism or MVVM Light. The scope of these frameworks is so large that they warrant their own topic.
I'm not sure why you would want a mainloop. Unless you plan to do some kind of game or 3d rendering. In the other cases you can suffice by adding commands to the visible objects and let Windows handle the primary input registration and dispatching of events. For long-running tasks you can use threading to have that done in the background (different topic again).
Related
In WPF applications all the views are inherited from System.Windows.Window and have an associated xaml and codebehind file. That seems logical.
However I'm confused that why does the App file, inherited from System.Windows.Application, have a xaml file? Although it is an application and not a view (It is not visible)? I know that this file is usually used to define application resources, etc, and xaml provides an efficient way of defining them. But that can also be done programatically. Then what benefit did the designers of wpf achieve by having both the xaml and code behind files for "App"? Wouldn't one of them have been enough?
However I'm confused that why does the App file, inherited from System.Windows.Application, have a xaml file? Although it is an application and not a view (It is not visible)?
Remember that XAML is not a UI language, but a general declarative language. While it's true that it's mostly used to represent UI for WPF or SilverLigth, it's also used to declare graph of objects in other non-UI technology.
The first example that comes into my mind is the Workflow (the XOML is a derivate of the XAML), SharePoint also use XAML in some hidden parts, and I've seen in a customer project with use XAML as a meta-language for generating web-apps (and yes, it actually outputs HTML).
Then, to answer to your question, the application have both files (and it is not actually a requirement) because you can :
declare some objects (in the xaml)
override the behavior of the application (by overriding appropriate methods)
Designers can specify resources for entire application without entering any code and use it in any Window. Its something like a root for all windows. For example, if you use one style for every TextBox (or any other control) in every window, you can specify it in App.xaml and bind anywhere without duplicating.
I've done .Net development for awhile but I'm new to the WPF technology. What is the supposed purpose of App.xaml? Also, what type of xaml code do you usually put in it? It seems like for simple applications it could be ignored and left untouched. Is this true?
App.xaml is the declarative portion of your code (usually generated by Visual Studio) extending System.Windows.Application. For example, Expression Blend can use App.xaml to share a Resource Dictionary or a design-time data set with your entire application. And, because we are using Microsoft products, whatever Expression Blend can do auto-magically, we can do by hand in Visual Studio.
Now the tangent: To me, to ask about the purpose of App.xaml is to ask about the purpose for System.Windows.Application. Feel free to accuse me of changing the original question (let the digital brutality ensue).
You can’t just open a System.Windows.Controls.Window in any Assembly you like… Chris Sells is likely telling me this in his book. I began to understand the purpose of System.Windows.Application while using MEF and MVVM Light to display WPF windows in DLLs (not EXEs). I got errors like this:
The type 'System.Windows.Markup.IComponentConnector' is defined in an assembly that is not referenced.
or
The type 'System.Windows.Markup.IQueryAmbient' is defined in an assembly that is not referenced.
The above error is simply saying that I’m trying to open a WPF Window inside of a DLL and not an EXE. Then, there’s this error:
The component 'Songhay.Wpf.WordWalkingStick.Views.ClientView' does not have a resource identified by the URI '/Songhay.Wpf.WordWalkingStick;component/views/clientview.xaml'.
This boils down to the absence of a facility that associates WPF Window XAML with the WPF “code” (an instance). This facility is associated with WPF EXEs and not WPF DLLs. Visual Studio auto-generates a WPF EXE class called App.g.cs (in your \obj\Debug folder) with this call in it: System.Windows.Application.LoadComponent(this, resourceLocater) where resourceLocater is a badly named variable containing a System.Uri pointing to the XAML like ClientView.xaml mentioned above.
I’m sure Chris Sells has a whole chapter written on how WPF depends on System.Windows.Application for its very life. It is my loss (quite literally of time) for not having read about it.
I have shown myself a little something with this unit test:
[STAThread]
[TestMethod]
public void ShouldOpenWindow()
{
Application app = new Application();
app.Run(new Window());
}
Failing to wrap a new Window in the System.Windows.Application.Run() method will throw an error from the land of COM talking about, “Why did you pull the rug from underneath me?”
For simple applications, it is true, it can be ignored. The major purpose for App.xaml is for holding resources (style, pens, brushes, etc.) that would would like to be available through out all of the windows in your application.
It is true. App.Xaml is some sort of central starting point. You CAN use it, or you CAN start your first window (it is defined in the app.xaml) manually. There are some lifetime events there centralls (like application start).
Storing resources that are used across the whole application.
Application is the root of the logical tree.
It is like Global.asax if you are coming from an ASP.NET background. You can also use it to share resources throughout your application. Comes in pretty handy for resource sharing.
App.xaml is a major part of wpf application.
It contains major four attributes
1.X:Class->used to connect you xaml and code-behind file(xaml.cs).
2.xmlns->To resolve wpf elements like canvas,stack panel(default one).
3.xmlns:x->To resolve XAML language definition.
4. StartupUri->To give start window when application is launching.
++++++++
App.xaml is the declarative starting point of your application. Visual
Studio will automatically create it for you when you start a new WPF
application, including a Code-behind file called App.xaml.cs. They
work much like for a Window, where the two files are partial classes,
working together to allow you to work in both markup (XAML) and
Code-behind.
App.xaml.cs extends the Application class, which is a central class in
a WPF Windows application. .NET will go to this class for starting
instructions and then start the desired Window or Page from there.
This is also the place to subscribe to important application events,
like application start, unhandled exceptions and so on.
One of the most commonly used features of the App.xaml file is to
define global resources that may be used and accessed from all over an
application, for instance global styles.
+++++++++
Source : http://www.wpf-tutorial.com/wpf-application/working-with-app-xaml/
Here is an updated answer in case people are still looking.
There is this excellent article on WPF, and the link specifically puts you at the App.Xaml point to begin teaching you the things you can do with it.
WPF is easy for the first very simple app or two. However, due to the increased flexibility of the framework, you need these types of tutorials to help you understand what can be done from where (in the various application files).
https://www.wpf-tutorial.com/wpf-application/working-with-app-xaml/
Good luck.
I am building an application in the MVVM style where the actual views (UserControls) are stored remotely and hopefully sent via a WCF service to my main application window. I am doing this in order to avoid having the user reinstall the application each time a new view is added. However, when I try to return a User Control from my WCF service I get an error stating:
System.Runtime.Serialization.InvalidDataContractException: Type 'System.Windows.Input.TouchDevice' cannot be serialized.
I am wondering if there is any way around this or if people have implemented something similar in other ways?
Thanks,
Ochowie
When you're loading from an assembly you're instantiating the compiled object from an assembly, which is a lot different than a deserialization operation, which is what is happening with a service call. The best you can do with serialization is transfer raw XAML that can be loaded with XamlReader, but this limits what you can do with a control since you can't use any code. If you're really set on hosting controls on your server the most flexible option would be to have your app download an assembly containing the new control and dynamically load the new assembly or use a separate launcher that can download new control assemblies before starting up the main application (make sure you take the time to understand the security implications and secure the assemblies and downloads).
What you're trying to do doesn't really make sense... controls are not DTOs, they're strongly dependent on their runtime environment. In WPF, there is also the issue of the dispatcher : even if you could transfer a control, how would you reattach it to your application dispatcher ? Anyway WPF controls are not serializable with the DataContractSerializer, and there is no way to change that.
However, what you could do is transfer a representation of the views in XAML. This is of course assuming your views are XAML only, without any code-behind. You could then load the views using XamlReader and render them in your UI. I'm not sure of the feasibility, but I think it's your best option.
You could also implement your views in a separate assembly, so that the users don't need to reinstall the whole application. They will only need to upgrade the modified assemblies.
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.
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.