3
votes

When coding WinForms applications, I always start with an empty project, then add an Application Class, Forms, etc... In doing so, I can build up the application from scratch, keeping it clean, without all the "fluff" of the Standard WinForms projects, which add Forms, etc... for you.

I want to do the same with WPF. I've created my application class, made a Window class and I can run the application just fine, but there is no XAML associated with the window because I'm just declaring it as a derived class from Window.

My question is, can WPF -Windows be added to a project like WinForms -Forms such that the XAML is also added and the designer can be used to layout the controls etc...? Or do I have to use the canned "WPF Project" and go from there?

Apparently it's not possible to create an Empty Project and add XAML backed Windows. If anyone knows why, I would appreciate an explanation. (You can, however, create programmatically generated windows, or if you want your own startup object in a default WPF Project, simple delete the App.xaml and add your own class with a static Main().)

class OrderEntry : System.Windows.Application
    {
        [STAThread]
        static void Main(string[] commandLine)
        {
            OrderEntry app = new OrderEntry();
            app.MainWindow = new WindowMain();
            app.MainWindow.Show();
            app.Run();
        }
    }

public partial class WindowMain : System.Windows.Window
{

}

Works fine, but WindowMain has no XAML associated with it.

3
If you need to create a WPF application. Use File -> New Project -> WPF Application. The default WPF project is clean. Don't try to reinvent the wheel. It's already been invented by Microsoft and they know much better than any of us. - Federico Berasategui
@user2942249 I have no idea what you mean by "magic". There is only 1 ApplicationDefinition, and a default Window, which can be removed. There is no "magic" at all. - Federico Berasategui
@user2942249 there is no such thing. Application.Run() is defined in PresentationFramework.dll. - Federico Berasategui
@user2942249 Wrong. The Main() method is generated in App.g.i.cs which is autogenerated by the Build Action of the App.xaml file. Why do you care about any of that? If you don't want that, remove the App.xaml file altogether, and define the Main() method yourself. - Federico Berasategui
@user2942249 Yes. I still fail to see the need for this. You're losing your time. - Federico Berasategui

3 Answers

2
votes

To answer your question, yes - XAML based windows can be added to the project as and when you want.

The trick is to ensure your project type is correct, because this governs the list of template items that you will see when you go Add->New...

If you find the right project in your Solution Explorer, right click and select Unload Project, then right click it again and select to Edit, you will then get the proj file in XML format. In it you will see a line similar to the following:

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

Those GUIDs dictate what project or file templates you will see in the add list. You can find more details in the previous SO question Visual Studio project type guids and the blog post linked in one of the answers INFO: List of known project type Guids

2
votes

This is what I have tried, it worked for me

  1. Create an empty project from Visual Studio 2013 Templates enter image description here
  2. Add reference for below dll's which are present at Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\ enter image description here
  3. Modify the .csproj file located at project root folder through a text editor. Add below entry for <ProjectTypeGuids> in <PropertyGroup> node.

    {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}

Read more about Project Type Guids here

  1. Change the <OutputType>WinExe</OutputType>

    <PropertyGroup>
    <ProjectGuid>{C60226AB-DDB6-49C2-8B0D-F59E6B590236}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    

  2. Add a App.Xaml file to your application and replace its content like this

Note here WpfApplication1 is the default namespace and we haven't created MainWindow.xaml yet

  1. Modify the code behind and inherit it from Application enter image description here
  2. Modify the .csproj to add <ApplicationDefinition> under <ItemGroup>

eg:

  <ItemGroup>
     <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>
    <Page Include="MainWindow.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="App.xaml.cs">
      <DependentUpon>App.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="MainWindow.xaml.cs">
      <DependentUpon>MainWindow.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>

Note MainWindow is a file which I have added later.

Now we can create XAML backed windows

1
votes

As HighCore said in comments that using given WPF FCL/Template are best I also agree with that . But if you still wants your own xaml Then do this

1) Add Xml file to your View Project and keep its extension .xaml say WindowMain.xaml

2) Remove the below line from it

<?xml version="1.0" encoding="utf-8" ?> 

3)Copy and Paste

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

</Window>

4) add x:class attribute to Window element like and set another attribute like Title height width etc

 <Window x:Class="Namespace.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MyWindow" Height="350" Width="525">

</Window>

5) Close the project and edit project file like

<Page Include="MainWindow.xaml">
  <Generator>MSBuild:Compile</Generator>
  <SubType>Designer</SubType>
</Page>

<Compile Include="MyWindow.xaml.cs">
  <DependentUpon>MyWindow.xaml</DependentUpon>
  <SubType>Code</SubType>

//or MainWindow.cs MainWindow.xaml Code

6) Save and close

7)Open your project you will find your .cs file under .xaml file as we mentioned it in DependentUpon

8) Add Constructor to your partial class and call InitializeComponent() method

public MainWindow()
    {
        InitializeComponent();
    }

This worked for me . But this is all we doing what Wpf exactly provide by itself by using their WPF Window . And I have assumed that your App class builded and worked correctly but I doubt it you calling window Show before App Run. I hope this will help.