dotnet / winforms

Windows Forms is a .NET UI framework for building Windows desktop applications.
MIT License
4.41k stars 984 forks source link

WinForms Designer SDK FAQ, Best Practices, News and Roadmap. #6942

Closed bairog closed 2 years ago

bairog commented 2 years ago

.NET 5/6 has an out-of-process WinForms Designer and docs for its SDK were promised for the first quarter of 2022:

There is a breaking change difference in how Designers work in Framework and .NET, so neither is this a bug, nor is it supposed to work this way.

To create a Designer for VS and .NET, you would need to use the WinForms Designer SDK. The reason is (simplified), that the Designer needs to run in the context of the Form (or the UserControl), which is .NET and not Framework. But VS is Framework. So, for the .NET Designer, there are two processes: The Client Process (Visual Studio, Framework) and a dedicated Server process (.NET) which is called the DesignToolsServer. So principally, and depending on what you need to do, you'd need to provide a NuGet which VS picks up, which holds the code for both the Server and the Client Process. And since the control and most part of the Designer logic is created in the Server process, anything Dialog-UI related needs to be marshalled from the Server process, which is not supposed to handle any dialogs due to potential dead lock concerns, back to the VS-Client.

Docs for the SDK are in the making, they are on our roadmap for the first quarter of this year. Originally posted by @KlausLoeffelmann in https://github.com/dotnet/winforms/issues/4451#issuecomment-1010264283

@KlausLoeffelmann First quarter of 2022 is over. Are docs for .NET WinForms Designer SDK ready?

janseris commented 2 years ago

The whole idea of this out-of-process designer for .NET Core (5/6) is terrible because it doesn't work properly in real use cases. I am glad to hear about any updates on it, as well.

merriemcgaw commented 2 years ago

@bairog , @janseris , We're working on those docs, but they're taking a bit longer than expected. We'll be getting them out to everyone as soon as we can, I promise πŸ˜„

@janseris - we didn't have any other choice as far as making an out of process designer for .NET 5+ apps. Previously WinForms Designer was running in the same process as VS, devenv.exe, which runs on .NET Framework. We had to pull the designer out into it's own .NET 5(or whatever is targeted) process and create a communication channel back to the .NET Framework process that is VS.

janseris commented 2 years ago

@merriemcgaw meanwhile I discovered that it might be the VS Professional version instead of Community (I am always working on the latest previe of VS 2022) working well or the problem lies solely in third party control vendors (DevExpress) designer because I have created very complicated layout without using any DevExpress controls in a new WinForms project to test this again and surprisingly everything worked very smoothly. Thank you and your team for all your work on WinForms. I will test this again with DevExpress controls soon.

bairog commented 2 years ago

@bairog , @janseris , We're working on those docs, but they're taking a bit longer than expected. We'll be getting them out to everyone as soon as we can, I promise πŸ˜„

@merriemcgaw Hope you will drop us a link as soon as docs (or at least a part of them) will be ready. Also tagging @chris-steema as this docs will help him with .NET 5.0 OnCreateHandle override isn't called issue #4451 (and me personally is waiting for a fix in his awesome charting control library πŸ˜„)

KlausLoeffelmann commented 2 years ago

@bairog: Good news is, a really comprehensive demo for the SDK is 99% complete. I am in the process of documenting it, and it covers

We've decided to go public with that sample and a blog post first, so that folks will be able to start migrating, even with the docs not completed. Then, we'll be adding to the docs over time.

As soon I will be able to provide further info, I'll make sure to post them here.

kirsan31 commented 2 years ago

The resulting assemblies (.NET Framework and .NET) need to be packed in a NuGet, and then picked up by the Designer for design time purposes.

This part raises the most questions... If I have a local control - can I do without nuget?

KlausLoeffelmann commented 2 years ago

What do you mean by local control?

RussKie commented 2 years ago

I presume scenarios here could be:

KlausLoeffelmann commented 2 years ago

Ah, OK, yes, that makes sense.

Well, if your Control Library includes controls that need a dedicated UI via custom Type Editors, then you are required to pack into a NuGet. The reason is, that the Client part needs to be loaded in the context of VS, and the Server part into the context of the DesignToolsServer. If not, so, if the Control needs let's say just custom adorners, action lists or custom CodeDom serializers, then no. You still need to build the Control Designers against the SDK, though, and you should have it in a dedicated project. But as soon as you need a custom UI for a Control Designer of the Library, those three assemblies/four projects, so the Client Part, the Server Part, the code for RPCs from Client to Server and the Packaging become a requirement.

kirsan31 commented 2 years ago

Well, if your Control Library includes controls that need a dedicated UI via custom Type Editors, then you are required to pack into a NuGet.

Yes, this is exactly what I was afraid of :( But let's hope this is the worst thing that awaits us πŸ˜†

KlausLoeffelmann commented 2 years ago

While the work on the blog post is in progress, the complete SDK docs will take a while due to a shift in internal prios. We know you're eager for sample code and starting points, so please take a look here for an early access to our SDK sample candidate:

https://github.com/KlausLoeffelmann/NetControlDesigners

kirsan31 commented 2 years ago

@KlausLoeffelmann I've spend some time on studying this. My thots / questions:

exception ``` Failed to create component 'Chart'. The error message follows: 'Microsoft.DotNet.DesignTools.Client.DesignToolsServerException: Method not found: 'System.CodeDom.CodeExpression Microsoft.DotNet.DesignTools.Serialization.CodeDomSerializerBase.SerializeToExpression(System.ComponentModel.Design.Serialization.IDesignerSerializationManager, System.Object)'. at Microsoft.DotNet.DesignTools.Client.DesignToolsClient.d__49`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.VisualStudio.Threading.JoinableTask.CompleteOnCurrentThread() at Microsoft.VisualStudio.Threading.JoinableTask`1.CompleteOnCurrentThread() at Microsoft.DotNet.DesignTools.Protocol.Endpoints.DesignToolsEndpoints.DesignerHostsImpl.CreateComponent(SessionId sessionId, TypeIdentity type, String name, NameValuePairs defaultValues) at Microsoft.WinForms.DesignTools.Client.Toolbox.WinFormsToolboxItem.CreateComponentsCore(IDesignerHost host, IDictionary defaultValues) at System.Drawing.Design.ToolboxItem.CreateComponents(IDesignerHost host, IDictionary defaultValues) at Microsoft.DotNet.DesignTools.Client.Designers.ParentControlProxyDesigner.CreateTool(ToolboxItem tool, IComponent parent, Nullable`1 location, Nullable`1 size, ObjectProxy toolboxSnapArgs)' ```
merriemcgaw commented 2 years ago

Maybe it will become easier when the full documentation appears? πŸ€·β€β™‚οΈ And examples of converting old projects is defiantly needed.

Yes, we're hoping it will make things a lot easier. And we will be investigating ways to simplify the building of controls as well as converting old controls. It's a process for sure.

KlausLoeffelmann commented 2 years ago

The most problems I faced are absent of editors ArrayEditor, ColorEditor, FileNameEditor etc. And their methods for override...

They are still part of both the .NET and the .NET Framework runtime, although those types as a base for derived Editors in a Server-only scenario don't make sense, since they are never deployed: The .NET types cannot run in the context of VS, and the .NET Framework types lack the infrastructure to be deployed in a server-only scenario. What you can do though in a server-only scenario is to invoke the client-types. In this case the communication between Server (the DesignToolsServer) and Client (Visual Studio) is handled automatically in the background, but only for the respective data types. So, for just using the existing editors, you currently need to include their assembly qualified type names with the Editor attribute for the respective property, and you should be good to go. Like this as an example, to enable a FileNameEditor for any property of type string:

        [Editor("System.Windows.Forms.Design.FileNameEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
        public string? Filename { get; set; }

Now, if you want to change the behavior of one of those editors in any way (or create new ones completely from scratch). then, yes, those editors must be running in the context of the Client. As long as you don't change the data types they are handling, you can just modify the editors in an assembly that targets the same TF version as the client, and the rest should work out of the box. But also yes, in that case your overridden types need to be loaded into the context of VS, and so you'd need to have the NuGet package deployment for that in place, even if you - in most cases - would not need to implement or change the underlaying communication between the DesignToolsServer and the client. Except you're handling different types.

Can you, just for my own understanding of the use case, provide a description of what part of the editor you want to change and to what end? That would be helpful!

[...] BUT It evokes a sense of betrayal any way

Can you clarify what you mean? What confuses me is that strong statement of yours, while you write at the same time "I understand the reason behind this".

For a bit more explanation, and that may be helping also in the understanding of our motivation to do this, because this enormous effort that we're doing with rewriting the Designer is really, really not out of some "arbitrary good idea" someone from our team had. It's a real and urgent necessity: Because we are not only addressing the .NET/.NET Framework type-resolution problem with it, so that VS runs in the context of .NET Framework and cannot resolve types from a WinForms .NET app. Rather, we cannot change but need to address the fact that Visual Studio is only one Framework and one Bitness at a time. (So, 64-Bit and .NET Framework in the case of Visual Studio 2022.) Out of that fact, please be clear about this: We will also take the Framework Designer out of process to address the problem, that we cannot - for example - host certain 32-Bit-only .NET Framework components in the 64-bit-.NET-Framework-process running Visual Studio 2022+. So, the whole effort we're doing here does not have anything to do with abandoning any .NET (Framework) version over another. On the contrary! This is a rewrite to make sure, that no matter what bitness and version Visual Studio runs in, it will always be able to host any completely different bitness/.NET version combination of the WinForms app it's providing the Designer for!

The documentation will certainly help to understand this better, but to finalize the documentation in a somewhat sane time frame, it needs more than just me working on that, so, we will be publishing not in one peace, but more and more of it over time.

And all this said - please, by any means: Those questions of yours are really, really helpful for us and for others, and I appreciate your contribution and engagement A LOT! Please, keep those questions coming!

Best

Klaus

KlausLoeffelmann commented 2 years ago

Oh, and sorry, I missed your last point!

When reference a control by project reference and adding it from toolbar to the form, the exception appears (when reference a control by dll reference - all work good).

Can you provide a small sample project for this? I would need to debug into that to see exactly what's going on.

kirsan31 commented 2 years ago

@KlausLoeffelmann thank you for detailed answer. Especially the part about x86/x64 is something that is not quite obvious at first glance

Can you clarify what you mean? What confuses me is that strong statement of yours, while you write at the same time "I understand the reason behind this".

I will try to...

And the short version:

But perhaps this is purely my subjective perception caused by the fact that over the years I had to keep legacy .Net Framework just for the sake of the designer's work...

Can you provide a small sample project for this? I would need to debug into that to see exactly what's going on.

Unfortunately I can't provide small project, because it's about System.Windows.Forms.DataVisualization. You can get my fork here. Everything you need for debug is already there: draft designer port and DesignerTest project (with project reference to ChartWin) with empty form.

Can you, just for my own understanding of the use case, provide a description of what part of the editor you want to change and to what end? That would be helpful!

Here is commit with my draft port: https://github.com/kirsan31/winforms-datavisualization/commit/17698a2255af0eb504588a6ee58d83cc36394924. All places that raise questions are marked with #warning designer.

KlausLoeffelmann commented 2 years ago

Well,

I think from what your write, it's best to address 3 major issues, which might also be good to hear about for the rest of the community, so, again, what you write is very valuable!

I already want to completely abandon and forget about .Net Framework!

I can't share this idea.

We have some example about design user control in .Net! WoW can I now to port my control and forget about .Net Framework? I'm afraid - NO because you need to code client side in .Net Framework 😁

The sample has both the Client (.NET Framework)/Server (.NET) and the Server-only version in it. So, is the only fact that I might be missing here, that you don't like to support .NET Framework anymore?

One way or the other, we can of course discuss forever the "Ifs" and "Wetheres" - but that doesn't bring us one inch/cm closer to our goals. I'd suggest concentrating on solving immediate problems now, with the person-power which we all have at our disposal. And given the work, we need to do, it is of course limited, so, prioritizing, being agile, and also being able to pivot the direction for taking on the next issue area if necessary, is something, which is good and will happen once in a while. This might be leading to decisions which not everyone always likes. But if that happens, I think the most important part is to explain decisions as much as possible and keep the dialog alive. I think this will get the best results for all of us.

KlausLoeffelmann commented 2 years ago

I also took the liberty to rename this issue, so people could easier assume to find answers to questions here, they are looking for. I think this is more inclusive.

KlausLoeffelmann commented 2 years ago

@bairog, @kirsan31, @janseris, @merriemcgaw: What do you think about the idea to add the initial post by an [Update] section, where we add links to resources about the Designer SDK?