A question of a beginner in c#
from net
using System;
namespace mcMath
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class Class1
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
}
}
When I make project, I am getting
using System;
namespace mcmath
{
public class Class1
{
}
}
How can add by default comments, and default constructor. I mean
/// <summary>
/// Summary description for Class1.
/// </summary>
public Class1()
{
//
// TODO: Add constructor logic here
//
}
What I have to do. I am using VS 2008. Regards,
Under the folder C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Windows\1033 are all the templates for C# windows projects. You'd have to unzip those, add the comments there, then re-zip them.
Then when you create a new project, the comments will be there.
Likewise, individual items can be found at C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\.
If you don't want to change those versions, you can copy them to C:\Users\<UserName>\Documents\Visual Studio 2010\Templates. Just be sure to update the vstemplate file with new names and GUIDs.
Just click above the class decleration, and start typing 3 slashes: ///
They Visual studio IntelliSense will create the documentation template for you.
Related
Background: We have a custom tool which takes the xml input and generates the cs output. A custom tool needs to register with the Visual studio in order to make it work with that version of visual studio.
What we have done: We have done the custom tool registration with the Visual Studio 2015 which is working fine. But now the problem is with Visual Studio 2017.
Problem: So far in my research, I found until Visual Studio 2015, VS had the direct registry entries which were allowing to register the tool but from VS 2017, Microsoft has made changes in the way how registry entries are stored (a good read to understand changes in VS2017).
If I open up the VS 2017 and try to run the custom tool then I get the error
Cannot find custom tool "Tool Name" on this system.
This is obvious because custom tool is not yet registered with VS 2017 to work.
I tried to follow this guy which says to load .bin file in to the registries but he also says that it disables to launch the VS 2017. In order to launch VS, we have to unload hive. Research says, .bin file can be on different location based on type of VS installed (enterprise, pro etc.).
Has anyone done this before?
TIA
You may have to follow different approach here by creating a Visual Studio extension (VSIX), below I have explained it in detail, hope it helps.
How to create a Custom Tool or Single File Generator in Visual Studio 2017:
Prior to VS2017 creating a custom tool required implementing Interface IVsSingleFileGenerator and code to register and unregister the custom tool in the system registry, but in VS2017, Microsoft has changed entire registry structure. The change is, VS will make registry entries to a private registry so that system registry is not messed up. While previously the registry entries were made in the system registry, now they are made to
C:\Users\xyz\AppData\Local\Microsoft\VisualStudio\15.0_xx\privateregistry.bin
Visual studio 2017 also supports testing your tool directly by running it from the visual studio itself (F5), which starts another instance of Visual Studio called Visual Studio Experimental Instance and your tool can be tested in it since it makes registry entries to
C:\Users\xyz\AppData\Local\Microsoft\VisualStudio\15.0_xxExp\privateregistry.bin
Follow below steps to create a Custom Tool in VS2017:
We need to create a VSIX extension
Add new Visual Studio Package
Implement IVsSingleFileGenerator
Add the registry entry code
Compile and test the tool by running it in VS2017
Install the tool by double clicking the generated .VSIX file
We will create an extension/custom tool as an example named "CountLines" which will read a file (having Custom Tool property set to CountLines) and generate an XML file containing the number of lines in the file. e.g. <LineCount>1050</LineCount>
1. Create a VSIX extension
In order to create an extension you must have installed Visual Studio Extensibility Tools which is included as an optional feature in Visual Studio setup. If it is not installed you can also install it by modifying VS 2017 setup.
Create new VSIX (Visual Studio Extension) project by selecting
New Project -> Extensibility -> VSIX Project
give it some name like "CountLinesVSIX".
2. Add new Visual Studio Package
Once VSIX project is created, add new Visual Studio Package to it by selecting
Add -> New Item -> Extensibility -> Visual Studio Package
give it name "CountLines.cs". In CountLines.cs we need to delete existing code and replace it with our code for IVsSingleFileGenerator implementation
3. Implement IVsSingleFileGenerator
Write your custom implementation for interface IVsSingleFileGenerator, our example code is as below
using System;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using System.Text;
namespace CountLinesVSIX
{
[PackageRegistration(UseManagedResourcesOnly = true)]
[InstalledProductRegistration( "CountLines", "Generate XML with line count", "1.0")]
[Guid("202E7E8B-557E-46CB-8A1D-3024AD68F44A")]
[ComVisible(true)]
[ProvideObject(typeof(CountLines))]
[CodeGeneratorRegistration(typeof(CountLines), "CountLines", "{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}", GeneratesDesignTimeSource = true)]
public sealed class CountLines : IVsSingleFileGenerator
{
#region IVsSingleFileGenerator Members
public int DefaultExtension(out string pbstrDefaultExtension)
{
pbstrDefaultExtension = ".xml";
return pbstrDefaultExtension.Length;
}
public int Generate(string wszInputFilePath, string bstrInputFileContents,
string wszDefaultNamespace, IntPtr[] rgbOutputFileContents,
out uint pcbOutput, IVsGeneratorProgress pGenerateProgress)
{
try
{
int lineCount = bstrInputFileContents.Split('\n').Length;
byte[] bytes = Encoding.UTF8.GetBytes("<LineCount>" + lineCount.ToString() + "</LineCount>" );
int length = bytes.Length;
rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(length);
Marshal.Copy(bytes, 0, rgbOutputFileContents[0], length);
pcbOutput = (uint)length;
}
catch (Exception ex)
{
pcbOutput = 0;
}
return VSConstants.S_OK;
}
#endregion
}
}
We need to provide an unique GUID for our extension such as one in above code [Guid("202E7E8B-557E-46CB-8A1D-3024AD68F44A")]. GUID can be created from VS2017 by selecting "Tools -> Create GUID". Select GUID format as Registry format. Note that GUID mentioned above code is without curly braces.
[ComVisible(true)] is required for COM Interops
[CodeGeneratorRegistration(typeof(CountLines), "CountLines", "{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}", GeneratesDesignTimeSource = true)] is a class attribute with code to register the tool. Params being GeneratorType, GeneratorName, and C# language GUID
You can also derive from "TemplatedCodeGenerator" which supports custom TextTemplate formatting, which may require some additional code implementation.
4. Add the registry entry code
Create new class file with below code, name it CodeGeneratorRegistrationAttribute.cs
using System;
using System.Globalization;
using Microsoft.VisualStudio.Shell;
namespace CountLinesVSIX
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class CodeGeneratorRegistrationAttribute : RegistrationAttribute
{
private string _contextGuid;
private Type _generatorType;
private Guid _generatorGuid;
private string _generatorName;
private string _generatorRegKeyName;
private bool _generatesDesignTimeSource = false;
private bool _generatesSharedDesignTimeSource = false;
public CodeGeneratorRegistrationAttribute(Type generatorType, string generatorName, string contextGuid)
{
if (generatorType == null)
throw new ArgumentNullException("generatorType");
if (generatorName == null)
throw new ArgumentNullException("generatorName");
if (contextGuid == null)
throw new ArgumentNullException("contextGuid");
_contextGuid = contextGuid;
_generatorType = generatorType;
_generatorName = generatorName;
_generatorRegKeyName = generatorType.Name;
_generatorGuid = generatorType.GUID;
}
/// <summary>
/// Get the generator Type
/// </summary>
public Type GeneratorType
{
get { return _generatorType; }
}
/// <summary>
/// Get the Guid representing the project type
/// </summary>
public string ContextGuid
{
get { return _contextGuid; }
}
/// <summary>
/// Get the Guid representing the generator type
/// </summary>
public Guid GeneratorGuid
{
get { return _generatorGuid; }
}
/// <summary>
/// Get or Set the GeneratesDesignTimeSource value
/// </summary>
public bool GeneratesDesignTimeSource
{
get { return _generatesDesignTimeSource; }
set { _generatesDesignTimeSource = value; }
}
/// <summary>
/// Get or Set the GeneratesSharedDesignTimeSource value
/// </summary>
public bool GeneratesSharedDesignTimeSource
{
get { return _generatesSharedDesignTimeSource; }
set { _generatesSharedDesignTimeSource = value; }
}
/// <summary>
/// Gets the Generator name
/// </summary>
public string GeneratorName
{
get { return _generatorName; }
}
/// <summary>
/// Gets the Generator reg key name under
/// </summary>
public string GeneratorRegKeyName
{
get { return _generatorRegKeyName; }
set { _generatorRegKeyName = value; }
}
/// <summary>
/// Property that gets the generator base key name
/// </summary>
private string GeneratorRegKey
{
get { return string.Format(CultureInfo.InvariantCulture, #"Generators\{0}\{1}", ContextGuid, GeneratorRegKeyName); }
}
/// <summary>
/// Called to register this attribute with the given context. The context
/// contains the location where the registration inforomation should be placed.
/// It also contains other information such as the type being registered and path information.
/// </summary>
public override void Register(RegistrationContext context)
{
using (Key childKey = context.CreateKey(GeneratorRegKey))
{
childKey.SetValue(string.Empty, GeneratorName);
childKey.SetValue("CLSID", GeneratorGuid.ToString("B"));
if (GeneratesDesignTimeSource)
childKey.SetValue("GeneratesDesignTimeSource", 1);
if (GeneratesSharedDesignTimeSource)
childKey.SetValue("GeneratesSharedDesignTimeSource", 1);
}
}
/// <summary>
/// Unregister this file extension.
/// </summary>
/// <param name="context"></param>
public override void Unregister(RegistrationContext context)
{
context.RemoveKey(GeneratorRegKey);
}
}
}
Above code will make sure your entries are made to VS private registry
5. Compile and test the tool by running it in VS2017
You may add "Install targets" in "source.extension.vsixmanifest" to ensure different VS2017 editions are supported by your extesion.
Run your tool in VS 2017 to test if it is working as expected. Once you Run the VSIX, the Visual Studio Experimental Instance will install the extension and register it in registry "C:\Users\xyz\AppData\Local\Microsoft\VisualStudio\15.0_xxExp\privateregistry.bin". You can see the installed extension by selecting "Tools -> Extensions and updates". To test the tool we will have to open a dummy project, select a file in solution explorer, go to its properties and update Custom Tool property to "CountLines". Once this is done VS will run the tool in background and generate the output, in our example it will generate a xml file under the selected file. Alternatively, once Custom Tool property is set, your can right click the file and select "Run Custom Tool"
6. Install the tool by double clicking the generated .VSIX file
Once tested successfully, try installing the VSIX which can be found at location "projectName/bin/debug". Install the VSIX by double clicking the file, follow the installation steps. Now your tool will be available for use in VS2017. Using tool is similar, right click the file on which you want to run the custom tool and select "Run Custom Tool"
In case you want to uninstall the extention, go to "Tools -> Extensions and updates -> select your extension" and click uninstall. Note that tool will not get uninstalled until VS is closed. Once closeed you will get a popup window to uninstall, select "Modify" to uninstall.
Well, during research, I got the answer of this problem.
Solution:
We have to load the the .bin file (via load hiv).
Make the changes or edit the bin to register your tool.
Unload hive.
Step#1: Load Hive.
a) Open registry (regedit). Select node HKEY_LOCAL_MACHINE.
b) Go to | File -> Load Hive
c) Select the bin file which is available at -> %LocalAppData%\ Microsoft\ VisualStudio\ 15.0_'instance_id'\privateregistry.bin.
d) Provide a key name. This will create a new key entry in HKEY_LOCAL_MACHINE with your key name.
e) You can check the .bin file at HKEY_LOCAL_MACHINE\YourKeyName\Software\Microsoft\VisualStudio\
Step#2: Edit the bin: You can now register your custom tool by following the same way as you were doing for other VS versions. Actually the only problem was to get the VS2017 keys in to the global registry and that is solved using Step#1 above.
Step#3: Unload Hive.
a) select your key under HKEY_LOCAL_MACHINE.
b) Go to | File menu
c) Unload Hive.
I am just starting to use the ToolStrip object on my windows Form.
I followed a nice tutorial that explained how to add the tool strip, then add a button, then assign a image to the button.
So, I added the toolstrip and then added the button:
As you can see, in the above screen shot I have also tried importing the image. I did this by right-clicking the button and choosing Set Image:
When I clicked OK, these extra files (MyGenioViewer1.Designer.cs) were automatically generated:
But now the project will not compile. If I restore my previous backup and do everything except importing a button, it compiles.
These are the errors:
Severity Code Description Project File Line Suppression State
Error CS0111 Type 'MyGenioView' already defines a member called '.ctor' with the same parameter types GENIO Viewer D:\My Programs\GENIO Viewer\GENIO Viewer\MyGenioView.cs 65 Active
Error CS0262 Partial declarations of 'MyGenioView' have conflicting accessibility modifiers GENIO Viewer D:\My Programs\GENIO Viewer\GENIO Viewer\MyGenioView.Designer.cs 25 Active
Error CS0260 Missing partial modifier on declaration of type 'MyGenioView'; another partial declaration of this type exists GENIO Viewer D:\My Programs\GENIO Viewer\GENIO Viewer\MyGenioView1.Designer.cs 25 Active
Error CS0111 Type 'MyGenioView' already defines a member called '.ctor' with the same parameter types GENIO Viewer D:\My Programs\GENIO Viewer\GENIO Viewer\MyGenioView1.Designer.cs 32 Active
Error CS0121 The call is ambiguous between the following methods or properties: 'MyGenioView.MyGenioView()' and 'MyGenioView.MyGenioView()' GENIO Viewer D:\My Programs\GENIO Viewer\GENIO Viewer\GENIO_Viewer_Form.cs 53 Active
Clearly, the addition of these extra files has caused me a problem. I don't know why they were added. I don't know how to resolve the issue. And I don't know how to prevent it.
Thank you for any clarification about resolving this issue correctly.
The original MyGenioView.Designer.cs contains:
namespace GENIO_Viewer
{
partial class MyGenioView
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// MyGenioView
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "MyGenioView";
this.ResumeLayout(false);
}
#endregion
}
}
The new MyGenioView1.Designer.cs causing issues is:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace GENIO_Viewer {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class MyGenioView {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal MyGenioView() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GENIO_Viewer.MyGenioView", typeof(MyGenioView).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
You've got a real mess here. Somehow, you wound up with a Designer file separate from a Form. One that, in fact, doesn't look like a designer file at all. What I didn't see in your screenshot was the form to which those Designers are supposed to be linked.
It should look like this:
You didn't show this class's code: MyGenioView.cs, but I'm guessing it already defines at least some of what is in MyGenioView1.Designer.cs.
The bottom line is that you have too many conflicting (partial) classes in too many places. It looks to me like you should have one class (code page) for MyGenioView, and another for the form. Anything else is conflicting.
P.S. I also wonder if you are confusing WPF constructs with WinForms. They are vastly different. Your use of the word 'View' suggested this to me. I may be wrong.
I'm trying to make a simple (no dependencies) .NET dll file that is accessible from VBA (MS Office). I'm using VS2015 Express, and make my dll the simplest way possible: Create a class library, add a simple class, and check the options "Make assembly COM-visible" as well as "Register for COM interop".
My C# code:
namespace TestLib {
public class Hello {
public int timestwo(int i) {
return 2 * i;
}
}
}
The library is added to the Windows registry automatically on build. I can access it from Tools --> References within the MS Office VBA editor, and the following VBA code works as expected:
Sub test()
Dim h as TestLib.Hello
MsgBox h.timestwo(2)
End Sub
Now the funny thing is: The object browser shows my class, but with no member functions! And consequently, the autocompletion feature does not work... What is going on here?
Mmm, your description of what you did is missing a few steps, it appears to me. You need GUIDs. You need an Interface, which your class needs to implement. And you need to specify how the class should work with the Interface. It needs to be set to the Type "None" for the Intellisense, etc. to work.
Here's an extract from a .NET COM DLL of mine which does appear in the Object Browser and gives Intellisense when referenced for a VBA project.
[Guid("149F7A5F-7DAC-4426-8AA0-28975A2CE203")]
[ComVisible(true)]
public interface ITest
{
string testLT(string FilePath, object Args);
string RemoveListTemplates(string FilePath, object Args);
void test(string arg);
}
[Guid("D86307C2-3FFA-4518-BABC-DA5F26ABC445")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Test : ITest
In VS, you need to add XML comments to your code:
namespace TestLib {
public class Hello {
/// <summary>
/// A method to return value * 2
/// </summary>
/// <param name="i">An integer to multiply by two</param>
public int timestwo(int i) {
return 2 * i;
}
}
}
Then make sure the tickbox for XML Documentation File is checked and ensure the XML file has the same name as your assembly. This should supply the meta data needed to populate the IntelliSense feature.
I incorporated a WLAN API given from Codeplex's Managed WiFi site into my C# project (Windows Form Application). In the API, different functions are given to retrieve various aspects of the machine's current WiFi profile. I am only interested in retrieving the RSSI strength given in the function below. I then want to take that value and stick it in a text box on my form.
(Visual Studio 2008)
In WlanAPI.cs file, the function I am interested in exists as such:
namespace NativeWifi
{
public class WlanClient
{
/// <summary>
/// Represents a Wifi network interface.
/// </summary>
public class WlanInterface
{
/// <summary>
/// Gets the RSSI.
/// </summary>
/// <value>The RSSI.</value>
/// <remarks>Not supported on Windows XP SP2.</remarks>
public int RSSI
{
get
{
return GetInterfaceInt(Wlan.WlanIntfOpcode.RSSI);
}
}
In myApp.cs I have a textbox simply named 'wifi' that will display the current RSSI.
I have included : 'using NativeWifi' in myApp.cs header, but can't seem to get the data from the RSSI function in the WlanAPI.csproj. The project builds and compiles just fine. I'm just snagged on getting the RSSI value.
In myApp.cs I have a statement to the effect of:
wifi.Text = (GetInterfaceInt(Wlan.WlanIntfOpcode.RSSI)); //app form txt_box=RSSI value
I know this is incorrect, but shows what I am trying to do.
Any ideas?
Thanks.
You should be able to solve the problems you are facing by
Adding a reference to WlanAPI.dll or WlanAPI project (if you add it to your solution)
Using code like following:
Using NativeWifi;
Class MyAPP : Form
{
public void PrintRSSI()
{
WlanClient client = new WlanClient();
var interfaces = client.Interfaces;
//Now chose an interface out of all the available interfaces. Usually there would be zero or 1 interfaces available
if(interfaces.Length > 0)
{
//Select first available interface. A more complicated logic can present the list of available interfaces to the user and and then display RSSI for the selected interface
wifi.Text = interfaces[0].RSSI.ToString();
}
}
//Other code for the class
}
I am a beginner when it comes to programming but I was sure that one of the universal rules was that a program starts with Main(). I do not see one when I create a WPF project. Is Main() simply named something differently in WPF?
The Main() method is created automatically.
If you want to provide your own you have to (tested in VS2013, VS2017 and VS2019):
Right-click App.xaml in the solution explorer, select Properties
Change 'Build Action' to 'Page' (initial value is 'ApplicationDefinition')
Then just add a Main() method to App.xaml.cs. It could be like this:
[STAThread]
public static void Main()
{
var application = new App();
application.InitializeComponent();
application.Run();
}
It is generated during build, but you can provide your own (disambiguating it in project-properties as necessary). Look in obj/debug for an app file; I have (courtesy of "C# 2010 Express") App.g.i.cs with:
namespace WpfApplication1 {
/// <summary>
/// App
/// </summary>
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public partial class App : System.Windows.Application {
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
#line 4 "..\..\..\App.xaml"
this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
#line default
#line hidden
}
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main() {
WpfApplication1.App app = new WpfApplication1.App();
app.InitializeComponent();
app.Run();
}
}
}
Main() is automatically provided by the CLR and the WPF.
The C# compiler takes a command-line switch /m which specifies the type that contains the implementation of Main(). By convention, if no startup object is explicitly specified, the CLR will lookup any class that has a static Main() method and will call it. (As #Marc Gravel pointed out in his comment)
In the case of WPF, the Main() is automatically generated when App.xaml is built and the /m switch is specified to make the C# compiler use that class as entry point. If you look at the project properties however, you'll find there's a setting for you to choose the startup object. So if you want, you can provide your own class that implements Main().
Note that this will put the responsibility on you to create the Application instance and call its Run() method to ensure that the WPF infrastructure is started properly.
Main() is generated during compilation. You can find it in App.g.cs (in obj/{Debug,Release} folder).
main() is a standard entry point for an application, but all applications are structured that way. In a XAML project, the App.XAML file specifies the entry point where it says StartupUri="MainWindow.xaml".
As it is stated by others, the actual main function is generated based on the contents of the XAML files in the project.
In case you removed default App.xaml and MinWindow.xaml, better to edit .csproj
After adding App.xaml manually, your .csproj will be:
<Page Include ="App.xaml">
<DependentUpon>MSBuild:Compile</DependentUpon>
<SubType>Code</SubType>
</Page>
Change this to:
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
I copied files that wouldn't load in another project that was without a mainwindow into a new one and got this error.
For me it took doing the opposite approach to Andreas Kahler to fix:
After making a window file and setting the startup uri to this file i switched Page to ApplicationDefinition of App.xaml 'Build Action' property.