No creation of a WPF window in a DLL project? - wpf

Is there a reason why Visual Studio won't let me create a WPF window in a DLL project?
I "solved" it by creating a window in an Application Project and copying it to my DLL project.
I also found that I could just create a UserControl and change the base class to "Window".
But if I had to do it this way, it's maybe because I shouldn't do it...

Make sure the project type is WPF User Control Library when you create your project.
If it isn't then no sweat, just edit the csproj file and make sure the <ProjectTypeGuids> element under Project/PropertyGroup contain the following GUIDs
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
Also, make sure you reference PresentationFramework and System.Xaml in your project, or you will not get any WPF in your code.

You can try adding new WPF User Control Item and change that to Window.
Add New Item->WPF->User Control
In XAML:
Change <UserControl> tag as <Window>
In CS:
Change base class from System.Windows.Controls.UserControl to System.Windows.Window.

I do it this way:
1) create "WPF Application"
2) remove App.xaml
3) change Project properties -> Application Output type: to Class Library (originally there is Windows Application)
Otherwise you will get errors:
"Library project file cannot specify ApplicationDefinition element"
"The project file contains a property value that is not valid"

What do you mean that Visual Studio won't let you create a WPF window in a DLL project? Do you mean that if you right click the project, there is no option to add a Window there?
If that is the case, I think that means that you created a project type that isn't a WPF project type. I encountered something similar a while back when I wanted to upgrade a WinForms project to use WPF instead - see this question for more information.

Related

How do I add XAML windows to a .Net Core "WPF Application"?

In Visual Studio 2019, if I create a new "WPF Application" using .Net Core (top in the screenshot below) it will create a project for me that does in fact include a working XAML setup. However, there is no way that I can find to add a new XAML window through the VS interface. Right-clicking on a folder, choosing Add and then Window (WPF) just gives you the codebehind, no XAML anywhere.
If instead I create a new "WPF App (.NET Framework)" (bottom in the screenshot) It creates a similar project but I can in fact add XAML windows via right-click and selecting Add as above, including the relevant codebehind.
What gives? If we want to use .Net Core do we have to create the XAML files manually? Am I missing something? XAML is explicitly not listed under the .Net Core option, but the project creation process does indeed create XAML files in the project as expected.
With suggestions above, I was able to get this working in VS2019. To condense the answer:
In the project properties, ensure the "Output Type" is "Windows Application".
Ensure the target framework is ".Net 5.0"
Then directly edit the .csproj file by adding <UseWPF>true</UseWPF> to the first <PropertyGroup>.
Right-click on the project, select: Add > Window
I seem to have answered my own question but it seems useful so I will leave it up here. When you create your .Net Core WPF Application, if you choose .NetCore 3.1 (Long-term support) you get the behavior I describe above (no ability to add XAML windows). If you choose .NET 5.0 (Current) it works as expected and you can add XAML windows.

Best Starting Point for WPF Revit Add in

I am wanting to rewrite one of my Revit Add ins so that it utilizes WPF with MVVM because I like the look and functionality of WPF better than Windows Forms.
I have used the Revit Template Wizzard from Jeremy Tammik for the Form based add in, but adding a WPF user control seems not to work (a run time error that the xaml resource cannot be found).
I found a WPF MVVM revit add in example (AddMaterials, here is the github link, which will add materials from an Excel spreadsheet) but it does not follow what I am expecting to see at the top level.
Revit Add ins have an app.cs file which tells Revit how to register and access the DLL (ribbon panel buttons etc).
A windows WPF app will have app.xaml as the top level entry point.
The Add Materials project has neither which tells me that it must be
a class library, however the views are not using UserControls
rather they are Windows which I prefer. However Visual Studio does not
let you add a Window for a Class Library type project.
The third issue is easily solved by simply copying windows from a WPF application project into a class library project. But I don't really understand how the class library will instantiate in Revit without following the app.cs code from the template. Is anyone else creating add-ins this way, and if so can you let me in on any tricks or discussions that will help? Has anyone created a WPF Revit addin template for Visual Studio?
When I add a WPF window and try to instantiate it I get an error that it cannot find the xaml resource (System.IO.IOException: Cannot locate resource 'xxxx.xaml'). I have tried to fix this according to advice found when googling for this error, but to no avail. I am thinking it comes from being in a form based project, and that I may have to just start with a new project without the form stuff.
I have now verified that indeed you can start with the Revit AddIn Wizzard and use WPF . . . I started from scratch and copied in a window created in another project and got it to run (after adding the various references, namespaces, etc). So my problem seems to just be with the original project which already had a bunch of form stuff added.
Yes, I'm using WPF to create Revit Addins. It works well. You can easily create your own WPF template from the SDK samples:
Start with one of the Autodesk-provided SDK samples. I used the "DockableDialogs" sample. I know this one works, your mileage may vary with the others. If you're looking for windows rather than docked panes in the UI, another sample (perhaps the AddMaterials sample) is probably simpler.
I used Visual Studio to turn the sample into a template. File - Export Template -> select "DockableDialogs" or other WPF sample project.
Create a new project based on the template you just created. This was the easiest method I could find to get the WPF internal bits wired up correctly.
I'm not specifically familiar with the AddMaterials project, but to clarify your bullet points.
Revit Addins - It's not the file name (app.cs) but rather they must extend IExternalApplication or IExternalCommand. If you are creating a xaml interface (rather than just running a command from a ribbon button) you'll use 'IExternalApplication' as your entry point. Look for something like this in the sample:
public class ThisApplication : IExternalApplication ...
I don't used a top level app.xaml, but instead have page.xaml pages which are called by the Revit app. In my case these are Pages rather than Windows, which extend the IDockablePaneProvider class. These must be registered with the application which can then can be show, hide, etc your Panes. I imagine this is simpler with Windows, but haven't done it myself. For the dockable panes, your xaml.cs should start out something like:
public partial class MainPage : Page, Autodesk.Revit.UI.IDockablePaneProvider ...
Yes, the project is a class library in the sense that it is a collection of classes, at least one of which extends IExternalApplication or IExternalCommand. Remember that you're not creating a standalone application, but adding functionality to an existing Windows application (Revit). Revit will instantiate the ThisApplication class and then call its .OnStartup() method when the Revit application starts. This shouldn't stop you from adding .xaml or .cs files to the project, though. I can do it using VS Community 2015 using Ctrl-Shift-A.
Hopefully this gets you started - I've been able to implement a WPF UI in Revit without any prior WPF experience, and I'm not even a real programmer, so it's definitely possible. Good Luck!
addendum
If you want to add WPF elements to an existing revit addin, you can follow the instructions here: How can I connect xaml and xaml.cs files
Ultimately I found it easier to migrate my addin code into a template made from a working sample, you may want to try this approach as well.

Adding a WPF form to a library in visual studio express

I managed to create a WPF project, but for some reason, when instead I am in a library project and I try 'Add Item', then go to WPF, there is only one thing I can add, which is a user control.
I am not clear what a user control is, but clearly it has no 'Show' method.
If instead I tried copying the mainwindow from my WPF project to the library project, but then it would not compile (and I added missing references).
Am I doing something wrong, or is Visual Studio Express for Desktop just not featuring a WPF form?
EDIT: it seems I am after a WPF window instead (as per the Mainwindow : window class that gets generated when creating a new WPF app), not a form.

User controls are not available in the toolbox in VS2010

I have created the WPF user control and WPF window in class library project. Controls are public.
These controls are available for other project of the same solution. I can see them in the toolbox of the VS2010 when i add project reference from the WPF application project.
However, when i create some WPF application project outside the solution and add reference to the my user control library project, the controls do not appear in the toolbox! (My applications XAML file is open when I try to see them in toolbox to drag-drop on the application's main XAML)
What makes the controls avilable to the outside world when their assembly is referenced by the consumers?
Try right clicking on the toolbox and selecting Choose Items From that form click browse and select your DLL. That should put the controls in the toolbox for you.
I think the problem is that in your new WPF project you need to set an XML namespace where you reference your user control library. Then you can use your controls in the XAML.
For example :
thats an xml namespace definition in the XAML:
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;
assembly=Microsoft.Phone.Controls.Toolkit"
And how you can use a control from this control library
< toolkit:ListPicker />
I hope this will help you.
Right click inside the toolbox and select "Show All".

How can I make Visual Studio 2010's "Add User Control" create a WPF control?

I have a class library that I created using the "Class Library" project template. If I right-click on this library in Solution Explorer and select "Add > User Control", Visual Studio adds a WinForms UserControl. That's not what I want -- I want "Add > User Control" to add a WPF user control.
I've already added references to the WPF assemblies (WindowsBase, PresentationFramework, and PresentationCore), and I already have some WPF UserControls in this library, and everything compiles. My library does not have references to the WinForms assemblies (System.Drawing and System.Windows.Forms). But apparently the proper references are not enough of a clue for Visual Studio, because when I try Add > User Control, it adds the WinForms references to my project, and then creates a WinForms UserControl.
I can add a WPF User Control to my WPF Application project, and then move it into my library. But that's a pain, and I'd rather have it work properly in the first place.
I think I'm probably missing some kind of arcane XML element in my .csproj file that tells Visual Studio which designer to use by default, and if I add the right XML element with the right cryptic GUID, it will start working properly. If I could create a new WPF Control Library, I could probably compare the two project files and figure this out. However, I'm using Visual C# Express, which doesn't have a template for a WPF Control Library project, so I'm out of luck there.
What do I need to do to my Class Library's .csproj file so that VS2010's Add > New User Control will add a WPF UserControl?
There are sub-projects class ids in the project file that affect the Visual Studio context menus and how the project behaves in general. The easiest thing to do is to recreate the project as a:
WPF User Control Library
instead of a "Class Library". It is possible if you already created the project to edit in the sub-project class ids by hand by opening the ".csproj" file in a text editor such as Visual Studio itself but its easy to cause more damage than you fix that way.
I believe but haven't test that another type of library will also work:
WPF Custom Control Library
which is intended to hold other types of controls than UserControl objects but being a WPF sub-project type the context menus also work correctly for the use case you are describing.
Edit:
For completeness, I've just tested how to manually add the sub-project GUIDS. Add this line to the first PropertyGroup in the .csproj file:
<PropertyGroup>
...
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
Not tested with Visual Studio Express.

Resources