dotnet/project-system

Windows Forms and WPF project support

jnm2 opened this issue ยท 8 comments

jnm2 commented

I could not find another issue tracking Windows Forms and WPF support in its entirety. The main justification for the decision to unify everything under .csproj was build SDK compatibility and I'm still looking forward to the list of benefits across the board. There are crucial ways in which legacy csproj just doesn't interoperate with the modern SDK.

For one example out of many, we are sorely missing a Pack target. Right now I have to write this kind of code to generate my own nuspec which is a crude hack. I am now searching for the best way to parse and handle PrivateAssets="all" and other values:

IReadOnlyList<(string id, string version)> ReadNuspecDependencies(string legacyCsproj)
{
    using (var reader = XmlReader.Create(legacyCsproj))
    {
        reader.MoveToContent();
        var namespaceManager = new XmlNamespaceManager(new NameTable());
        namespaceManager.AddNamespace("m", "http://schemas.microsoft.com/developer/msbuild/2003");

        return (
            from element in XNode.ReadFrom(reader).XPathSelectElements("/m:ItemGroup/m:PackageReference", namespaceManager)
            select (element.Attribute("Include").Value, element.Attribute("Version").Value)
        ).ToList();
    }
}

In order to be able to pack properly, we'll need to be able to move the modern SDK. That means:

  • Making the Windows Forms designers work in a modern-SDK csproj
    • SubType noise is added all over the csproj (#997)
    • Double-clicking does not open the designer. (#1272 (comment))
    • Every time the form is edited in the designer, Form1.designer.cs gets replaced by the codegen for Form1.resx. This loses the partial modifier so the code does not compile, and moves InitializeComponent and all the field declarations into Form1.cs which is less than ideal.
      Every time, I have to manually remove the internal modifier and add the partial modifier to Form1.designer.cs and delete the constructor. If you delete the .resx and the resx-generated designer file, the designer will no longer open. (#1272 (comment), #159)
    • The icon for Form1.cs is not the Form icon. (#1272 (comment))
    • Once the designer is opened, the Text property is blank. Usually it would be Form1. (#1272 (comment))
    • Deliverance from licenses.licx. That file being added to the csproj has caused ongoing pain over the years with Windows Forms projects. It's fine existing locally (even though it seems truly pointless and should be cached outside of the source code), but the file itself is filtered from source control because of the inevitable thrashing of assembly-qualified type name versions that happens and the inevitable build errors it causes on both dev machines and build servers. The last remaining piece of the puzzle is to keep it from appearing in the .csproj at all, because it's hard to notice and catch that before accidentally checking in the .csproj and having the build server choke on the missing file. (#1272 (comment))
  • Making the WPF designers work in a modern-SDK csproj
    • To be filled out.

@davkean, you invited me in January to create and link back each of these items. Is that still a helpful thing to do?

Again, the legacy SDK combined with Windows Forms has already been less than friendly to us for years and years. But after tasting the new opportunities of the modern SDK in our libraries and console apps, it's becoming ever more frustrating to continue putting up with the discrepancy.

What's the status of UWP? Could it be tracked together? Some components could be shared with WPF.

wjk commented

@jnm2 @huoyaoyuan WPF support actually already works in SDK-style csproj, designer and all! See the MSBuild.Sdk.Extras package. You can see the README for basic instructions on how to use it, but please note that those instructions are out-of-date. Instead, see the WPF sample instead.

I would recommend copy/pasting the entire contents of WpfApplication.csproj into your csproj, because the correct MSBuild invocation for WPF designer support is quite quirky. However, if you do this, you will need to change the OriginalProjectName property to contain the name of the csproj file, without its extension (do not use $(MSBuildProjectFileName) here, it won't work). If you don't keep this value up to date, the WPF designer won't "see" NuGet packages you've referenced.

I was actually the one who got the WPF support to work. ๐Ÿ˜„ Hope this helps!

jnm2 commented

Very interesting! I spend almost all my time in Windows Forms rather than WPF, but I'll look for a chance to try it out.

We're still working out a timeline for improved support of other project types. That's currently being superseded by performance and reliability work for our existing scenarios. Going to put this in our "Unknown" milestone until it becomes a focus.

@Pilchie

any update on this? When can we expect official support? VS16/2019?

@MagicAndre1981 As per the roadmap and feature list, 2019/16.0 will include WinForms/WPF support.

@Pilchie thanks for the links. I haven't noticed them before

Going to close this - WPF/WinForms support was adding in 16.3/16.4 timeframe. I've looked through all the listed items and we have addressed all them. Please file individual bugs for any new issues that you encounter.