Previously all application level resources in a project I am authoring were stored in App.xaml. Then I decided to migrate from VS 2008 to 2010 and that is where the trouble started.
After migrating, I tried to do a little testing using a testing window instead of the normal startup window. After changing the startup object, suddenly I was faced with lots of compile errors and what not which (long story short) resulted in finding that there was now two files which held application level resources associated with the project: App.xaml (the original), and Application.xaml (at this time veritably empty). I migrated all of the resources (as well as merged dictionaries) over to the Application.xaml, and all was again right with the world so far as Visual Studio was concerned.
I then found out that Blend still wanted to use the App.xaml. I had created several resources and placed them in the Application.xaml, and saw that they were not being used when I compiled with Blend (but they were being used when I compiled with VS).
Where does one specify which XAML is the top level WPF resource file? This is getting out of hand...
There are slight differences in naming depending on what programming language you choose.
Visual Basic WPF projects use Application.xaml, while C# projects name it App.xaml.
As you probably know all .NET apps need a Main method. Also, windows apps need a message pump to get hooked to the Windows messaging system. IN WPF you can use the Application class to start listening to the windows messages.
Here's how you can do it explicitly.
VB
Public Class Startup
<STAThread()>
Shared Sub Main()
Dim app As New Application()
Dim window As New MainWindow()
window.Show()
app.Run()
End Sub
End Class
C#
public class Startup
{
[STAThread()]
public static void Main()
{
Application app = new Application();
MainWindow window = new MainWindow();
window.Show();
app.Run();
}
}
Since creating this type of code is common for WPF applications you can tell MSBuild to write this code by defining a XAML file and class that derives from System.Windows.Application and specifing its build action as 'ApplicationDefinition'.
In your situation, instead of editing the VbProj file, you could just select the correct file in Solution Explorer and change the BuildAction.
Related
At the risk of beating a dead horse, I would like to be clear on the initial setup for using Elmish.WPF.
My intent is to have essentially two projects:
FrontOfficeV -- a C# project to hold the XAML's, Windows, etc..
Models -- a F# project for Elmish.WFP, F# code, etc..
After trying most all of the project type options (Visual Studio 2019), I settled on: Console App (.NET Framework) C# for the C# Project.
This created the C# project that defaulted to: Target framework: .NET Framework 4.7.2 Output type: Console Application. This also created a "program.cs" file.
Next, using ADD -->New Item with the C# Console App did not show a "Window" option. It did show the "User Control (WPF)" option. So the "User Control (WPF) was added and renamed to "MainWindow". I then changed the element tag in the xaml from UserControl to Window and changed the code behind to inherit from Window instead of UserControl. Lastly, I changed the project properties to compile output type to: Windows Application. This C# project was now marked as the "StartUp" project for visual studio.
Next, the F# Models project was created using: Library (.NET Framework) F# Windows library. This created a project which defaulted to: Target framework: .NET Framework 4.7.2 Output type: Class Library. To the F# class library, a program -- FrontOffice.fs, was added with:
/// This is the application's entry point. It hands things off to Elmish.WPF
let entryPoint (mainWindow: Window) =
Program.mkSimpleWpf init update bindings
|> Program.runWindowWithConfig
{ ElmConfig.Default with LogTrace = true; Measure = true; MeasureLimitMs = 1 }
mainWindow
Lastly, the program.cs was changed to read:
public class Program
{
[STAThread]
public static void Main(string[] args)
{
Application app = new Application();
Window mainWindow = new MainWindow();
Models.FrontOffice.entryPoint(mainWindow);
}
}
The point here being the usage of: Program.mkSimpleWpf.
Why all the hassle? I would like to use the full WPF/C#/XAML goodies (like Themes, custom controls, etc), and I am not so sure the direct compilation of XAML in F# can do this. I'd like to be able to use the F# data types in the XAML, so the C# project requires a reference to the F# Modules, so it seems easier to create the windows in C# and pass a reference unto the F# Modules entryPoint, as above.
Questions:
Is the setup above correct for Elmish.WPF?
Is there a better setup to accomplish my goals?
As of Visual Studio 2019, does F# compilation of the xaml work for themes, custom controls, etc? What hiccups can I expect?
Thank you for any clarification on these points. TIA
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.
I'm improving an existent WPF project with a TCP/IP protocol that sends and receive small objects. I'm using Visual Studio 10 but I'm stuck.
I'm using BinaryFormatter to serialize the objects and until I used to send and receive with two classes in the same project I had no problem, but when I separated listener and sender (TCPListener and TCPCLient) on runtime i had this error:
"Can't find Assembly 'ProjectName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'".
Googling I found out that the problem could be solved creating an external dll called from main program, but I don't know how to pass the MainWindow to the dll because the library not even can find WPF types (such as MainWindow, Combobox or Textbox)
Can you help me with this dll problem or do you have any ideas to solve the assembly reference problem?
First of all, you shouldn't pass the MainWindow to a class you intend to serialize. This data class should actually not have any dependencies on the GUI. In fact, if you want to serialize a class, its public interface should in my opinion only contain primitive types or classes defined in the same assembly.
However, for a quick fix, and if you don't want to rewrite your project completely, I found that the easiest way to get the dependencies for a WPF library right was to start a new WPF application project and then change its project type to WPF Class library in the application tab of the project properties.
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.
First I just want to say I am new to WPF, so please excuse my ignorance...
I am creating a .Net plug-in for Rhino 4.0. With the plugin I am developing a UI using WPF.
The Rhino 4.0 CAD engine is an MFC/Win32 application. The plugin will execute after the application is run, and it creates the WPF Window and then "sucks" the MFC Window into it.
So my question is, does WPF look for an App.xaml file to get to Application level resources if the hosting application isn't a WPF app?
If not, what is the best way to store application level resources?
Thanks,
Jason
App.xaml is used as a part of a partial class App : Application.
If your application does not have a WPF based Application class,
you can manually load dictionaries and merge with the application and create a main window and show it (access via static methods of Application class).
Code goes kind of like this.
var reader = new XamlReader();
var dictionary = reader.read("path to xaml file") as ResourceDictionary;
if (dictionary != null)
Application.MergedDictionaries.Merge(dictionary);
var mainWindow = new MyMainWindow();
mainWindow.Show();
WPF projects will - by default - generate an entry point for your application. This entry point constructs and initializes your Application-derived class for you. If you need, you can always create your instance manually, and store application-level resources in it:
App app = new App();
app.InitializeComponent();
app.Run();
Have you tried storing your resources at what MSDN refers to as the 'theme level'?
Within a folder called "<root>\Themes" have a file called generic.xaml.
I haven't tried this for a project that wasn't a WPF application, but the approach might work for you.
my guess is it has to do with how does rhino run your plugin does it run it as a seperate process or does it just call some thing you have defined?
If it does call a function you defined then you could just put the code there that will start the window?