From 4f7f9a4fc57f7003ba2e9c86c34b55ab1f6fd7f2 Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Wed, 3 May 2023 12:13:49 -0700 Subject: [PATCH 01/11] Implement first draft of RootDesigner samples. --- .../RootDesignerDemo/RootDesignerDemo.sln | 31 ++ .../RootDesignerDemo/App.config | 38 +++ .../RootDesignerDemo/Form1.Designer.cs | 145 ++++++++ .../RootDesignerDemo/Form1.cs | 12 + .../RootDesignerDemo/Form1.resx | 123 +++++++ .../SimpleBoxComponent.Designer.cs | 36 ++ .../HostingComponents/SimpleBoxComponent.cs | 25 ++ .../RootDesignerDemo/Program.cs | 22 ++ .../Properties/AssemblyInfo.cs | 36 ++ .../Properties/Resources.Designer.cs | 71 ++++ .../Properties/Resources.resx | 117 +++++++ .../Properties/Settings.Designer.cs | 30 ++ .../Properties/Settings.settings | 7 + .../RootDesignerDemo/RootDesignedComponent.cs | 19 ++ .../RootDesignedComponent.resx | 123 +++++++ .../RootDesignerDemo/RootDesignerDemo.csproj | 93 +++++ .../SampleRootDesigner.RootDesignerView.cs | 30 ++ .../RootDesignerDemo/SampleRootDesigner.cs | 67 ++++ .../RootDesignerDemo/ShapeDocument.cs | 14 + .../Properties/AssemblyInfo.cs | 36 ++ .../Properties/Resources.Designer.cs | 93 +++++ .../Properties/Resources.resx | 130 +++++++ .../RootDesignerSupportLib/Resources/Line.bmp | Bin 0 -> 3382 bytes .../Resources/Rectangle.bmp | Bin 0 -> 3382 bytes .../RootDesignerSupportLib/Resources/Text.bmp | Bin 0 -> 3382 bytes .../SampleRootDesigner.RootDesignerView.cs | 60 ++++ .../RootDesigner/SampleRootDesigner.cs | 153 +++++++++ .../RootDesigner/ShapeDocumentBase.cs | 47 +++ .../RootDesigner/ShapeDocumentBase.resx | 132 ++++++++ .../RootDesignerSupportLib.csproj | 267 +++++++++++++++ .../SimpleBoxComponent.Designer.cs | 36 ++ .../ShapeComponents/SimpleBoxComponent.cs | 25 ++ .../IToolboxServiceControl.cs | 208 ++++++++++++ .../IToolboxServiceControl.resx | 120 +++++++ .../TextDataTextBoxComponent.cs | 157 +++++++++ .../VsOutputWindowLogger.cs | 30 ++ .../WindowMessageDesigner.cs | 21 ++ .../RootDesignerSupportLib/app.config | 35 ++ .../RootDesignerSupportLib/packages.config | 56 +++ .../Directory.Build.targets | 8 + .../Net/ClientServerSample/NuGet.config | 8 + .../Properties/Resources.Designer.cs | 93 +++++ .../Properties/Resources.resx | 130 +++++++ .../Resources/Line.bmp | Bin 0 -> 3382 bytes .../Resources/Rectangle.bmp | Bin 0 -> 3382 bytes .../Resources/Text.bmp | Bin 0 -> 3382 bytes .../RootDesignerDemo.Client.csproj | 34 ++ .../ShapeRootProxyDesigner.cs | 97 ++++++ .../TypeEditor/CustomEnumClientVersion.cs | 14 + .../TypeEditor/ErrorProviderExtension.cs | 28 ++ .../TypeEditor/RdTypeEditor.cs | 57 ++++ .../TypeEditor/RdTypeEditorDialog.Designer.cs | 240 +++++++++++++ .../TypeEditor/RdTypeEditorDialog.cs | 109 ++++++ .../TypeEditor/RdTypeEditorDialog.resx | 123 +++++++ .../TypeEditor/RdTypeEditorVMClient.cs | 92 +++++ .../TypeRoutingProvider.cs | 31 ++ .../RootDesignerDemo.Controls/RdControl.cs | 128 +++++++ .../RdPropertyStore.cs | 55 +++ .../RdPropertyStoreEnum.cs | 13 + .../RootDesignerDemo.Controls.csproj | 16 + .../ShapeDocumentBase.cs | 19 ++ .../ShapeDocumentBase.resx | 123 +++++++ .../RootDesignerDemo.Package.csproj | 39 +++ .../DataTransport/RdPropertyStoreData.cs | 69 ++++ .../RootDesignerDemo.Protocol/EditorNames.cs | 15 + .../EndpointNames.cs | 11 + .../Endpoints/CreateRdTypeEditorVMEndpoint.cs | 35 ++ .../Endpoints/CreateRdTypeEditorVMRequest.cs | 38 +++ .../Endpoints/CreateRdTypeEditorVMResponse.cs | 44 +++ .../Endpoints/RdTypeEditorOKClickEndpoint.cs | 22 ++ .../Endpoints/RdTypeEditorOKClickRequest.cs | 44 +++ .../Endpoints/RdTypeEditorOKClickResponse.cs | 23 ++ .../CallerArgumentExpressionAttribute.cs | 21 ++ .../GlobalUtilities/GlobalUtilities.cs | 168 +++++++++ .../GlobalUtilities/NullableAttributes.cs | 153 +++++++++ .../GlobalUtilities/ThrowHelper.cs | 44 +++ .../RootDesignerDemo.Protocol.csproj | 10 + .../ViewModelNames.cs | 10 + .../RdPropertyStoreCodeDomSerializer.cs | 95 ++++++ .../RdControlDesigner.ActionList.cs | 78 +++++ .../ControlDesigner/RdControlDesigner.cs | 51 +++ .../Handler/CreateRdTypeEditorVMHandler.cs | 28 ++ .../Handler/RdTypeEditorOkClickHandler.cs | 28 ++ .../RdTypeEditor/RdTypeEditorVM.Factory.cs | 19 ++ .../RdTypeEditor/RdTypeEditorVM.cs | 64 ++++ ...hapeRootDesigner.SampleRootDesignerView.cs | 52 +++ .../RootDesigner/ShapeRootDesigner.cs | 42 +++ .../RootDesignerDemo.Server.csproj | 14 + .../TypeRoutingProvider.cs | 29 ++ .../ClientServerSample/RootDesignerDemo.sln | 77 +++++ .../RootDesignerTestApp/Form1.Designer.cs | 83 +++++ .../RootDesignerTestApp/Form1.cs | 10 + .../RootDesignerTestApp/Form1.resx | 120 +++++++ .../RootDesignerTestApp/Program.cs | 17 + .../RootDesignerTestApp.csproj | 15 + .../RootDesignerTestApp/ShapeDocument.cs | 16 + .../RootDesignerTestApp/ShapeDocument.resx | 120 +++++++ .../Net/ClientServerSample/readme.md | 320 ++++++++++++++++++ .../CustomControl/SimpleCustomControl.cs | 10 + .../SimpleCustomControlDesigner.cs | 80 +++++ .../RootDesigner.Lib/RootDesigner.Lib.csproj | 14 + ...mpleRootDesigner.SampleRootDesignerView.cs | 58 ++++ .../RootDesigner/SampleRootDesigner.cs | 114 +++++++ .../RootDesigner/ShapeDocumentBase.cs | 19 ++ .../RootDesigner/ShapeDocumentBase.resx | 123 +++++++ .../SimpleBoxComponent.Designer.cs | 35 ++ .../ShapeComponents/SimpleBoxComponent.cs | 18 + .../ShapeComponents/SimpleBoxComponent.resx | 120 +++++++ .../Net/Simple Sample/RootDesignerDemo.sln | 31 ++ .../RootDesignerDemo/Form1.Designer.cs | 57 ++++ .../Simple Sample/RootDesignerDemo/Form1.cs | 20 ++ .../Simple Sample/RootDesignerDemo/Form1.resx | 120 +++++++ .../Simple Sample/RootDesignerDemo/Program.cs | 17 + .../RootDesignerDemo/RootDesignerDemo.csproj | 15 + .../RootDesignerDemo/ShapeDocument.cs | 14 + .../RootDesignerDemo/ShapeDocument.resx | 120 +++++++ .../TileRepeater.Package.1.234.121557.zip | Bin 0 -> 47108 bytes .../TileRepeater.Package.nuspec | 13 + .../[Content_Types].xml | 8 + .../_rels/.rels | 5 + .../TileRepeater.ClientServerProtocol.dll | Bin 0 -> 13312 bytes .../Server/TileRepeater.Designer.Server.dll | Bin 0 -> 17408 bytes .../TileRepeater.ClientServerProtocol.dll | Bin 0 -> 13312 bytes .../WinForms/TileRepeater.Designer.Client.dll | Bin 0 -> 18944 bytes .../lib/net6.0/TileRepeater.Controls.dll | Bin 0 -> 20992 bytes .../871454ca44c34012b8ddbcedc07e7c8e.psmdcp | 9 + 126 files changed, 7107 insertions(+) create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo.sln create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/App.config create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.Designer.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.resx create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/HostingComponents/SimpleBoxComponent.Designer.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/HostingComponents/SimpleBoxComponent.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Program.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/AssemblyInfo.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Resources.Designer.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Resources.resx create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Settings.Designer.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Settings.settings create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignedComponent.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignedComponent.resx create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignerDemo.csproj create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/SampleRootDesigner.RootDesignerView.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/SampleRootDesigner.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/ShapeDocument.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/AssemblyInfo.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/Resources.Designer.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/Resources.resx create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Resources/Line.bmp create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Resources/Rectangle.bmp create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Resources/Text.bmp create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/SampleRootDesigner.RootDesignerView.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/SampleRootDesigner.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/ShapeDocumentBase.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/ShapeDocumentBase.resx create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesignerSupportLib.csproj create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ShapeComponents/SimpleBoxComponent.Designer.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ShapeComponents/SimpleBoxComponent.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/IToolboxServiceControl.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/IToolboxServiceControl.resx create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/TextDataTextBoxComponent.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/VsOutputWindowLogger.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/WindowMessageDesigner.cs create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/app.config create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/packages.config create mode 100644 Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets create mode 100644 Samples/RootDesigner/Net/ClientServerSample/NuGet.config create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Properties/Resources.Designer.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Properties/Resources.resx create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Resources/Line.bmp create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Resources/Rectangle.bmp create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Resources/Text.bmp create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerDemo.Client.csproj create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/CustomEnumClientVersion.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/ErrorProviderExtension.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditor.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.Designer.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.resx create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorVMClient.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeRoutingProvider.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdControl.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdPropertyStore.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdPropertyStoreEnum.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RootDesignerDemo.Controls.csproj create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeDocumentBase.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeDocumentBase.resx create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Package/RootDesignerDemo.Package.csproj create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/DataTransport/RdPropertyStoreData.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/EditorNames.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/EndpointNames.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMEndpoint.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMRequest.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMResponse.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickEndpoint.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickRequest.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickResponse.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/CallerArgumentExpressionAttribute.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/GlobalUtilities.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/NullableAttributes.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/ThrowHelper.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/RootDesignerDemo.Protocol.csproj create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/ViewModelNames.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/CodeDomSerializer/RdPropertyStoreCodeDomSerializer.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/ControlDesigner/RdControlDesigner.ActionList.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/ControlDesigner/RdControlDesigner.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/Handler/CreateRdTypeEditorVMHandler.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/Handler/RdTypeEditorOkClickHandler.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/RdTypeEditorVM.Factory.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/RdTypeEditorVM.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.SampleRootDesignerView.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesignerDemo.Server.csproj create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/TypeRoutingProvider.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.sln create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.Designer.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.resx create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Program.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/RootDesignerTestApp.csproj create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.resx create mode 100644 Samples/RootDesigner/Net/ClientServerSample/readme.md create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/CustomControl/SimpleCustomControl.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/CustomControl/SimpleCustomControlDesigner.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner.Lib.csproj create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/SampleRootDesigner.SampleRootDesignerView.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/SampleRootDesigner.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/ShapeDocumentBase.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/ShapeDocumentBase.resx create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.Designer.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.resx create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo.sln create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.Designer.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.resx create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Program.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/RootDesignerDemo.csproj create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/ShapeDocument.cs create mode 100644 Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/ShapeDocument.resx create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557.zip create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/TileRepeater.Package.nuspec create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/[Content_Types].xml create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/_rels/.rels create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/Server/TileRepeater.ClientServerProtocol.dll create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/Server/TileRepeater.Designer.Server.dll create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/TileRepeater.ClientServerProtocol.dll create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/TileRepeater.Designer.Client.dll create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/TileRepeater.Controls.dll create mode 100644 Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/package/services/metadata/core-properties/871454ca44c34012b8ddbcedc07e7c8e.psmdcp diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo.sln b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo.sln new file mode 100644 index 0000000..64e66f8 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33209.295 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RootDesignerDemo", "RootDesignerDemo\RootDesignerDemo.csproj", "{5887C1E1-5924-4A07-84F8-BA9C616F4BAF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RootDesignerSupportLib", "RootDesignerSupportLib\RootDesignerSupportLib.csproj", "{548CC959-438A-4BCB-9AF3-D0F019F4C3BC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5887C1E1-5924-4A07-84F8-BA9C616F4BAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5887C1E1-5924-4A07-84F8-BA9C616F4BAF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5887C1E1-5924-4A07-84F8-BA9C616F4BAF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5887C1E1-5924-4A07-84F8-BA9C616F4BAF}.Release|Any CPU.Build.0 = Release|Any CPU + {548CC959-438A-4BCB-9AF3-D0F019F4C3BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {548CC959-438A-4BCB-9AF3-D0F019F4C3BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {548CC959-438A-4BCB-9AF3-D0F019F4C3BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {548CC959-438A-4BCB-9AF3-D0F019F4C3BC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {48A19B94-7503-4753-AEA9-A7C03F2EF695} + EndGlobalSection +EndGlobal diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/App.config b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/App.config new file mode 100644 index 0000000..e376a0e --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/App.config @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.Designer.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.Designer.cs new file mode 100644 index 0000000..85553d5 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.Designer.cs @@ -0,0 +1,145 @@ +namespace RootDesignerDemo +{ + partial class Form3 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.lkjlkjhlkfhjlkfToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.hkkjhkjhkjkjhkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.kjhkjhkjhkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.klkjlkjljToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.GripMargin = new System.Windows.Forms.Padding(2, 2, 0, 2); + this.menuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32); + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.lkjlkjhlkfhjlkfToolStripMenuItem, + this.hkkjhkjhkjkjhkToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Padding = new System.Windows.Forms.Padding(4, 2, 0, 2); + this.menuStrip1.Size = new System.Drawing.Size(811, 33); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // lkjlkjhlkfhjlkfToolStripMenuItem + // + this.lkjlkjhlkfhjlkfToolStripMenuItem.Name = "lkjlkjhlkfhjlkfToolStripMenuItem"; + this.lkjlkjhlkfhjlkfToolStripMenuItem.Size = new System.Drawing.Size(124, 29); + this.lkjlkjhlkfhjlkfToolStripMenuItem.Text = "lkjlkjhlkfhjlkf"; + // + // hkkjhkjhkjkjhkToolStripMenuItem + // + this.hkkjhkjhkjkjhkToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.kjhkjhkjhkToolStripMenuItem, + this.klkjlkjljToolStripMenuItem}); + this.hkkjhkjhkjkjhkToolStripMenuItem.Name = "hkkjhkjhkjkjhkToolStripMenuItem"; + this.hkkjhkjhkjkjhkToolStripMenuItem.Size = new System.Drawing.Size(138, 29); + this.hkkjhkjhkjkjhkToolStripMenuItem.Text = "hkkjhkjhkjkjhk"; + // + // kjhkjhkjhkToolStripMenuItem + // + this.kjhkjhkjhkToolStripMenuItem.Name = "kjhkjhkjhkToolStripMenuItem"; + this.kjhkjhkjhkToolStripMenuItem.Size = new System.Drawing.Size(192, 34); + this.kjhkjhkjhkToolStripMenuItem.Text = "kjhkjhkjhk"; + // + // klkjlkjljToolStripMenuItem + // + this.klkjlkjljToolStripMenuItem.Name = "klkjlkjljToolStripMenuItem"; + this.klkjlkjljToolStripMenuItem.Size = new System.Drawing.Size(192, 34); + this.klkjlkjljToolStripMenuItem.Text = "klkjlkjlj"; + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Location = new System.Drawing.Point(165, 334); + this.checkBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(113, 24); + this.checkBox1.TabIndex = 1; + this.checkBox1.Text = "checkBox1"; + this.checkBox1.UseVisualStyleBackColor = true; + // + // comboBox1 + // + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Location = new System.Drawing.Point(393, 334); + this.comboBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(354, 28); + this.comboBox1.TabIndex = 2; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(166, 125); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(51, 20); + this.label1.TabIndex = 3; + this.label1.Text = "label1"; + // + // Form3 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(811, 414); + this.Controls.Add(this.label1); + this.Controls.Add(this.comboBox1); + this.Controls.Add(this.checkBox1); + this.Controls.Add(this.menuStrip1); + this.MainMenuStrip = this.menuStrip1; + this.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.Name = "Form3"; + this.Text = "Form1"; + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private TextDataTextBoxComponent.TextDataTextBoxComponent textDataTextBoxComponent1; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem lkjlkjhlkfhjlkfToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem hkkjhkjhkjkjhkToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem kjhkjhkjhkToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem klkjlkjljToolStripMenuItem; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.Label label1; + } +} + diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.cs new file mode 100644 index 0000000..2512b68 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.cs @@ -0,0 +1,12 @@ +using System.Windows.Forms; + +namespace RootDesignerDemo +{ + public partial class Form3 : Form + { + public Form3() + { + InitializeComponent(); + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.resx b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.resx new file mode 100644 index 0000000..25af2b6 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 488, 17 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/HostingComponents/SimpleBoxComponent.Designer.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/HostingComponents/SimpleBoxComponent.Designer.cs new file mode 100644 index 0000000..54ca929 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/HostingComponents/SimpleBoxComponent.Designer.cs @@ -0,0 +1,36 @@ +namespace RootDesignerDemo.HostingComponents +{ + partial class SimpleBoxComponent + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/HostingComponents/SimpleBoxComponent.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/HostingComponents/SimpleBoxComponent.cs new file mode 100644 index 0000000..0ac538c --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/HostingComponents/SimpleBoxComponent.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RootDesignerDemo.HostingComponents +{ + public partial class SimpleBoxComponent : Component + { + public SimpleBoxComponent() + { + InitializeComponent(); + } + + public SimpleBoxComponent(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Program.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Program.cs new file mode 100644 index 0000000..e7e63f3 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace RootDesignerDemo +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form3()); + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/AssemblyInfo.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3a87c32 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RootDesignerDemo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RootDesignerDemo")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5887c1e1-5924-4a07-84f8-ba9c616f4baf")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Resources.Designer.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Resources.Designer.cs new file mode 100644 index 0000000..6a51467 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace RootDesignerDemo.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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 Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RootDesignerDemo.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Resources.resx b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Settings.Designer.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Settings.Designer.cs new file mode 100644 index 0000000..42e0174 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace RootDesignerDemo.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Settings.settings b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignedComponent.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignedComponent.cs new file mode 100644 index 0000000..e974530 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignedComponent.cs @@ -0,0 +1,19 @@ +using System.ComponentModel; +using System.ComponentModel.Design; + +namespace SampleRootDesigner +{ + // The following attribute associates the SampleRootDesigner designer + // with the SampleComponent component. + [Designer(typeof(SampleRootDesigner), typeof(IRootDesigner))] + public class RootDesignedComponent : Component + { + public RootDesignedComponent() + { + } + + private void InitializeComponent() + { + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignedComponent.resx b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignedComponent.resx new file mode 100644 index 0000000..e5858cc --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignedComponent.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignerDemo.csproj b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignerDemo.csproj new file mode 100644 index 0000000..45aa50b --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/RootDesignerDemo.csproj @@ -0,0 +1,93 @@ + + + + + Debug + AnyCPU + {5887C1E1-5924-4A07-84F8-BA9C616F4BAF} + WinExe + RootDesignerDemo + RootDesignerDemo + v4.8.1 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + + + Component + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {548CC959-438A-4BCB-9AF3-D0F019F4C3BC} + RootDesignerSupportLib + + + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/SampleRootDesigner.RootDesignerView.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/SampleRootDesigner.RootDesignerView.cs new file mode 100644 index 0000000..6334eaf --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/SampleRootDesigner.RootDesignerView.cs @@ -0,0 +1,30 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace SampleRootDesigner +{ + public partial class SampleRootDesigner + { + // RootDesignerView is a simple control that will be displayed + // in the designer window. + private class RootDesignerView : Control + { + private SampleRootDesigner m_designer; + + public RootDesignerView(SampleRootDesigner designer) + { + m_designer = designer; + BackColor = Color.Blue; + Font = new Font(Font.FontFamily.Name, 24.0f); + } + + protected override void OnPaint(PaintEventArgs pe) + { + base.OnPaint(pe); + + // Draws the name of the component in large letters. + pe.Graphics.DrawString(m_designer.Component.Site.Name, Font, Brushes.Yellow, ClientRectangle); + } + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/SampleRootDesigner.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/SampleRootDesigner.cs new file mode 100644 index 0000000..a350521 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/SampleRootDesigner.cs @@ -0,0 +1,67 @@ +using System; +using System.ComponentModel.Design; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace SampleRootDesigner +{ + public partial class SampleRootDesigner : ComponentDesigner, IRootDesigner, IToolboxUser, IToolboxItemProvider + { + // Member field of custom type RootDesignerView, a control that + // will be shown in the Forms designer view. This member is + // cached to reduce processing needed to recreate the + // view control on each call to GetView(). + private RootDesignerView m_view; + + // This method returns an instance of the view for this root + // designer. The "view" is the user interface that is presented + // in a document window for the user to manipulate. + object IRootDesigner.GetView(ViewTechnology technology) + { + if (technology != ViewTechnology.Default) + { + throw new ArgumentException("Not a supported view technology", "technology"); + } + + if (m_view == null) + { + // Some type of displayable Form or control is required + // for a root designer that overrides GetView(). In this + // example, a Control of type RootDesignerView is used. + // Any class that inherits from Control will work. + m_view = new RootDesignerView(this); + } + return m_view; + } + + public bool GetToolSupported(ToolboxItem tool) + { + MessageBox.Show("Reached GetToolSupported!"); + return false; + } + + public void ToolPicked(ToolboxItem tool) + { + MessageBox.Show("Reached ToolPicked!"); + } + + // IRootDesigner.SupportedTechnologies is a required override for an + // IRootDesigner. Default is the view technology used by this designer. + ViewTechnology[] IRootDesigner.SupportedTechnologies + { + get + { + return new ViewTechnology[] { ViewTechnology.Default }; + } + } + + public ToolboxItemCollection Items + { + get + { + MessageBox.Show("Reached Toolbox-Items requested!"); + return null; + } + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/ShapeDocument.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/ShapeDocument.cs new file mode 100644 index 0000000..a87e82b --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/ShapeDocument.cs @@ -0,0 +1,14 @@ +namespace SampleRootDesigner +{ + // This sample demonstrates how to provide the root designer view, or + // design mode background view, by overriding IRootDesigner.GetView(). + + // This sample component inherits from RootDesignedComponent which + // uses the SampleRootDesigner. + public class ShapeDocument : ShapeDocumentBase + { + public ShapeDocument() + { + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/AssemblyInfo.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9e27f4a --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RootDesignerSupportLib")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RootDesignerSupportLib")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("548cc959-438a-4bcb-9af3-d0f019f4c3bc")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/Resources.Designer.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/Resources.Designer.cs new file mode 100644 index 0000000..062994b --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/Resources.Designer.cs @@ -0,0 +1,93 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace RootDesignerDemo.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("RootDesignerDemo.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Line { + get { + object obj = ResourceManager.GetObject("Line", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Rectangle { + get { + object obj = ResourceManager.GetObject("Rectangle", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Text { + get { + object obj = ResourceManager.GetObject("Text", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/Resources.resx b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/Resources.resx new file mode 100644 index 0000000..f67fbfd --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Properties/Resources.resx @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Rectangle.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Line.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Text.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Resources/Line.bmp b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Resources/Line.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89280eb754cf7f26da6208599218eb883a44628d GIT binary patch literal 3382 zcmeIxF^<$w490P<#7I<#Be>)QTYH8Y&fue1TJ0U6b4kG=T)^xVDBZ3^L61h}znN*0 zJpxJei=W@Tr$k>er%(3>S&sWRA|DvNzqymQ*B`k4cy}dtG%rL(Bu0W7F+m^nL0?t# z_1pLP_56E84Gz|7qR=BIP#7G6M4?AqpfETBi9+A*t5kz8&mfW1LXV_CVQ>Tzg&rw^ z!r%xb3O&*Sg~1U>6nabq3WFn%DD;>L6b45iQRp!fC=8B3qR?Y5P#7G6M4`t*pfETB zi9(O1Kw)qM5``Wsfx_SjBnmy&0)@d5NEG_^zLje5>${hv7J5Pj3WFn%DD;F06b45i zQRoR5C=8B3qR`8C7NJywBakTcL<$rJM<7w?i4rIbjzFT&6D?2}9Dzikr-biZ6b45i zQRpcZC=8B3qR>+&P#7G6M4_i#pfETBi9%0>Kw)qM5`~^hfx_SjBnr)cRG=_80y%&F z&V2bSOP(S#vYf+UXR=T5p6PyiD1 zub#23+132|W@g{LzkjJ?-M^6D(!F_dr&o_BIDUQoNOufZ(n`5XYUU<$GADC)@2AgS z_S^R#D{}<+t`!=ya>3vTBnpjLgngCmeAG-f>ogCmeAG-ka7 zgCmeAG-ka8gCmeAG-iDSgCmeAH0J4k8`Tky_g+P9%%%wjM<7vX%%%$lM<7vX%w`A% zM<7vX%<-IM8r2a<6dJQxg253;6dJSHg253;6dJQRg253;6dJQFo^u%-fkdG(+a?$s zfkdG(+b$R!fkdG(+aVYnfkdG(+bI|vfkdG(+a(wrfkdG(yrY7_5lGbj{I&b>gN{6< zT^*mLIfiS4-OKNbKZKigx!er2*ZKJu|Hgc~!$0@?yxYHaM+oQPOyEr5OyEr5OyEr5 Hze?Z%xmw^v literal 0 HcmV?d00001 diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Resources/Text.bmp b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Resources/Text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a8e028ffafa412fbc0c98336f48c7cc7cef7ff9d GIT binary patch literal 3382 zcmeIyF^<$=42I!vC6K5PM{v0(*xI6pGx#Vz26QedID`uhLFpEWf*!5B?`B3*Y=w}h z$Uk~wTZv|VeM#p1hlkfX*2635p6=b%o!(qdaQyc6LU#<$q?K}&)XYuhWKQPp-p^mY z?)M)*SLO(CtrZ%xa>3vTBnpjLgngCmeAG-f>ogCmeAG-ka7 zgCmeAG-ka8gCmeAG-iDSgCmeAH0FB0jp~TYy;o5ivuT3C5l9pov+07t5l9povl)WH z5l9pob3A96Ms)-dg~n`_U~mKyg~n{QU~mKyg~n`-U~mKyg~n`)=UfIyAW>+{wh0DD zAW>+{whIPFAW>+{b_fPXAW>+{b_xbZAW>+{b_oVYAW>)x@2FsK1QNBse(!$zs3T8l zSI1{*j^Vk%?&BXX>2~SS{ base.DefaultCursor; + + public RootDesignerView(ShapeRootDesigner designer) + { + _designer = designer; + BackColor = Color.LightGray; + Font = new Font(Font.FontFamily.Name, 24.0f); + } + + protected override void OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + + _savedCursor = Cursor; + _designer.VsOutputWindowLogger.WriteLine($"View: MouseEnter"); + object toolboxItem = _designer.ToolboxService.GetSelectedToolboxItem(); + + if (toolboxItem is null) + { + toolboxItem = "No toolbox item selected."; + } + + if (_designer.ToolboxService.SetCursor()) + { + Cursor = Cursor.Current; + } + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + _designer.VsOutputWindowLogger.WriteLine($"View: MouseLeave"); + Cursor = _savedCursor; + } + + protected override void OnPaint(PaintEventArgs pe) + { + base.OnPaint(pe); + + // Draws the name of the component in large letters. + pe.Graphics.DrawString(_designer.Component.Site.Name, Font, Brushes.Black, ClientRectangle); + } + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/SampleRootDesigner.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/SampleRootDesigner.cs new file mode 100644 index 0000000..6f3b8d0 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/SampleRootDesigner.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; +using RootDesignerDemo; + +namespace SampleRootDesigner +{ + [ToolboxItemFilter(ToolboxCategory, ToolboxItemFilterType.Require)] + public partial class ShapeRootDesigner : ComponentDesigner, IRootDesigner, IToolboxUser + { + private const string ToolboxCategory = "ShapeRootDesigner"; + private const string VsOutputWindowPaneName = "Root Designer Demo"; + + private VsOutputWindowLogger _vsOutputWindowLogger = new VsOutputWindowLogger(VsOutputWindowPaneName); + + // Member field of custom type RootDesignerView, a control that + // will be shown in the Forms designer view. This member is + // cached to reduce processing needed to recreate the + // view control on each call to GetView(). + private RootDesignerView _designerSurface; + + private IToolboxService _toolboxService = null; + private ToolboxItemCollection _tools; + private ISelectionService _selectionService = null; + private IDesignerHost _designerHost = null; + + public override void Initialize(IComponent component) + { + base.Initialize(component); + _vsOutputWindowLogger.WriteLine($"ShapeRootDesigner.Initialize() for component {component.GetType().FullName} called."); + _selectionService = GetService(typeof(ISelectionService)) as ISelectionService; + if (!(_selectionService is null)) + { + _vsOutputWindowLogger.WriteLine($"ShapeRootDesigner.Initialize(): ISelectionService retrieved."); + } + + _designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost; + if (!(_designerHost is null)) + { + _vsOutputWindowLogger.WriteLine($"ShapeRootDesigner.Initialize(): IDesignerHost retrieved."); + } + + _toolboxService = GetService(typeof(IToolboxService)) as IToolboxService; + if (!(_toolboxService is null)) + { + _vsOutputWindowLogger.WriteLine($"ShapeRootDesigner.Initialize(): IToolboxService retrieved."); + } + } + + public ViewTechnology[] SupportedTechnologies => new[] { ViewTechnology.Default }; + + public bool GetToolSupported(ToolboxItem tool) + { + return !(tool.Properties[ToolboxCategory] is null); + } + + public void ToolPicked(ToolboxItem tool) + { + _vsOutputWindowLogger.WriteLine($"ToolPicked: {tool}"); + } + + // This method returns an instance of the view for this root + // designer. The "view" is the user interface that is presented + // in a document window for the user to manipulate. + object IRootDesigner.GetView(ViewTechnology technology) + { + if (technology != ViewTechnology.Default) + { + throw new ArgumentException("Not a supported view technology", "technology"); + } + + if (_designerSurface == null) + { + // Some type of displayable Form or control is required + // for a root designer that overrides GetView(). In this + // example, a Control of type RootDesignerView is used. + // Any class that inherits from Control will work. + _designerSurface = new RootDesignerView(this); + + _toolboxService = (IToolboxService)this.GetService(typeof(IToolboxService)); + // If an IToolboxService was located, update the + // category list. + if (_toolboxService is null) + { + MessageBox.Show("Couldn't retrieve Toolbox Service!"); + } + else + { + SetupToolboxItems(); + } + } + + return _designerSurface; + } + + private void SetupToolboxItems() + { + CreateToolboxItem("Line Tool", "LineTool", "ShapeRootDesigner", + RootDesignerDemo.Properties.Resources.Line); + CreateToolboxItem("Rectangle Tool", "RectangleTool", "ShapeRootDesigner", + RootDesignerDemo.Properties.Resources.Rectangle); + CreateToolboxItem("Text Tool", "TextTool", "ShapeRootDesigner", + RootDesignerDemo.Properties.Resources.Text); + } + + private void CreateToolboxItem(string toolDisplayName, string toolTypeName, string toolboxFilterString, Bitmap toolboxBitmap) + { + ToolboxItem toolboxItem; + ToolboxItemFilterAttribute toolboxItemFilterAttribute; + ToolboxItemFilterAttribute[] toolboxItemFilterAttributeArray; + + string toolboxItemName =$"{ToolboxCategory}.{toolTypeName}"; + + foreach (ToolboxItem existingToolboxItem in _toolboxService.GetToolboxItems(ToolboxCategory)) + { + if (existingToolboxItem.TypeName != toolboxItemName) + { + continue; + } + + // We found the item, so remove it... + _toolboxService.RemoveToolboxItem(existingToolboxItem); + break; + } + + // ...and add it again. + toolboxItem = new ToolboxItem() + { + TypeName = toolboxItemName, + DisplayName = toolDisplayName, + Description = $"Description of {toolDisplayName}", + Bitmap = toolboxBitmap + }; + + toolboxItemFilterAttribute = new ToolboxItemFilterAttribute(toolboxFilterString, ToolboxItemFilterType.Require); + toolboxItemFilterAttributeArray = new ToolboxItemFilterAttribute[] { toolboxItemFilterAttribute }; + toolboxItem.Filter = (ICollection)toolboxItemFilterAttributeArray; + toolboxItem.Properties[ToolboxCategory] = toolTypeName; + _toolboxService.AddToolboxItem(toolboxItem, ToolboxCategory); + + return; + } + + internal IToolboxService ToolboxService => _toolboxService; + internal IDesignerHost DesignerHost => _designerHost; + internal ISelectionService SelectionService => _selectionService; + internal VsOutputWindowLogger VsOutputWindowLogger => _vsOutputWindowLogger; + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/ShapeDocumentBase.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/ShapeDocumentBase.cs new file mode 100644 index 0000000..02e28c0 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/ShapeDocumentBase.cs @@ -0,0 +1,47 @@ +using System.ComponentModel; +using System.ComponentModel.Design; + +namespace SampleRootDesigner +{ + // The following attribute associates the SampleRootDesigner designer + // with the SampleComponent component. + [Designer(typeof(ShapeRootDesigner), typeof(IRootDesigner)), + ToolboxItem(false)] + public class ShapeDocumentBase : Component + { + private IToolboxServiceExample.IToolboxServiceControl iToolboxServiceControl1; + private RootDesignerDemo.HostingComponents.SimpleBoxComponent simpleBoxComponent1; + private System.Windows.Forms.Button button1; + private IContainer components; + + public ShapeDocumentBase() + { + } + + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.iToolboxServiceControl1 = new IToolboxServiceExample.IToolboxServiceControl(); + this.simpleBoxComponent1 = new RootDesignerDemo.HostingComponents.SimpleBoxComponent(this.components); + this.button1 = new System.Windows.Forms.Button(); + // + // iToolboxServiceControl1 + // + this.iToolboxServiceControl1.BackColor = System.Drawing.Color.Beige; + this.iToolboxServiceControl1.Location = new System.Drawing.Point(500, 400); + this.iToolboxServiceControl1.Name = "iToolboxServiceControl1"; + this.iToolboxServiceControl1.Size = new System.Drawing.Size(771, 432); + this.iToolboxServiceControl1.TabIndex = 0; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(0, 0); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 0; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/ShapeDocumentBase.resx b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/ShapeDocumentBase.resx new file mode 100644 index 0000000..8e8ff23 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesigner/ShapeDocumentBase.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 225, 291 + + + 849, 394 + + + 1434, 432 + + + True + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesignerSupportLib.csproj b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesignerSupportLib.csproj new file mode 100644 index 0000000..019f4e8 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesignerSupportLib.csproj @@ -0,0 +1,267 @@ + + + + + + Debug + AnyCPU + {548CC959-438A-4BCB-9AF3-D0F019F4C3BC} + Library + Properties + RootDesignerDemo + RootDesignerSupportLib + v4.7.2 + 512 + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\MessagePack.2.4.59\lib\netstandard2.0\MessagePack.dll + + + ..\packages\MessagePack.Annotations.2.4.59\lib\netstandard2.0\MessagePack.Annotations.dll + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + ..\packages\Microsoft.Build.Framework.17.3.1\lib\net472\Microsoft.Build.Framework.dll + + + ..\packages\Microsoft.IO.Redist.6.0.0\lib\net472\Microsoft.IO.Redist.dll + + + ..\packages\Microsoft.NET.StringTools.17.4.0\lib\net472\Microsoft.NET.StringTools.dll + + + ..\packages\Microsoft.ServiceHub.Framework.4.1.3102\lib\netstandard2.0\Microsoft.ServiceHub.Framework.dll + + + ..\packages\Microsoft.VisualStudio.GraphModel.17.5.33428.366\lib\net472\Microsoft.VisualStudio.GraphModel.dll + + + ..\packages\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.17.5.33428.366\lib\net472\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll + True + + + ..\packages\Microsoft.VisualStudio.Interop.17.5.33428.366\lib\net472\Microsoft.VisualStudio.Interop.dll + + + ..\packages\Microsoft.VisualStudio.RemoteControl.16.3.44\lib\net45\Microsoft.VisualStudio.RemoteControl.dll + + + ..\packages\Microsoft.VisualStudio.RpcContracts.17.5.21\lib\netstandard2.0\Microsoft.VisualStudio.RpcContracts.dll + + + ..\packages\Microsoft.VisualStudio.Shell.Framework.17.5.33428.388\lib\net472\Microsoft.VisualStudio.Shell.Framework.dll + + + ..\packages\Microsoft.VisualStudio.Shell.Interop.17.5.33428.366\lib\net472\Microsoft.VisualStudio.Shell.Interop.dll + + + ..\packages\Microsoft.VisualStudio.Telemetry.16.6.21\lib\net45\Microsoft.VisualStudio.Telemetry.dll + + + ..\packages\Microsoft.VisualStudio.Threading.17.5.21\lib\net472\Microsoft.VisualStudio.Threading.dll + + + ..\packages\Microsoft.VisualStudio.Utilities.17.5.33428.366\lib\net472\Microsoft.VisualStudio.Utilities.dll + + + ..\packages\Microsoft.VisualStudio.Utilities.Internal.16.3.38\lib\net45\Microsoft.VisualStudio.Utilities.Internal.dll + + + ..\packages\Microsoft.VisualStudio.Validation.17.0.65\lib\netstandard2.0\Microsoft.VisualStudio.Validation.dll + + + ..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll + + + ..\packages\Nerdbank.Streams.2.9.112\lib\netstandard2.0\Nerdbank.Streams.dll + + + + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\StreamJsonRpc.2.14.24\lib\netstandard2.0\StreamJsonRpc.dll + + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\packages\System.Collections.Immutable.6.0.0\lib\net461\System.Collections.Immutable.dll + + + + ..\packages\System.Composition.AttributedModel.6.0.0\lib\net461\System.Composition.AttributedModel.dll + + + ..\packages\System.Composition.Convention.6.0.0\lib\net461\System.Composition.Convention.dll + + + ..\packages\System.Composition.Hosting.6.0.0\lib\net461\System.Composition.Hosting.dll + + + ..\packages\System.Composition.Runtime.6.0.0\lib\net461\System.Composition.Runtime.dll + + + ..\packages\System.Composition.TypedParts.6.0.0\lib\net461\System.Composition.TypedParts.dll + + + + + + ..\packages\System.Diagnostics.DiagnosticSource.6.0.0\lib\net461\System.Diagnostics.DiagnosticSource.dll + + + + + ..\packages\System.IO.Pipelines.6.0.3\lib\net461\System.IO.Pipelines.dll + + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Security.AccessControl.6.0.0\lib\net461\System.Security.AccessControl.dll + + + ..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll + + + ..\packages\System.Text.Encodings.Web.6.0.0\lib\net461\System.Text.Encodings.Web.dll + + + ..\packages\System.Text.Json.6.0.0\lib\net461\System.Text.Json.dll + + + ..\packages\System.Threading.AccessControl.6.0.0\lib\net461\System.Threading.AccessControl.dll + + + ..\packages\System.Threading.Tasks.Dataflow.6.0.0\lib\net461\System.Threading.Tasks.Dataflow.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + + + + + + + + + + True + True + Resources.resx + + + Component + + + SimpleBoxComponent.cs + + + UserControl + + + + + + Component + + + Component + + + + + + + IToolboxServiceControl.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + ShapeDocumentBase.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ShapeComponents/SimpleBoxComponent.Designer.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ShapeComponents/SimpleBoxComponent.Designer.cs new file mode 100644 index 0000000..54ca929 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ShapeComponents/SimpleBoxComponent.Designer.cs @@ -0,0 +1,36 @@ +namespace RootDesignerDemo.HostingComponents +{ + partial class SimpleBoxComponent + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ShapeComponents/SimpleBoxComponent.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ShapeComponents/SimpleBoxComponent.cs new file mode 100644 index 0000000..0ac538c --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ShapeComponents/SimpleBoxComponent.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RootDesignerDemo.HostingComponents +{ + public partial class SimpleBoxComponent : Component + { + public SimpleBoxComponent() + { + InitializeComponent(); + } + + public SimpleBoxComponent(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/IToolboxServiceControl.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/IToolboxServiceControl.cs new file mode 100644 index 0000000..3f36d8c --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/IToolboxServiceControl.cs @@ -0,0 +1,208 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace IToolboxServiceExample +{ + // Provides an example control that functions in design mode to + // demonstrate use of the IToolboxService to list and select toolbox + // categories and items, and to add components or controls + // to the parent form using code. + [DesignerAttribute(typeof(WindowMessageDesigner), typeof(IDesigner))] + public class IToolboxServiceControl : System.Windows.Forms.UserControl + { + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.ListBox listBox2; + private IToolboxService toolboxService = null; + private ToolboxItemCollection tools; + private int controlSpacingMultiplier; + + public IToolboxServiceControl() + { + InitializeComponent(); + listBox2.DoubleClick += new EventHandler(this.CreateComponent); + controlSpacingMultiplier = 0; + } + + // Obtain or reset IToolboxService reference on each siting of control. + public override System.ComponentModel.ISite Site + { + get + { + return base.Site; + } + set + { + base.Site = value; + + // If the component was sited, attempt to obtain + // an IToolboxService instance. + if (base.Site != null) + { + toolboxService = (IToolboxService)this.GetService(typeof(IToolboxService)); + // If an IToolboxService was located, update the + // category list. + if (toolboxService != null) + UpdateLists(); + } + else + { + toolboxService = null; + } + } + } + + // Updates the list of categories and the list of items in the + // selected category. + private void UpdateLists() + { + if (toolboxService != null) + { + this.listBox1.SelectedIndexChanged -= new System.EventHandler(this.UpdateSelectedCategory); + this.listBox2.SelectedIndexChanged -= new System.EventHandler(this.UpdateSelectedItem); + listBox1.Items.Clear(); + for (int i = 0; i < toolboxService.CategoryNames.Count; i++) + { + listBox1.Items.Add(toolboxService.CategoryNames[i]); + if (toolboxService.CategoryNames[i] == toolboxService.SelectedCategory) + { + listBox1.SelectedIndex = i; + tools = toolboxService.GetToolboxItems(toolboxService.SelectedCategory); + listBox2.Items.Clear(); + for (int j = 0; j < tools.Count; j++) + listBox2.Items.Add(tools[j].DisplayName); + } + } + this.listBox1.SelectedIndexChanged += new System.EventHandler(this.UpdateSelectedCategory); + this.listBox2.SelectedIndexChanged += new System.EventHandler(this.UpdateSelectedItem); + } + } + + // Sets the selected category when a category is clicked in the + // category list. + private void UpdateSelectedCategory(object sender, System.EventArgs e) + { + if (toolboxService != null) + { + toolboxService.SelectedCategory = (string)listBox1.SelectedItem; + UpdateLists(); + } + } + + // Sets the selected item when an item is clicked in the item list. + private void UpdateSelectedItem(object sender, System.EventArgs e) + { + if (toolboxService != null) + { + if (listBox1.SelectedIndex != -1) + { + if ((string)listBox1.SelectedItem == toolboxService.SelectedCategory) + toolboxService.SetSelectedToolboxItem(tools[listBox2.SelectedIndex]); + else + UpdateLists(); + } + } + } + + // Creates a control from a double-clicked toolbox item and adds + // it to the parent form. + private void CreateComponent(object sender, EventArgs e) + { + // Obtains an IDesignerHost service from design environment. + IDesignerHost host = (IDesignerHost)this.GetService(typeof(IDesignerHost)); + + // Get the project components container (Windows Forms control + // containment depends on controls collections). + IContainer container = host.Container; + + // Identifies the parent Form. + System.Windows.Forms.Form parentForm = this.FindForm(); + + // Retrieves the parent Form's designer host. + IDesignerHost parentHost = (IDesignerHost)parentForm.Site.GetService(typeof(IDesignerHost)); + + // Create the components. + IComponent[] comps = null; + try + { + comps = toolboxService.GetSelectedToolboxItem().CreateComponents(parentHost); + } + catch (Exception ex) + { + // Catch and show any exceptions to prevent disabling + // the control's UI. + MessageBox.Show(ex.ToString(), "Exception message"); + } + if (comps == null) + return; + + // Add any created controls to the parent form's controls + // collection. Note: components are added from the + // ToolboxItem.CreateComponents(IDesignerHost) method. + for (int i = 0; i < comps.Length; i++) + { + if (parentForm != null && comps[i].GetType().IsSubclassOf(typeof(System.Windows.Forms.Control))) + { + ((System.Windows.Forms.Control)comps[i]).Location = new Point(20 * controlSpacingMultiplier, 20 * controlSpacingMultiplier); + if (controlSpacingMultiplier > 10) + controlSpacingMultiplier = 0; + else + controlSpacingMultiplier++; + parentForm.Controls.Add((System.Windows.Forms.Control)comps[i]); + } + } + } + + // Displays labels. + protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) + { + e.Graphics.DrawString("IToolboxService Control", new Font("Arial", 14), new SolidBrush(Color.Black), 6, 4); + e.Graphics.DrawString("Category List", new Font("Arial", 8), new SolidBrush(Color.Black), 8, 26); + e.Graphics.DrawString("Items in Category", new Font("Arial", 8), new SolidBrush(Color.Black), 208, 26); + e.Graphics.DrawString("(Double-click item to add to parent form)", new Font("Arial", 7), new SolidBrush(Color.Black), 232, 12); + } + + private void InitializeComponent() + { + this.listBox1 = new System.Windows.Forms.ListBox(); + this.listBox2 = new System.Windows.Forms.ListBox(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.listBox1.ItemHeight = 20; + this.listBox1.Location = new System.Drawing.Point(8, 41); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(192, 364); + this.listBox1.TabIndex = 0; + this.listBox1.SelectedIndexChanged += new System.EventHandler(this.UpdateSelectedCategory); + // + // listBox2 + // + this.listBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listBox2.ItemHeight = 20; + this.listBox2.Location = new System.Drawing.Point(208, 41); + this.listBox2.Name = "listBox2"; + this.listBox2.Size = new System.Drawing.Size(557, 364); + this.listBox2.TabIndex = 3; + // + // IToolboxServiceControl + // + this.BackColor = System.Drawing.Color.Beige; + this.Controls.Add(this.listBox2); + this.Controls.Add(this.listBox1); + this.Location = new System.Drawing.Point(500, 400); + this.Name = "IToolboxServiceControl"; + this.Size = new System.Drawing.Size(771, 432); + this.ResumeLayout(false); + + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/IToolboxServiceControl.resx b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/IToolboxServiceControl.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/IToolboxServiceControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/TextDataTextBoxComponent.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/TextDataTextBoxComponent.cs new file mode 100644 index 0000000..8b21447 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/ToolboxServiceDemo/TextDataTextBoxComponent.cs @@ -0,0 +1,157 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing.Design; +using System.Windows.Forms; + +namespace TextDataTextBoxComponent +{ + // Component that adds a "Text" data format ToolboxItemCreatorCallback + // to the Toolbox. This component uses a custom ToolboxItem that + // creates a TextBox containing the text data. + public class TextDataTextBoxComponent : Component + { + private bool creatorAdded = false; + private IToolboxService ts; + + public TextDataTextBoxComponent() + { + } + + // ISite override to register TextBox creator + public override System.ComponentModel.ISite Site + { + get + { + return base.Site; + } + set + { + if (value != null) + { + base.Site = value; + + if (!creatorAdded) + { + AddTextTextBoxCreator(); + } + } + else + { + if (creatorAdded) + { + RemoveTextTextBoxCreator(); + } + + base.Site = value; + } + } + } + + // Adds a "Text" data format creator to the toolbox that creates + // a textbox from a text fragment pasted to the toolbox. + private void AddTextTextBoxCreator() + { + ts = (IToolboxService)GetService(typeof(IToolboxService)); + + if (ts != null) + { + ToolboxItemCreatorCallback textCreator = + new ToolboxItemCreatorCallback(this.CreateTextBoxForText); + + try + { + ts.AddCreator( + textCreator, + "Text", + (IDesignerHost)GetService(typeof(IDesignerHost))); + + creatorAdded = true; + } + catch (Exception ex) + { + MessageBox.Show( + ex.ToString(), + "Exception Information"); + } + } + } + + // Removes any "Text" data format creator from the toolbox. + private void RemoveTextTextBoxCreator() + { + if (ts != null) + { + ts.RemoveCreator( + "Text", + (IDesignerHost)GetService(typeof(IDesignerHost))); + + creatorAdded = false; + } + } + + // ToolboxItemCreatorCallback delegate format method to create + // the toolbox item. + private ToolboxItem CreateTextBoxForText( + object serializedObject, + string format) + { + DataObject o = new DataObject((IDataObject)serializedObject); + + string[] formats = o.GetFormats(); + + if (o.GetDataPresent("System.String", true)) + { + string toolboxText = (string)(o.GetData("System.String", true)); + return (new TextToolboxItem(toolboxText)); + } + + return null; + } + + protected override void Dispose(bool disposing) + { + if (creatorAdded) + { + RemoveTextTextBoxCreator(); + } + } + } + + // Custom toolbox item creates a TextBox and sets its Text property + // to the constructor-specified text. + public class TextToolboxItem : ToolboxItem + { + private string text; + private delegate void SetTextMethodHandler(Control c, string text); + + public TextToolboxItem(string text) : base() + { + this.text = text; + } + + // ToolboxItem.CreateComponentsCore override to create the TextBox + // and link a method to set its Text property. + protected override IComponent[] CreateComponentsCore(IDesignerHost host) + { + System.Windows.Forms.TextBox textbox = + (TextBox)host.CreateComponent(typeof(TextBox)); + + // Because the designer resets the text of the textbox, use + // a SetTextMethodHandler to set the text to the value of + // the text data. + Control c = host.RootComponent as Control; + c.BeginInvoke( + new SetTextMethodHandler(OnSetText), + new object[] { textbox, text }); + + return new System.ComponentModel.IComponent[] { textbox }; + } + + // Method to set the text property of a TextBox after it is initialized. + private void OnSetText(Control c, string text) + { + c.Text = text; + } + } +} \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/VsOutputWindowLogger.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/VsOutputWindowLogger.cs new file mode 100644 index 0000000..3b2face --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/VsOutputWindowLogger.cs @@ -0,0 +1,30 @@ +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; + +namespace RootDesignerDemo +{ + internal class VsOutputWindowLogger + { + IVsOutputWindowPane _generalPane; + + public VsOutputWindowLogger(string outputPaneName) + { + ThreadHelper.ThrowIfNotOnUIThread(); + + // Get the output window + IVsOutputWindow outputWindow = ServiceProvider.GlobalProvider.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow; + + var generalPaneGuid = VSConstants.GUID_OutWindowGeneralPane; + outputWindow.CreatePane(ref generalPaneGuid, outputPaneName, 1, 1); + outputWindow.GetPane(ref generalPaneGuid, out _generalPane); + _generalPane.Activate(); + } + + public void WriteLine(string message) + { + ThreadHelper.ThrowIfNotOnUIThread(); + _ = _generalPane.OutputStringThreadSafe($"{message}\r\n"); + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/WindowMessageDesigner.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/WindowMessageDesigner.cs new file mode 100644 index 0000000..3fb87cf --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/WindowMessageDesigner.cs @@ -0,0 +1,21 @@ +using System.Windows.Forms.Design; + +namespace IToolboxServiceExample +{ + // This designer passes window messages to the controls at design time. + public class WindowMessageDesigner : ControlDesigner + { + public WindowMessageDesigner() + { + } + + // Window procedure override passes events to control. + protected override void WndProc(ref System.Windows.Forms.Message m) + { + if (m.HWnd == this.Control.Handle) + base.WndProc(ref m); + else + this.DefWndProc(ref m); + } + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/app.config b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/app.config new file mode 100644 index 0000000..c324813 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/app.config @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/packages.config b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/packages.config new file mode 100644 index 0000000..0f3e704 --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/packages.config @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets new file mode 100644 index 0000000..57f285a --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Samples/RootDesigner/Net/ClientServerSample/NuGet.config b/Samples/RootDesigner/Net/ClientServerSample/NuGet.config new file mode 100644 index 0000000..68668ff --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/NuGet.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Properties/Resources.Designer.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Properties/Resources.Designer.cs new file mode 100644 index 0000000..f440fe7 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Properties/Resources.Designer.cs @@ -0,0 +1,93 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace RootDesignerDemo.Client.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("RootDesignerDemo.Client.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Line { + get { + object obj = ResourceManager.GetObject("Line", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Rectangle { + get { + object obj = ResourceManager.GetObject("Rectangle", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Text { + get { + object obj = ResourceManager.GetObject("Text", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Properties/Resources.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Properties/Resources.resx new file mode 100644 index 0000000..dc7dbfa --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Properties/Resources.resx @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Rectangle.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Line.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Text.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Resources/Line.bmp b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Resources/Line.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89280eb754cf7f26da6208599218eb883a44628d GIT binary patch literal 3382 zcmeIxF^<$w490P<#7I<#Be>)QTYH8Y&fue1TJ0U6b4kG=T)^xVDBZ3^L61h}znN*0 zJpxJei=W@Tr$k>er%(3>S&sWRA|DvNzqymQ*B`k4cy}dtG%rL(Bu0W7F+m^nL0?t# z_1pLP_56E84Gz|7qR=BIP#7G6M4?AqpfETBi9+A*t5kz8&mfW1LXV_CVQ>Tzg&rw^ z!r%xb3O&*Sg~1U>6nabq3WFn%DD;>L6b45iQRp!fC=8B3qR?Y5P#7G6M4`t*pfETB zi9(O1Kw)qM5``Wsfx_SjBnmy&0)@d5NEG_^zLje5>${hv7J5Pj3WFn%DD;F06b45i zQRoR5C=8B3qR`8C7NJywBakTcL<$rJM<7w?i4rIbjzFT&6D?2}9Dzikr-biZ6b45i zQRpcZC=8B3qR>+&P#7G6M4_i#pfETBi9%0>Kw)qM5`~^hfx_SjBnr)cRG=_80y%&F z&V2bSOP(S#vYf+UXR=T5p6PyiD1 zub#23+132|W@g{LzkjJ?-M^6D(!F_dr&o_BIDUQoNOufZ(n`5XYUU<$GADC)@2AgS z_S^R#D{}<+t`!=ya>3vTBnpjLgngCmeAG-f>ogCmeAG-ka7 zgCmeAG-ka8gCmeAG-iDSgCmeAH0J4k8`Tky_g+P9%%%wjM<7vX%%%$lM<7vX%w`A% zM<7vX%<-IM8r2a<6dJQxg253;6dJSHg253;6dJQRg253;6dJQFo^u%-fkdG(+a?$s zfkdG(+b$R!fkdG(+aVYnfkdG(+bI|vfkdG(+a(wrfkdG(yrY7_5lGbj{I&b>gN{6< zT^*mLIfiS4-OKNbKZKigx!er2*ZKJu|Hgc~!$0@?yxYHaM+oQPOyEr5OyEr5OyEr5 Hze?Z%xmw^v literal 0 HcmV?d00001 diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Resources/Text.bmp b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/Resources/Text.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a8e028ffafa412fbc0c98336f48c7cc7cef7ff9d GIT binary patch literal 3382 zcmeIyF^<$=42I!vC6K5PM{v0(*xI6pGx#Vz26QedID`uhLFpEWf*!5B?`B3*Y=w}h z$Uk~wTZv|VeM#p1hlkfX*2635p6=b%o!(qdaQyc6LU#<$q?K}&)XYuhWKQPp-p^mY z?)M)*SLO(CtrZ%xa>3vTBnpjLgngCmeAG-f>ogCmeAG-ka7 zgCmeAG-ka8gCmeAG-iDSgCmeAH0FB0jp~TYy;o5ivuT3C5l9pov+07t5l9povl)WH z5l9pob3A96Ms)-dg~n`_U~mKyg~n{QU~mKyg~n`-U~mKyg~n`)=UfIyAW>+{wh0DD zAW>+{whIPFAW>+{b_fPXAW>+{b_xbZAW>+{b_oVYAW>)x@2FsK1QNBse(!$zs3T8l zSI1{*j^Vk%?&BXX>2~SS{ + + + net472 + true + 9.0 + enable + true + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs new file mode 100644 index 0000000..446408c --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs @@ -0,0 +1,97 @@ +using System.Collections; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Design; +using System.Windows.Forms; +using Microsoft.DotNet.DesignTools.Client.Designers; + +namespace RootDesignerDemo.Client.RootDesignerProxy +{ + [ToolboxItemFilter(ToolboxCategory, ToolboxItemFilterType.Require)] + public class ShapeRootProxyDesigner : RootComponentProxyDesigner, IToolboxUser + { + private const string ToolboxCategory = "SdkShapeRootDesigner"; + + private IToolboxService? _toolboxService = null; + private ToolboxItemCollection? _tools; + + public override void Initialize(IComponent component) + { + base.Initialize(component); + + _toolboxService = (IToolboxService?) GetService(typeof(IToolboxService)); + } + + private void SetupToolboxItems() + { + CreateToolboxItem("Line Tool", "LineTool", "ShapeRootDesigner", + RootDesignerDemo.Client.Properties.Resources.Line); + CreateToolboxItem("Rectangle Tool", "RectangleTool", "ShapeRootDesigner", + RootDesignerDemo.Client.Properties.Resources.Rectangle); + CreateToolboxItem("Text Tool", "TextTool", "ShapeRootDesigner", + RootDesignerDemo.Client.Properties.Resources.Text); + } + + private void CreateToolboxItem(string toolDisplayName, string toolTypeName, string toolboxFilterString, Bitmap toolboxBitmap) + { + ToolboxItem toolboxItem; + ToolboxItemFilterAttribute toolboxItemFilterAttribute; + ToolboxItemFilterAttribute[] toolboxItemFilterAttributeArray; + + string toolboxItemName = $"{ToolboxCategory}.{toolTypeName}"; + + foreach (ToolboxItem existingToolboxItem in _toolboxService.GetToolboxItems(ToolboxCategory)) + { + if (existingToolboxItem.TypeName != toolboxItemName) + { + continue; + } + + // We found the item, so remove it... + _toolboxService.RemoveToolboxItem(existingToolboxItem); + break; + } + + // ...and add it again. + toolboxItem = new ToolboxItem() + { + TypeName = toolboxItemName, + DisplayName = toolDisplayName, + Description = $"Description of {toolDisplayName}", + Bitmap = toolboxBitmap + }; + + toolboxItemFilterAttribute = new ToolboxItemFilterAttribute(toolboxFilterString, ToolboxItemFilterType.Require); + toolboxItemFilterAttributeArray = new ToolboxItemFilterAttribute[] { toolboxItemFilterAttribute }; + toolboxItem.Filter = (ICollection)toolboxItemFilterAttributeArray; + toolboxItem.Properties[ToolboxCategory] = toolTypeName; + _toolboxService.AddToolboxItem(toolboxItem, ToolboxCategory); + + return; + } + + bool IToolboxUser.GetToolSupported(ToolboxItem tool) + { + return !(tool.Properties[ToolboxCategory] is null); + } + + void IToolboxUser.ToolPicked(ToolboxItem tool) + { + } + + protected override void OnAfterGetView() + { + // If an IToolboxService was located, update the + // category list. + if (_toolboxService is null) + { + MessageBox.Show("Couldn't retrieve Toolbox Service!"); + } + else + { + SetupToolboxItems(); + } + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/CustomEnumClientVersion.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/CustomEnumClientVersion.cs new file mode 100644 index 0000000..ec590ce --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/CustomEnumClientVersion.cs @@ -0,0 +1,14 @@ +namespace RootDesignerDemo.Designer.Client +{ + /// + /// Mirror of the server-defined enum for the class + /// which makes up the RdControl's RdPropertyStore property. + /// + public enum CustomEnumClientVersion + { + FirstValue, + SecondValue, + ThirdValue, + FourthValue + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/ErrorProviderExtension.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/ErrorProviderExtension.cs new file mode 100644 index 0000000..a70308d --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/ErrorProviderExtension.cs @@ -0,0 +1,28 @@ +using System; +using System.Windows.Forms; + +namespace RootDesignerDemo.Designer.Client +{ + internal static class ErrorProviderExtension + { + /// + /// Marks the provided control as errored if the is not met. + /// + /// ErrorProvider component instance. + /// Control, on which the Error to set on if errorCondition is true. + /// Function delegate which checks the error condition. + /// Error text to be assigned in the error case. + /// true, if an error occured. + public static bool SetErrorOrNull(this ErrorProvider errorProvider, Control control, Func errorCondition, string errorText) + { + if (errorCondition()) + { + errorProvider.SetError(control, errorText); + return true; + } + + errorProvider.SetError(control, null); + return false; + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditor.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditor.cs new file mode 100644 index 0000000..8d1db63 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditor.cs @@ -0,0 +1,57 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing.Design; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace RootDesignerDemo.Designer.Client +{ + /// + /// The actual client-side implementation of the RdTypeEditor, which is called by + /// Visual Studio's Property Browser. + /// + public class RdTypeEditor : UITypeEditor + { + RdTypeEditorDialog? _customTypeEditorDialog; + + public override object? EditValue( + ITypeDescriptorContext context, + IServiceProvider provider, + object? value) + { + if (provider is null) + { + return value; + } + + var editorService = provider.GetRequiredService(); + var designerHost = provider.GetRequiredService(); + + // Value now holds the proxy of the RdPropertyStore object the user wants to edit. + var viewModelClient = RdTypeEditorVMClient.Create(provider, value); + + _customTypeEditorDialog ??= new RdTypeEditorDialog(provider, viewModelClient); + _customTypeEditorDialog.Context = context; + _customTypeEditorDialog.Host = designerHost; + + var dialogResult = editorService.ShowDialog(_customTypeEditorDialog); + if (dialogResult == DialogResult.OK) + { + // By now, the UI of the Editor has asked its (client-side) ViewModel + // to run the code which updates the property value. It passes the data to + // the server, which in turn updates the server-side ViewModel. + // When it's time to return the value from the client-side ViewModel back to the + // Property Browser (which has called the TypeEditor in the first place), the client-side + // ViewModel accesses its PropertyStore property, which in turn gets the required PropertyStore + // proxy object directly from the server-side ViewModel. + value = viewModelClient.PropertyStore; + } + + return value; + } + + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + => UITypeEditorEditStyle.Modal; + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.Designer.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.Designer.cs new file mode 100644 index 0000000..5f766c5 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.Designer.cs @@ -0,0 +1,240 @@ +namespace RootDesignerDemo.Designer.Client +{ + partial class RdTypeEditorDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this._mainTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); + this._customEnumValueLabel = new System.Windows.Forms.Label(); + this._listOfStringsLabel = new System.Windows.Forms.Label(); + this._dateCreatedLabel = new System.Windows.Forms.Label(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this._okButton = new System.Windows.Forms.Button(); + this._cancelButton = new System.Windows.Forms.Button(); + this._dateCreated = new System.Windows.Forms.DateTimePicker(); + this._customEnumValueListBox = new System.Windows.Forms.ComboBox(); + this._requiredIdLabel = new System.Windows.Forms.Label(); + this._requiredIdTextBox = new System.Windows.Forms.TextBox(); + this._listOfStringTextBox = new System.Windows.Forms.TextBox(); + this._errorProvider = new System.Windows.Forms.ErrorProvider(this.components); + this._mainTableLayoutPanel.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this._errorProvider)).BeginInit(); + this.SuspendLayout(); + // + // _mainTableLayoutPanel + // + this._mainTableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._mainTableLayoutPanel.ColumnCount = 3; + this._mainTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this._mainTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this._mainTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this._mainTableLayoutPanel.Controls.Add(this._customEnumValueLabel, 0, 3); + this._mainTableLayoutPanel.Controls.Add(this._listOfStringsLabel, 0, 2); + this._mainTableLayoutPanel.Controls.Add(this._dateCreatedLabel, 0, 1); + this._mainTableLayoutPanel.Controls.Add(this.flowLayoutPanel1, 2, 0); + this._mainTableLayoutPanel.Controls.Add(this._dateCreated, 1, 1); + this._mainTableLayoutPanel.Controls.Add(this._customEnumValueListBox, 1, 3); + this._mainTableLayoutPanel.Controls.Add(this._requiredIdLabel, 0, 0); + this._mainTableLayoutPanel.Controls.Add(this._requiredIdTextBox, 1, 0); + this._mainTableLayoutPanel.Controls.Add(this._listOfStringTextBox, 1, 2); + this._mainTableLayoutPanel.Location = new System.Drawing.Point(7, 6); + this._mainTableLayoutPanel.Margin = new System.Windows.Forms.Padding(2); + this._mainTableLayoutPanel.Name = "_mainTableLayoutPanel"; + this._mainTableLayoutPanel.RowCount = 2; + this._mainTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this._mainTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this._mainTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this._mainTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this._mainTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this._mainTableLayoutPanel.Size = new System.Drawing.Size(511, 264); + this._mainTableLayoutPanel.TabIndex = 0; + // + // _customEnumValueLabel + // + this._customEnumValueLabel.Anchor = System.Windows.Forms.AnchorStyles.Left; + this._customEnumValueLabel.AutoSize = true; + this._customEnumValueLabel.Location = new System.Drawing.Point(4, 243); + this._customEnumValueLabel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this._customEnumValueLabel.Name = "_customEnumValueLabel"; + this._customEnumValueLabel.Size = new System.Drawing.Size(104, 13); + this._customEnumValueLabel.TabIndex = 6; + this._customEnumValueLabel.Text = "Custom Enum value:"; + // + // _listOfStringsLabel + // + this._listOfStringsLabel.Anchor = System.Windows.Forms.AnchorStyles.Left; + this._listOfStringsLabel.AutoSize = true; + this._listOfStringsLabel.Location = new System.Drawing.Point(4, 139); + this._listOfStringsLabel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this._listOfStringsLabel.Name = "_listOfStringsLabel"; + this._listOfStringsLabel.Size = new System.Drawing.Size(73, 13); + this._listOfStringsLabel.TabIndex = 4; + this._listOfStringsLabel.Text = "List of Strings:"; + // + // _dateCreatedLabel + // + this._dateCreatedLabel.Anchor = System.Windows.Forms.AnchorStyles.Left; + this._dateCreatedLabel.AutoSize = true; + this._dateCreatedLabel.Location = new System.Drawing.Point(4, 35); + this._dateCreatedLabel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this._dateCreatedLabel.Name = "_dateCreatedLabel"; + this._dateCreatedLabel.Size = new System.Drawing.Size(72, 13); + this._dateCreatedLabel.TabIndex = 2; + this._dateCreatedLabel.Text = "Date created:"; + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.flowLayoutPanel1.AutoSize = true; + this.flowLayoutPanel1.Controls.Add(this._okButton); + this.flowLayoutPanel1.Controls.Add(this._cancelButton); + this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.flowLayoutPanel1.Location = new System.Drawing.Point(424, 2); + this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(11, 2, 2, 2); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this._mainTableLayoutPanel.SetRowSpan(this.flowLayoutPanel1, 5); + this.flowLayoutPanel1.Size = new System.Drawing.Size(85, 70); + this.flowLayoutPanel1.TabIndex = 0; + // + // _okButton + // + this._okButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this._okButton.Location = new System.Drawing.Point(2, 2); + this._okButton.Margin = new System.Windows.Forms.Padding(2); + this._okButton.Name = "_okButton"; + this._okButton.Size = new System.Drawing.Size(81, 28); + this._okButton.TabIndex = 0; + this._okButton.Text = "OK"; + this._okButton.UseVisualStyleBackColor = true; + // + // _cancelButton + // + this._cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this._cancelButton.Location = new System.Drawing.Point(2, 40); + this._cancelButton.Margin = new System.Windows.Forms.Padding(2, 8, 2, 2); + this._cancelButton.Name = "_cancelButton"; + this._cancelButton.Size = new System.Drawing.Size(81, 28); + this._cancelButton.TabIndex = 1; + this._cancelButton.Text = "Cancel"; + this._cancelButton.UseVisualStyleBackColor = true; + // + // _dateCreated + // + this._dateCreated.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this._dateCreated.Location = new System.Drawing.Point(116, 32); + this._dateCreated.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this._dateCreated.Name = "_dateCreated"; + this._dateCreated.Size = new System.Drawing.Size(293, 20); + this._dateCreated.TabIndex = 3; + // + // _customEnumValueListBox + // + this._customEnumValueListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this._customEnumValueListBox.FormattingEnabled = true; + this._customEnumValueListBox.Location = new System.Drawing.Point(116, 239); + this._customEnumValueListBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this._customEnumValueListBox.Name = "_customEnumValueListBox"; + this._customEnumValueListBox.Size = new System.Drawing.Size(293, 21); + this._customEnumValueListBox.TabIndex = 7; + // + // _requiredIdLabel + // + this._requiredIdLabel.Anchor = System.Windows.Forms.AnchorStyles.Left; + this._requiredIdLabel.AutoSize = true; + this._requiredIdLabel.Location = new System.Drawing.Point(4, 7); + this._requiredIdLabel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this._requiredIdLabel.Name = "_requiredIdLabel"; + this._requiredIdLabel.Size = new System.Drawing.Size(72, 13); + this._requiredIdLabel.TabIndex = 0; + this._requiredIdLabel.Text = "A required ID:"; + // + // _requiredIdTextBox + // + this._requiredIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this._requiredIdTextBox.Location = new System.Drawing.Point(116, 4); + this._requiredIdTextBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this._requiredIdTextBox.Name = "_requiredIdTextBox"; + this._requiredIdTextBox.Size = new System.Drawing.Size(293, 20); + this._requiredIdTextBox.TabIndex = 1; + // + // _listOfStringTextBox + // + this._listOfStringTextBox.AcceptsReturn = true; + this._listOfStringTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this._listOfStringTextBox.Location = new System.Drawing.Point(114, 58); + this._listOfStringTextBox.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this._listOfStringTextBox.Multiline = true; + this._listOfStringTextBox.Name = "_listOfStringTextBox"; + this._listOfStringTextBox.Size = new System.Drawing.Size(297, 175); + this._listOfStringTextBox.TabIndex = 5; + // + // _errorProvider + // + this._errorProvider.ContainerControl = this; + // + // RdTypeEditorDialog + // + this.AcceptButton = this._okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this._cancelButton; + this.ClientSize = new System.Drawing.Size(524, 273); + this.Controls.Add(this._mainTableLayoutPanel); + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "RdTypeEditorDialog"; + this.Text = "RdTypeEditorDialog"; + this._mainTableLayoutPanel.ResumeLayout(false); + this._mainTableLayoutPanel.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this._errorProvider)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel _mainTableLayoutPanel; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.Button _okButton; + private System.Windows.Forms.Button _cancelButton; + private System.Windows.Forms.Label _dateCreatedLabel; + private System.Windows.Forms.DateTimePicker _dateCreated; + private System.Windows.Forms.Label _listOfStringsLabel; + private System.Windows.Forms.Label _requiredIdLabel; + private System.Windows.Forms.Label _customEnumValueLabel; + private System.Windows.Forms.ComboBox _customEnumValueListBox; + private System.Windows.Forms.TextBox _requiredIdTextBox; + private System.Windows.Forms.TextBox _listOfStringTextBox; + private System.Windows.Forms.ErrorProvider _errorProvider; + } +} \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.cs new file mode 100644 index 0000000..f6d82ff --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.cs @@ -0,0 +1,109 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Linq; +using System.Windows.Forms; +using RootDesignerDemo.Protocol.DataTransport; + +namespace RootDesignerDemo.Designer.Client +{ + internal partial class RdTypeEditorDialog : Form + { + RdPropertyStoreData? _propertyStore; + + public RdTypeEditorDialog(IServiceProvider provider, RdTypeEditorVMClient viewModelClient) + { + InitializeComponent(); + + Provider = provider; + ViewModelClient = viewModelClient; + + // Fill the Enum Combobox with the enum values. + _customEnumValueListBox.Items.AddRange( + Enum.GetValues(typeof(CustomEnumClientVersion)) + .Cast() + .Select(enumValue => enumValue.ToString()) + .ToArray()); + + _customEnumValueListBox.SelectedIndex = 0; + + // Fill the Form with the values. + PropertyStoreData = ViewModelClient.PropertyStoreData; + } + + public IServiceProvider? Provider { get; } + public RdTypeEditorVMClient ViewModelClient { get; set; } + public ITypeDescriptorContext? Context { get; set; } + public IDesignerHost? Host { get; set; } + + public RdPropertyStoreData? PropertyStoreData + { + get => _propertyStore; + + set + { + _requiredIdTextBox.Text = value?.SomeMustHaveId; + _dateCreated.Value = value?.DateCreated ?? DateTime.Now.Date; + _listOfStringTextBox.Lines = value?.ListOfStrings; + _customEnumValueListBox.SelectedIndex = value?.CustomEnumValue ?? 0; + } + } + + // Question: "How does this dialog ever get closed?" + // In this dialog, the OK button is set as the Form's accept button, + // the Cancel button is set as the Form's cancel button. + // The OK button's DialogResult is set to OK. + // Now, assigning a DialogResult value to a modal Form's DialogResult property + // automatically also causes OnValidating to run, and if its CancelEventArgs + // are not actually cancelled, the modal Form closes automatically. + // There is no need to write any code for that, expect for validating the user input. + // So, we neither need to handle the OK click event, nor Cancel click. + protected override void OnFormClosed(FormClosedEventArgs e) + { + base.OnFormClosed(e); + + if (DialogResult == DialogResult.OK) + { + ViewModelClient.ExecuteOkCommand(); + } + } + + protected override void OnFormClosing(FormClosingEventArgs e) + { + base.OnFormClosing(e); + e.Cancel = FormValidating(); + } + + private bool FormValidating() + { + // If the user doesn't click OK but cancels then we dont validate but return false. + // In this case, the existing content of _propertyStore stays current. + if (DialogResult != DialogResult.OK) + return false; + + bool validationFailed = false; + + validationFailed |= _errorProvider.SetErrorOrNull( + control: _requiredIdTextBox, + errorCondition: () => string.IsNullOrWhiteSpace(_requiredIdTextBox.Text), + errorText: "Please enter some valid ID value (alphanumerical)."); + + validationFailed |= _errorProvider.SetErrorOrNull( + control: _dateCreated, + errorCondition: () => _dateCreated.Value > DateTime.Now, + errorText: "Date can't be in the future."); + + _propertyStore = validationFailed + ? null + : (new( + _requiredIdTextBox.Text, + _dateCreated.Value, + _listOfStringTextBox.Lines, + (byte)_customEnumValueListBox.SelectedIndex)); + + ViewModelClient.PropertyStoreData = _propertyStore; + + return validationFailed; + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.resx new file mode 100644 index 0000000..91f6789 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorDialog.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorVMClient.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorVMClient.cs new file mode 100644 index 0000000..50aad03 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeEditor/RdTypeEditorVMClient.cs @@ -0,0 +1,92 @@ +using System; +using RootDesignerDemo.Protocol; +using RootDesignerDemo.Protocol.DataTransport; +using RootDesignerDemo.Protocol.Endpoints; +using Microsoft.DotNet.DesignTools.Client; +using Microsoft.DotNet.DesignTools.Client.Proxies; +using Microsoft.DotNet.DesignTools.Client.Views; + +namespace RootDesignerDemo.Designer.Client +{ + /// + /// Client-side implementation of the ViewModel to control the TypeEditor UI. + /// + internal class RdTypeEditorVMClient : ViewModelClient + { + [ExportViewModelClientFactory(ViewModelNames.RdTypeEditorVM)] + private class Factory : ViewModelClientFactory + { + protected override RdTypeEditorVMClient CreateViewModelClient(ObjectProxy? viewModel) + => new(viewModel); + } + + public RdTypeEditorVMClient(ObjectProxy? viewModel) : base(viewModel) + { + if (viewModel is null) + { + throw new ArgumentNullException(nameof(viewModel)); + } + } + + /// + /// Creates an instance of this VMClient and initializes it with the server types + /// from which the data sources can be generated. + /// + /// + /// The designer session to create the VMClient server side. + /// + /// + /// The VMClient for controlling the TypeEditor dialog. + /// + public static RdTypeEditorVMClient Create( + IServiceProvider provider, + object? customPropertyStoreProxy) + { + var session = provider.GetRequiredService(); + var client = provider.GetRequiredService(); + + var response = client.SendRequest( + new CreateRdTypeEditorVMRequest( + session.Id, + customPropertyStoreProxy)); + + var viewModel = (ObjectProxy)response.ViewModel!; + + var clientViewModel = provider.CreateViewModelClient(viewModel); + clientViewModel.Initialize(response.PropertyStoreData); + + return clientViewModel; + } + + private void Initialize(RdPropertyStoreData? propertyStoreData) + { + PropertyStoreData = propertyStoreData; + } + + // Executes the OK Command when the user has clicked the OK button: + // It takes the _propertyStoreData, sends it to the Server along with the ViewModelProxy, + // so the server process can access it. The server process then creates the actual PropertyStore object + // from the passed data (remember: the client cannot do that, since it doesn't know about the + // RdPropertyStore type which only exists server-side!) and stores it in its PropertyStore property. + // Now, when the TypeEditor continues with the codeflow in EditValue, it gets the updated value to return to + // the property grid from this client-side ViewModel, namely from its PropertyStore property. This property + // in turn uses the ViewModelProxy to call the server and get the Proxy of the value from the server-side + // ViewModel, which our OKClickHandler has _just_ updated server-side and is therefore up-to-date. + internal void ExecuteOkCommand() + { + Client!.SendRequest(new RdTypeEditorOKClickRequest(ViewModelProxy, PropertyStoreData)); + } + + // Get, when the TypeEditor's UI need to be update its controls to show the content of the custom property. + // Set, when the validation of the data passed, which was just entered by the User. + internal RdPropertyStoreData? PropertyStoreData { get; set; } + + /// + /// Returns the Proxy of the server-side ViewModel's PropertyStore property. + /// + public Object? PropertyStore + + // See also comment on ExecuteOKCommand. + => ViewModelProxy!.GetPropertyValue(nameof(PropertyStore)); + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeRoutingProvider.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeRoutingProvider.cs new file mode 100644 index 0000000..3367624 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/TypeRoutingProvider.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using Microsoft.DotNet.DesignTools.Client.TypeRouting; +using RootDesignerDemo.Client.RootDesignerProxy; +using RootDesignerDemo.Designer.Client; +using RootDesignerDemo.Protocol; + +namespace RootDesignerDemo.Designer.Server +{ + /// + /// Class holding the TypeRoutings for resolving the control designer type on the client. + /// + [ExportTypeRoutingDefinitionProvider] + internal class TypeRoutingProvider : TypeRoutingDefinitionProvider + { + public override IEnumerable GetDefinitions() + { + return new[] + { + new TypeRoutingDefinition( + TypeRoutingKinds.Editor, + nameof(EditorNames.RdTypeEditor), + typeof(RdTypeEditor)), + + new TypeRoutingDefinition( + TypeRoutingKinds.Designer, + nameof(DesignerNames.ShapeRootDesigner), + typeof(ShapeRootProxyDesigner)), + }; + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdControl.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdControl.cs new file mode 100644 index 0000000..9b7fdd8 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdControl.cs @@ -0,0 +1,128 @@ +using System.ComponentModel; +using System.Text; + +namespace RootDesignerDemo.Controls +{ + /// + /// Custom Control sample implementation. + /// + /// + /// This sample custom control implements one custom property named + /// of type . Its sole purpose is to demonstrate how to implement + /// a custom TypeEditor for editing this property's content at design time with the out-of-process + /// WinForms Designer. + /// + [Designer("RdControlDesigner")] + public class RdControl : Control + { + // Backing field for CustomProperty. + private RdPropertyStore? _customPropertyStoreProperty; + + /// + /// Occurs when the RdPropertyStoreProperty changes. + /// + public event EventHandler? RdPropertyStorePropertyChanged; + + public RdControl() + { + DoubleBuffered = true; + ResizeRedraw = true; + } + + /// + /// Gets or sets a value of type which is composed of different value types, + /// a custom enum and a string array. + /// + [Description("A custom property composed of different value types, a custom enum and a string array."), + DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public RdPropertyStore? RdPropertyStoreProperty + { + get => _customPropertyStoreProperty; + + set + { + if (!Equals(value, _customPropertyStoreProperty)) + { + _customPropertyStoreProperty = value; + OnRdPropertyStoreProperty(EventArgs.Empty); + + // We update this property only at design-time, not at runtime. + if (IsHandleCreated && IsAncestorSiteInDesignMode) + { + Invalidate(); + } + } + } + } + + /// + /// Raises the event. + /// + protected virtual void OnRdPropertyStoreProperty(EventArgs e) + => RdPropertyStorePropertyChanged?.Invoke(this, e); + + /// + /// Resets the . + /// + private void ResetRdPropertyStoreProperty() + => RdPropertyStoreProperty = null; + + /// + /// Indicates whether the property should be persisted. + /// + /// + /// if the CodeDOM serializer should emit code for + /// assigning a valid content to the property in InitializeComponent. + /// + private bool ShouldSerializeRdPropertyStoreProperty() + => RdPropertyStoreProperty is not null; + + // The only function of this control is to draw a visual + // representation of the RdPropertyStoreProperty at Design and Runtime. + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + // We show this only at Design time, not at runtime. + if (IsAncestorSiteInDesignMode) + { + + // Drawing a frame around the control's borders: + var pen = new Pen(ForeColor); + var brush = new SolidBrush(ForeColor); + + // Drawing the contents of the CustomProperty. + e.Graphics.DrawString( + BuildContentString(RdPropertyStoreProperty), + Font, + brush, + point: new(10, 10)); + + // Builds a long string with the text representation of + // the RdPropertyStoreProperty property of this control. + string BuildContentString(RdPropertyStore? propertyData) + { + StringBuilder stringBuilder = new(); + + if (propertyData is null) + { + stringBuilder.Append("No CustomProperty Data defined."); + return stringBuilder.ToString(); + } + + stringBuilder.AppendLine($"{nameof(propertyData.SomeMustHaveId)}: {propertyData.SomeMustHaveId}"); + stringBuilder.AppendLine($"{nameof(propertyData.DateCreated)}: {propertyData.DateCreated:yyyy-mm-dd (ddd)}"); + stringBuilder.AppendLine($"{nameof(propertyData.CustomEnumValue)}: '{propertyData.CustomEnumValue}'"); + stringBuilder.AppendLine(); + stringBuilder.AppendLine("List of Strings:"); + stringBuilder.AppendLine("============================="); + + propertyData.ListOfStrings?.ForEach( + stringValue => stringBuilder.AppendLine($"* {stringValue}")); + + return stringBuilder.ToString(); + } + } + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdPropertyStore.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdPropertyStore.cs new file mode 100644 index 0000000..a35b14c --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdPropertyStore.cs @@ -0,0 +1,55 @@ +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Drawing.Design; + +namespace RootDesignerDemo.Controls +{ + /// + /// An example for a custom type used by a property of a custom control. + /// + /// + /// Since this type is composed from different sub types, there is no editor out of the box to enter data in a + /// meaningful way when we are editing the value at design-time from within the property grid. That is the + /// reason we need a dedicated editor (RdTypeEditor) deriving from which does + /// that job. + /// Note for CodeDom serialization: since this is a complex type, serializing a property of this type in the + /// custom control won't produce the correct code in the InitializeComponent method. Therefore, we need a + /// custom serializer. Since we cannot refer to the types directly, we need to refer to them as full qualified names + /// and pass them to the as strings. + /// The custom CodeDom serializer should by default be placed in the same assembly as the custom control's designer. + /// + [DesignerSerializer("RootDesignerDemo.Designer.Server.Serialization.RdPropertyStoreCodeDomSerializer", + "Microsoft.DotNet.DesignTools.Serialization.CodeDomSerializer")] + [Editor("RdTypeEditor", typeof(UITypeEditor))] + public class RdPropertyStore + { + // We need the default constructor for the CodeDom serializer. + public RdPropertyStore() + { + SomeMustHaveId = Guid.NewGuid().ToString(); + } + + public RdPropertyStore( + string someMustHaveId, + DateTime dateCreated, + List? listOfStrings, + RdPropertyStoreEnum customEnumValue) + { + SomeMustHaveId = someMustHaveId; + DateCreated = dateCreated; + ListOfStrings = listOfStrings; + CustomEnumValue = customEnumValue; + } + + public string SomeMustHaveId { get; set; } + public DateTime DateCreated { get; set; } + public List? ListOfStrings { get; set; } + public RdPropertyStoreEnum CustomEnumValue { get; set; } + + public override string ToString() + => $"{nameof(SomeMustHaveId)}: {SomeMustHaveId}" + + $"{nameof(DateCreated)}: {DateCreated:yyyy-MM-dd HH:mm}" + + $"{nameof(CustomEnumValue)}: {CustomEnumValue}" + + $"{(ListOfStrings is null ? "No" : ListOfStrings?.Count ?? 0)} strings in list defined."; + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdPropertyStoreEnum.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdPropertyStoreEnum.cs new file mode 100644 index 0000000..146fba7 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdPropertyStoreEnum.cs @@ -0,0 +1,13 @@ +namespace RootDesignerDemo.Controls +{ + /// + /// Custom enum used in . + /// + public enum RdPropertyStoreEnum + { + FirstValue, + SecondValue, + ThirdValue, + FourthValue + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RootDesignerDemo.Controls.csproj b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RootDesignerDemo.Controls.csproj new file mode 100644 index 0000000..879defe --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RootDesignerDemo.Controls.csproj @@ -0,0 +1,16 @@ + + + + net6.0-windows + enable + true + enable + + + + + Component + + + + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeDocumentBase.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeDocumentBase.cs new file mode 100644 index 0000000..6d33c35 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeDocumentBase.cs @@ -0,0 +1,19 @@ +using System.ComponentModel; +using System.ComponentModel.Design; + +namespace RootDesignerDemo.Designer.Server; + +// The following attribute associates the SampleRootDesigner designer +// with the SampleComponent component. +[Designer("ShapeRootDesigner", typeof(IRootDesigner)), + ToolboxItem(false)] +public class ShapeDocumentBase : Component +{ + public ShapeDocumentBase() + { + } + + private void InitializeComponent() + { + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeDocumentBase.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeDocumentBase.resx new file mode 100644 index 0000000..e5858cc --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeDocumentBase.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Package/RootDesignerDemo.Package.csproj b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Package/RootDesignerDemo.Package.csproj new file mode 100644 index 0000000..c272472 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Package/RootDesignerDemo.Package.csproj @@ -0,0 +1,39 @@ + + + + net6.0 + false + false + true + https://github.com/dotnet/winforms-designer + git + $(TargetsForTfmSpecificContentInPackage);_GetFilesToPackage + Always + $([System.DateTime]::Now.ToString("1.yM.dHmm")) + $([System.DateTime]::Now.ToString("yyyy.MM.dd.HHmm")) + + + + + <_File Include="$(SolutionDir)\RootDesignerDemo.Controls\bin\$(Configuration)\net6.0-windows\RootDesignerDemo.Controls.dll" /> + + + <_File Include="$(SolutionDir)\RootDesignerDemo.Controls\bin\$(Configuration)\net6.0-windows\RootDesignerDemo.Controls.pdb" /> + + <_File Include="$(SolutionDir)\RootDesignerDemo.Client\bin\$(Configuration)\net472\RootDesignerDemo.Client.dll" TargetDir="Design/WinForms" /> + <_File Include="$(SolutionDir)\RootDesignerDemo.Protocol\bin\$(Configuration)\net472\RootDesignerDemo.Protocol.dll" TargetDir="Design/WinForms" /> + <_File Include="$(SolutionDir)\RootDesignerDemo.Server\bin\$(Configuration)\net6.0-windows\RootDesignerDemo.Server.dll" TargetDir="Design/WinForms/Server" /> + <_File Include="$(SolutionDir)\RootDesignerDemo.Protocol\bin\$(Configuration)\net6.0-windows\RootDesignerDemo.Protocol.dll" TargetDir="Design/WinForms/Server" /> + + + + + + + + + + + + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/DataTransport/RdPropertyStoreData.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/DataTransport/RdPropertyStoreData.cs new file mode 100644 index 0000000..54bf475 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/DataTransport/RdPropertyStoreData.cs @@ -0,0 +1,69 @@ +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using Microsoft.DotNet.DesignTools.Protocol.DataPipe; + +namespace RootDesignerDemo.Protocol.DataTransport +{ + /// + /// Transport class to carry the content of the RdPropertyStore + /// from the DesignToolServer's server process to the client (Visual Studio) + /// and back. + /// + [DebuggerDisplay("{" + nameof(GetDebuggerDisplay) + "(),nq}")] + public partial class RdPropertyStoreData : IDataPipeObject + { + [AllowNull] + public string SomeMustHaveId { get; private set; } + + public DateTime DateCreated { get; private set; } + public string[]? ListOfStrings { get; private set; } + public byte CustomEnumValue { get; private set; } + + public RdPropertyStoreData() + { + } + + public RdPropertyStoreData( + string someMustHaveId, + DateTime dateCreated, + string[]? listOfStrings, + byte customEnumValue) + { + // We use this extension method here, which works also for .NET Framework and + // lower than .NET 7 versions; it's defined in GlobalUtilities.cs. + SomeMustHaveId = someMustHaveId.OrThrowIfArgumentIsNullOrEmpty(); + DateCreated = dateCreated; + ListOfStrings = listOfStrings; + CustomEnumValue = customEnumValue; + } + + public void ReadProperties(IDataPipeReader reader) + { + SomeMustHaveId = reader.ReadString(nameof(SomeMustHaveId)); + DateCreated = reader.ReadDateTimeOrDefault(nameof(DateCreated)); + + ListOfStrings = reader.ReadArrayOrNull( + nameof(ListOfStrings), + (reader) => reader.ReadString()!); + + CustomEnumValue = reader.ReadByte(nameof(CustomEnumValue)); + } + + public void WriteProperties(IDataPipeWriter writer) + { + writer.Write(nameof(SomeMustHaveId), SomeMustHaveId); + writer.WriteIfNotDefault(nameof(DateCreated), DateCreated); + + writer.WriteArrayIfNotNull( + nameof(ListOfStrings), + ListOfStrings, + (writer, value) => writer.Write(value)); + + writer.Write(nameof(CustomEnumValue), CustomEnumValue); + } + + private string GetDebuggerDisplay() + => $"ID: {SomeMustHaveId}; {nameof(DateCreated)}: {DateCreated}"; + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/EditorNames.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/EditorNames.cs new file mode 100644 index 0000000..7c0b346 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/EditorNames.cs @@ -0,0 +1,15 @@ +namespace RootDesignerDemo.Protocol +{ + /// + /// Static class for holding the names of all custom type editors to provide IntelliSense support. + /// + public static class EditorNames + { + public static readonly string RdTypeEditor = nameof(RdTypeEditor); + } + + public static class DesignerNames + { + public static readonly string ShapeRootDesigner = "RootDesignerDemo.Designer.Server.ShapeRootDesigner"; + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/EndpointNames.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/EndpointNames.cs new file mode 100644 index 0000000..70b6450 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/EndpointNames.cs @@ -0,0 +1,11 @@ +namespace RootDesignerDemo.Protocol +{ + /// + /// Static class for holding the names of all endpoints to provide IntelliSense support. + /// + public static class EndpointNames + { + public const string CreateRdTypeEditorVM = nameof(CreateRdTypeEditorVM); + public const string RdTypeEditorEditorOKClick = nameof(RdTypeEditorEditorOKClick); + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMEndpoint.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMEndpoint.cs new file mode 100644 index 0000000..d05c8b1 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMEndpoint.cs @@ -0,0 +1,35 @@ +using System.Composition; +using Microsoft.DotNet.DesignTools.Protocol.DataPipe; +using Microsoft.DotNet.DesignTools.Protocol.Endpoints; + +namespace RootDesignerDemo.Protocol.Endpoints +{ + /// + /// Endpoint for the method to create the RdTypeEditor's ViewModel. + /// + /// + /// 'ViewModel' in this context is a class which holds the logic/properties to control the UI. There is a + /// server-side and a client-side part of that view model. The server-side provides the logic based on the actual + /// types of RdTypeEditor, running in the context of the custom control's TFM. It communicates to the + /// client-side view model, which then controls the client-side hosted UI, running in the context of + /// Visual Studio. + /// For every endpoint there is a request class and a response class for transporting the necessary data + /// to the respective context. There is also an additional endpoint handler, which holds the code that executes the actual + /// functionality of that endpoint. Request and response are located in the communications assembly; the actual handler is + /// part of the server-side implementation of the RdControl, along with the actual control designer and the + /// server-side view model. + /// + [Shared] + [ExportEndpoint] + public class CreateRdTypeEditorVMEndpoint + : Endpoint + { + public override string Name => EndpointNames.CreateRdTypeEditorVM; + + protected override CreateRdTypeEditorVMRequest CreateRequest(IDataPipeReader reader) + => new(reader); + + protected override CreateRdTypeEditorVMResponse CreateResponse(IDataPipeReader reader) + => new(reader); + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMRequest.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMRequest.cs new file mode 100644 index 0000000..662beea --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMRequest.cs @@ -0,0 +1,38 @@ +using Microsoft.DotNet.DesignTools.Protocol; +using Microsoft.DotNet.DesignTools.Protocol.DataPipe; +using Microsoft.DotNet.DesignTools.Protocol.Endpoints; + +namespace RootDesignerDemo.Protocol.Endpoints +{ + /// + /// Request class for the . This passes the necessary + /// context (SessionId, proxy of the RdControl) from the client to the server. + /// + public class CreateRdTypeEditorVMRequest : Request + { + public SessionId SessionId { get; private set; } + public object? RdControlProxy { get; private set; } + + public CreateRdTypeEditorVMRequest() { } + + public CreateRdTypeEditorVMRequest(SessionId sessionId, object? customControlProxy) + { + SessionId = sessionId.OrThrowIfArgumentIsNull(); + RdControlProxy = customControlProxy; + } + + public CreateRdTypeEditorVMRequest(IDataPipeReader reader) : base(reader) { } + + protected override void ReadProperties(IDataPipeReader reader) + { + SessionId = reader.ReadSessionId(nameof(SessionId)); + RdControlProxy = reader.ReadObject(nameof(RdControlProxy)); + } + + protected override void WriteProperties(IDataPipeWriter writer) + { + writer.Write(nameof(SessionId), SessionId); + writer.WriteObject(nameof(RdControlProxy), RdControlProxy); + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMResponse.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMResponse.cs new file mode 100644 index 0000000..9b3e978 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/CreateRdTypeEditorVMResponse.cs @@ -0,0 +1,44 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using RootDesignerDemo.Protocol.DataTransport; +using Microsoft.DotNet.DesignTools.Protocol.DataPipe; +using Microsoft.DotNet.DesignTools.Protocol.Endpoints; + +namespace RootDesignerDemo.Protocol.Endpoints +{ + /// + /// Response class, answering the request for that endpoint. This transports the requested data (Proxy of + /// the server-side ViewModel and the data of the custom property type PropertyStore) back to the client. + /// + public class CreateRdTypeEditorVMResponse : Response + { + [AllowNull] + public object ViewModel { get; private set; } + + public RdPropertyStoreData? PropertyStoreData { get; set; } + + public CreateRdTypeEditorVMResponse() { } + + public CreateRdTypeEditorVMResponse( + object viewModel, + RdPropertyStoreData? propertyStoreData) + { + ViewModel = viewModel ?? throw new ArgumentNullException(nameof(viewModel)); + PropertyStoreData = propertyStoreData; + } + + public CreateRdTypeEditorVMResponse(IDataPipeReader reader) : base(reader) { } + + protected override void ReadProperties(IDataPipeReader reader) + { + ViewModel = reader.ReadObject(nameof(ViewModel)); + PropertyStoreData = reader.ReadDataPipeObjectOrNull(nameof(PropertyStoreData)); + } + + protected override void WriteProperties(IDataPipeWriter writer) + { + writer.WriteObject(nameof(ViewModel), ViewModel); + writer.WriteDataPipeObjectIfNotNull(nameof(PropertyStoreData), PropertyStoreData!); + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickEndpoint.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickEndpoint.cs new file mode 100644 index 0000000..9bd8883 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickEndpoint.cs @@ -0,0 +1,22 @@ +using System.Composition; +using Microsoft.DotNet.DesignTools.Protocol.DataPipe; +using Microsoft.DotNet.DesignTools.Protocol.Endpoints; + +namespace RootDesignerDemo.Protocol.Endpoints +{ + /// + /// Endpoint to handle the event when the user clicks the OK button of the custom type editor. + /// + [Shared] + [ExportEndpoint] + public class RdTypeEditorOKClickEndpoint : Endpoint + { + public override string Name => EndpointNames.RdTypeEditorEditorOKClick; + + protected override RdTypeEditorOKClickRequest CreateRequest(IDataPipeReader reader) + => new(reader); + + protected override RdTypeEditorOKClickResponse CreateResponse(IDataPipeReader reader) + => new(reader); + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickRequest.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickRequest.cs new file mode 100644 index 0000000..6f6b253 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickRequest.cs @@ -0,0 +1,44 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using RootDesignerDemo.Protocol.DataTransport; +using Microsoft.DotNet.DesignTools.Protocol.DataPipe; +using Microsoft.DotNet.DesignTools.Protocol.Endpoints; + +namespace RootDesignerDemo.Protocol.Endpoints +{ + /// + /// Request class for the endpoint. This passes the necessary + /// context (ViewModel, content of custom property) from the Client to the Server. + /// + public class RdTypeEditorOKClickRequest : Request + { + [AllowNull] + public object ViewModel { get; private set; } + + [AllowNull] + public RdPropertyStoreData PropertyStoreData { get; private set; } + + public RdTypeEditorOKClickRequest(object? viewModel, RdPropertyStoreData? propertyStoreData) + { + ViewModel = viewModel ?? throw new ArgumentNullException(nameof(viewModel)); + PropertyStoreData = propertyStoreData; + } + + public RdTypeEditorOKClickRequest(IDataPipeReader reader) + : base(reader) + { + } + + protected override void ReadProperties(IDataPipeReader reader) + { + ViewModel = reader.ReadObject(nameof(ViewModel)); + PropertyStoreData = reader.ReadDataPipeObjectOrNull(nameof(PropertyStoreData)); + } + + protected override void WriteProperties(IDataPipeWriter writer) + { + writer.WriteObject(nameof(ViewModel), ViewModel); + writer.WriteDataPipeObjectIfNotNull(nameof(PropertyStoreData), PropertyStoreData); + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickResponse.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickResponse.cs new file mode 100644 index 0000000..88f971d --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/Endpoints/RdTypeEditorOKClickResponse.cs @@ -0,0 +1,23 @@ +using Microsoft.DotNet.DesignTools.Protocol.DataPipe; +using Microsoft.DotNet.DesignTools.Protocol.Endpoints; + +namespace RootDesignerDemo.Protocol.Endpoints +{ + /// + /// Response class for this endpoint. This is not returning any relevant data, but this class is still needed + /// to meet the infrastructure conventions. + /// + public class RdTypeEditorOKClickResponse : Response.Empty + { + public static new RdTypeEditorOKClickResponse Empty { get; } = new RdTypeEditorOKClickResponse(); + + private RdTypeEditorOKClickResponse() + { + } + + public RdTypeEditorOKClickResponse(IDataPipeReader reader) + : base(reader) + { + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/CallerArgumentExpressionAttribute.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/CallerArgumentExpressionAttribute.cs new file mode 100644 index 0000000..06b6dc6 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/CallerArgumentExpressionAttribute.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Copied from https://github/dotnet/runtime + +// Note: This attribute was introduced in .NET Core 3.0. + + +namespace System.Runtime.CompilerServices; + +[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] +internal sealed class CallerArgumentExpressionAttribute : Attribute +{ + public CallerArgumentExpressionAttribute(string parameterName) + { + ParameterName = parameterName; + } + + public string ParameterName { get; } +} + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/GlobalUtilities.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/GlobalUtilities.cs new file mode 100644 index 0000000..30e80e0 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/GlobalUtilities.cs @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All Rights Reserved. +// ------------------------------------------------------------------- + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Microsoft.DotNet.DesignTools.Protocol; +using Microsoft.WinForms.Utilities.Shared; + +#pragma warning disable VSTHRD003 // Avoid awaiting foreign Tasks + +internal static class GlobalUtilities +{ + private const string ValueCannotBeAnEmptyString = "Value cannot be an empty string!"; + private const string ValueCannotBeNull = "Value cannot be null!"; + + /// + /// If the specified is , throw an + /// . + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowIfNull([NotNull] T? value) + { + if (value is null) + { + ThrowHelper.ThrowInvalidOperationException(ValueCannotBeNull); + } + } + + /// + /// If the specified is , throw an + /// . Otherwise, return the value passed. + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T OrThrowIfNull([NotNull] this T? value) + { + ThrowIfNull(value); + return value; + } + + /// + /// Awaits the specified . If the result is , + /// throw an . Otherwise, return the result. + /// + /// + public static async Task OrThrowIfNullAsync(this Task task) + => (await task).OrThrowIfNull(); + + /// + /// If is or an empty + /// . + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowIfNullOrEmpty([NotNull] string? value) + { + if (value.IsNullOrEmpty()) + { + ThrowIfNull(value); + ThrowHelper.ThrowInvalidOperationException(ValueCannotBeAnEmptyString); + } + } + + /// + /// If is or an empty + /// . Otherwise, return the value passed. + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string OrThrowIfNullOrEmpty([NotNull] string? value) + { + ThrowIfNullOrEmpty(value); + return value; + } + + /// + /// If is , throw an . + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowIfArgumentIsNull( + [NotNull] object? argument, + [CallerArgumentExpression("argument")] string? paramName = null) + { + if (argument is null) + { + ThrowHelper.ThrowArgumentNullException(paramName); + } + } + + /// + /// If is , throw an . + /// Otherwise, return the value of . + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T OrThrowIfArgumentIsNull( + [NotNull] this T? argument, + [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIfArgumentIsNull(argument, paramName); + + return argument; + } + + /// + /// If is or an empty , + /// throw an . + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowIfArgumentIsNullOrEmpty( + [NotNull] string? argument, + [CallerArgumentExpression("argument")] string? paramName = null) + { + if (argument.IsNullOrEmpty()) + { + ThrowIfArgumentIsNull(argument, paramName); + ThrowHelper.ThrowArgumentException(ValueCannotBeAnEmptyString, paramName); + } + } + + /// + /// If is , + /// throw an . + /// + /// + public static SessionId OrThrowIfArgumentIsNull( + this SessionId sessionId, + [CallerArgumentExpression("sessionId")] string? paramName = null) + { + if (sessionId.IsNull) + { + throw new ArgumentNullException(nameof(sessionId)); + } + + return sessionId; + } + + /// + /// If is or an empty , + /// throw an . Otherwise, return the value of . + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string OrThrowIfArgumentIsNullOrEmpty( + [NotNull] this string? argument, + [CallerArgumentExpression("argument")] string? paramName = null) + { + ThrowIfArgumentIsNullOrEmpty(argument, paramName); + return argument; + } + + /// + /// Indicates whether the specified string is or an empty . + /// + /// + /// This method can be used to workaround the fact that string.IsNullOrEmpty doesn't have nullable + /// annotations on .NET Framework. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value) + => string.IsNullOrEmpty(value); +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/NullableAttributes.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/NullableAttributes.cs new file mode 100644 index 0000000..83bf2b9 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/NullableAttributes.cs @@ -0,0 +1,153 @@ +// ------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All Rights Reserved. +// ------------------------------------------------------------------- +// Copied from https://github/dotnet/runtime +// Note: These attributes were introduced in .NET Core 3.0 and .NET 5. +#nullable disable + +namespace System.Diagnostics.CodeAnalysis +{ + + + /// Specifies that null is allowed as an input even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] + internal sealed class AllowNullAttribute : Attribute + { } + + /// Specifies that null is disallowed as an input even if the corresponding type allows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] + internal sealed class DisallowNullAttribute : Attribute + { } + + /// Specifies that an output may be null even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] + internal sealed class MaybeNullAttribute : Attribute + { } + + /// Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] + internal sealed class NotNullAttribute : Attribute + { } + + /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] + internal sealed class MaybeNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter may be null. + /// + public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } + + /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] + internal sealed class NotNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } + + /// Specifies that the output will be non-null if the named parameter is non-null. + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] + internal sealed class NotNullIfNotNullAttribute : Attribute + { + /// Initializes the attribute with the associated parameter name. + /// + /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + /// + public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; + + /// Gets the associated parameter name. + public string ParameterName { get; } + } + + /// Applied to a method that will never return under any circumstance. + [AttributeUsage(AttributeTargets.Method, Inherited = false)] + internal sealed class DoesNotReturnAttribute : Attribute + { } + + /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] + internal sealed class DoesNotReturnIfAttribute : Attribute + { + /// Initializes the attribute with the specified parameter value. + /// + /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + /// the associated parameter matches this value. + /// + public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; + + /// Gets the condition parameter value. + public bool ParameterValue { get; } + } + + + + /// Specifies that the method or property will ensure that the listed field and property members have not-null values. + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] + internal sealed class MemberNotNullAttribute : Attribute + { + /// Initializes the attribute with a field or property member. + /// + /// The field or property member that is promised to be not-null. + /// + public MemberNotNullAttribute(string member) => Members = new[] { member }; + + /// Initializes the attribute with the list of field and property members. + /// + /// The list of field and property members that are promised to be not-null. + /// + public MemberNotNullAttribute(params string[] members) => Members = members; + + /// Gets field or property member names. + public string[] Members { get; } + } + + /// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition. + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] + internal sealed class MemberNotNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition and a field or property member. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + /// + /// The field or property member that is promised to be not-null. + /// + public MemberNotNullWhenAttribute(bool returnValue, string member) + { + ReturnValue = returnValue; + Members = new[] { member }; + } + + /// Initializes the attribute with the specified return value condition and list of field and property members. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + /// + /// The list of field and property members that are promised to be not-null. + /// + public MemberNotNullWhenAttribute(bool returnValue, params string[] members) + { + ReturnValue = returnValue; + Members = members; + } + + /// Gets the return value condition. + public bool ReturnValue { get; } + + /// Gets field or property member names. + public string[] Members { get; } + } + +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/ThrowHelper.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/ThrowHelper.cs new file mode 100644 index 0000000..ef3186c --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/ThrowHelper.cs @@ -0,0 +1,44 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace Microsoft.WinForms.Utilities.Shared; + +internal static class ThrowHelper +{ + /// + /// Thows an . + /// + /// + /// This is marked with NoInlining to ensure that the JIT can better inline calling code. + /// + /// + [DoesNotReturn] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowArgumentNullException(string? paramName) + => throw new ArgumentNullException(paramName); + + /// + /// Throws an . + /// + /// + /// This is marked with NoInlining to ensure that the JIT can better inline calling code. + /// + /// + [DoesNotReturn] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowArgumentException(string message, string? paramName) + => throw new ArgumentException(message, paramName); + + /// + /// Throws an . + /// + /// + /// This is marked with NoInlining to ensure that the JIT can better inline calling code. + /// + /// + [DoesNotReturn] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowInvalidOperationException(string message) + => throw new InvalidOperationException(message); +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/RootDesignerDemo.Protocol.csproj b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/RootDesignerDemo.Protocol.csproj new file mode 100644 index 0000000..64bd0ba --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/RootDesignerDemo.Protocol.csproj @@ -0,0 +1,10 @@ + + + + net6.0-windows;net472 + true + latest + enable + true + + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/ViewModelNames.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/ViewModelNames.cs new file mode 100644 index 0000000..18daf6f --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/ViewModelNames.cs @@ -0,0 +1,10 @@ +namespace RootDesignerDemo.Protocol +{ + /// + /// Static class for holding the names of all ViewModels to provide IntelliSense support. + /// + public static class ViewModelNames + { + public const string RdTypeEditorVM = nameof(RdTypeEditorVM); + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/CodeDomSerializer/RdPropertyStoreCodeDomSerializer.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/CodeDomSerializer/RdPropertyStoreCodeDomSerializer.cs new file mode 100644 index 0000000..e48a132 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/CodeDomSerializer/RdPropertyStoreCodeDomSerializer.cs @@ -0,0 +1,95 @@ +using System.CodeDom; +using System.ComponentModel.Design.Serialization; +using System.Diagnostics; +using Microsoft.DotNet.DesignTools.Serialization; +using RootDesignerDemo.Controls; + +namespace RootDesignerDemo.Designer.Server.Serialization +{ + /// + /// Provides a generic content serializer for reference types, which - in contrast to + /// DesignerSerializationVisibility.Content - also generates code which instantiates the property's + /// custom type. + /// + internal class RdPropertyStoreCodeDomSerializer : CodeDomSerializer + { + public override object Serialize( + IDesignerSerializationManager manager, + object value) + { + if (Debugger.IsAttached) + Debugger.Break(); + + if (manager.Context.Current is ExpressionContext expressionContext) + { + RdPropertyStore propertyStore = (RdPropertyStore)value; + + // This is the left-side assignment target, we want to generate. + // And it describes the current context, for which we need the + // object generation. + var contextExpression = expressionContext.Expression; + CodeStatementCollection statements = new(); + + // Now, we want to generate: + // this.customControl1.CustomProperty = new RootDesignerDemo.RdPropertyStore(); + // this.customControl1.CustomProperty.CustomEnumValue = RootDesignerDemo.CustomEnum.FourthValue; + // this.customControl1.CustomProperty.DateCreated = new System.DateTime(2022, 7, 13, 0, 0, 0, 0); + // this.customControl1.CustomProperty.ListOfStrings = ((System.Collections.Generic.List)(resources.GetObject("resource.ListOfStrings"))); + // this.customControl1.CustomProperty.SomeMustHaveId = "{C0E03E00-EFDA-47AA-9BA9-B69671F7A565}"; + + // We start with 'new RdPropertyStore()'; + CodeObjectCreateExpression customPropertyCreateExpression = new( + new CodeTypeReference(typeof(RdPropertyStore))); + + // Then we do the assignment '{codeExpression} = new RdPropertyStore()'; + CodeAssignStatement contextAssignmentStatement = new( + contextExpression, customPropertyCreateExpression); + + // And from here on we're doing exactly that what the default serializer would be doing, + // had it detected the DesignerSerializationVisibilityAttribute set to 'Content'. + // It just traverses the property's object graph and creates the code for generating + // the respective value types, enums, arrays, etc. + + // To that end, we're _not_ getting this type's serializer, because then we would ending up with running + // this exact serializer. This is not what we want, we would end up in a recusion. Instead, we want to serialize + // the graph of property type, so we're getting object's default serializer... + var serializer = (CodeDomSerializer)manager.GetSerializer(typeof(object), typeof(CodeDomSerializer)); + + /// ...indicate, that we also want to generate code for setting the default values ... + var absolute = manager.Context[typeof(SerializeAbsoluteContext)] as SerializeAbsoluteContext; + + /// ...and we finally make sure, we're not serializing things that have been serialized before and could just + /// get from the stack. + var result = IsSerialized(manager, value, absolute != null) + ? GetExpression(manager, value) + : serializer.Serialize(manager, value); + + /// Now: Here is the difference to DesignerSerializationVisibility.Content: We are adding the instantiation code for our + /// custom (complex) property. And now ... + statements.Add(contextAssignmentStatement); + + /// ...we're adding all the statements, which the default (object) serializer generated, and which are at this point + /// supposed to be all the statements for assigning our custom control's property's custom type's properties. + if (result is CodeStatementCollection statementCollection) + { + foreach (CodeStatement statement in statementCollection) + { + statements.Add(statement); + } + } + else + { + if (result is CodeStatement statement) + { + statements.Add(statement); + } + } + + return statements; + }; + + var baseResult = base.Serialize(manager, value); + return baseResult; + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/ControlDesigner/RdControlDesigner.ActionList.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/ControlDesigner/RdControlDesigner.ActionList.cs new file mode 100644 index 0000000..aed6c98 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/ControlDesigner/RdControlDesigner.ActionList.cs @@ -0,0 +1,78 @@ +using System.ComponentModel; +using Microsoft.DotNet.DesignTools.Designers; +using Microsoft.DotNet.DesignTools.Designers.Actions; +using RootDesignerDemo.Controls; + +namespace RootDesignerDemo.Designer.Server +{ + internal partial class RdControlDesigner + { + /// + /// Action lists implementation for the . + /// + /// + /// Note: Action lists for the out-of-process Designer can be implemented exactly as they would be for the in-process + /// Designer, except: The control designer has to be compiled against the Winforms Designer Extensibility SDK, and ActionList + /// related classes must come from the namespace. + /// + private class ActionList : DesignerActionList + { + private const string Behavior = nameof(Behavior); + + private readonly ComponentDesigner _designer; + + public ActionList(RdControlDesigner designer) + : base(designer.Component) + { + _designer = designer; + } + + public RdPropertyStore? CustomProperty + { + get => ((RdControl?)Component)?.RdPropertyStoreProperty; + + // Note: This code would not work, since the PropertyBrowser wouldn't get updated. + //set + //{ + // if (Component is { } component) + // { + // ((RdControl)component).CustomProperty = value; + // } + //} + + // Do this instead: + set + { + if (Component is not null) + { + TypeDescriptor.GetProperties(Component)[nameof(CustomProperty)]?.SetValue(Component, value); + } + } + } + + public void InvokeRdTypeEditor() + => _designer.InvokePropertyEditor(nameof(RdControl.RdPropertyStoreProperty)); + + public override DesignerActionItemCollection GetSortedActionItems() + { + DesignerActionItemCollection actionItems = new(); + + actionItems.Add(new DesignerActionHeaderItem(Behavior)); + + actionItems.Add(new DesignerActionPropertyItem( + nameof(CustomProperty), + "CustomProperty definition", + Behavior, + "Controls the values of the CustomProperty Definition.")); + + actionItems.Add(new DesignerActionMethodItem( + this, + nameof(InvokeRdTypeEditor), + "Invokes the custom TypeEditor...", + true)); + + return actionItems; + } + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/ControlDesigner/RdControlDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/ControlDesigner/RdControlDesigner.cs new file mode 100644 index 0000000..8ef8ac1 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/ControlDesigner/RdControlDesigner.cs @@ -0,0 +1,51 @@ +using System.Drawing; +using System.Windows.Forms; +using Microsoft.DotNet.DesignTools.Designers; +using Microsoft.DotNet.DesignTools.Designers.Actions; + +namespace RootDesignerDemo.Designer.Server +{ + /// + /// The control designer of the RdControl. + /// + internal partial class RdControlDesigner : ControlDesigner + { + /// + /// Attaches the action lists to the control designer. + /// + /// + /// Note: Action lists for the out-of-process Designer can be implemented exactly as they would be for the in-process + /// designer, except: The control designer has to be compiled against the Winforms Designer Extensibility SDK, and ActionList + /// related classes must come from the namespace. + /// + public override DesignerActionListCollection ActionLists + => new() + { + new ActionList(this) + }; + + protected override void OnPaintAdornments(PaintEventArgs paintEventArgs) + { + base.OnPaintAdornments(paintEventArgs); + + // If you want to paint custom adorner or other GDI+ based content, + // use the paintEventArgs' Graphics methods to render it. + + // Drawing the frame around the ClientRectangle with a dotted brush... + if (!(SelectionService?.GetComponentSelected(Control) ?? false)) + { + using var pen = new Pen(Control.ForeColor); + + // ...if the control is not currently selected. + pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot; + using var brush = new SolidBrush(Control.ForeColor); + + var clientRect = Control.ClientRectangle; + clientRect.Inflate(-1, -1); + + paintEventArgs.Graphics.DrawRectangle(pen, clientRect); + } + } + } +} + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/Handler/CreateRdTypeEditorVMHandler.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/Handler/CreateRdTypeEditorVMHandler.cs new file mode 100644 index 0000000..08ee276 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/Handler/CreateRdTypeEditorVMHandler.cs @@ -0,0 +1,28 @@ +using RootDesignerDemo.Protocol; +using RootDesignerDemo.Protocol.Endpoints; +using Microsoft.DotNet.DesignTools.Protocol.Endpoints; + +namespace RootDesignerDemo.Designer.Server.Handlers +{ + /// + /// The handler for . + /// This actually creates the ViewModel and returns it via its request class. + /// + [ExportRequestHandler(EndpointNames.CreateRdTypeEditorVM)] + internal class CreateRdTypeEditorVMHandler + : RequestHandler + { + public override CreateRdTypeEditorVMResponse HandleRequest(CreateRdTypeEditorVMRequest request) + { + // Gets the respective DesignerHost of the sessionId, which has been passed by the client. + var designerHost = GetDesignerHost(request.SessionId); + + // Creates the ViewModel and passes the DesignerHost. + var viewModel = CreateViewModel(designerHost); + + // The ViewModel then initializes and wraps itself into the response class + // so it can be returned to the client. + return viewModel.Initialize(request.RdControlProxy!); + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/Handler/RdTypeEditorOkClickHandler.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/Handler/RdTypeEditorOkClickHandler.cs new file mode 100644 index 0000000..3b3ad1c --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/Handler/RdTypeEditorOkClickHandler.cs @@ -0,0 +1,28 @@ +using RootDesignerDemo.Protocol; +using RootDesignerDemo.Protocol.Endpoints; +using Microsoft.DotNet.DesignTools.Protocol.Endpoints; + +namespace RootDesignerDemo.Designer.Server.Handlers +{ + [ExportRequestHandler(EndpointNames.RdTypeEditorEditorOKClick)] + internal class RdTypeEditorOkClickHandler : RequestHandler + { + /// + /// Handler for the TypeEditor Dialog's OK-Click event. + /// + /// Contains the ViewModel reference and the new PropertyStoreData, + /// which contain the new values which have been edited/entered in the TypeEditor dialog. + /// The response, which is empty in this case, but the conventions need to be honored. + public override RdTypeEditorOKClickResponse HandleRequest(RdTypeEditorOKClickRequest request) + { + // Getting the ViewModel passed via the endpoint's request class. + var viewModel = (RdTypeEditorVM)request.ViewModel; + + // Delegate the actual handling of the OKClick event to the server-side ViewModel. + viewModel.OKClick(request.PropertyStoreData); + + // Nothing really to return, just honoring the conventions. + return RdTypeEditorOKClickResponse.Empty; + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/RdTypeEditorVM.Factory.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/RdTypeEditorVM.Factory.cs new file mode 100644 index 0000000..fb93124 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/RdTypeEditorVM.Factory.cs @@ -0,0 +1,19 @@ +using System; +using RootDesignerDemo.Protocol; +using Microsoft.DotNet.DesignTools.ViewModels; + +namespace RootDesignerDemo.Designer.Server +{ + internal partial class RdTypeEditorVM + { + /// + /// Factory class which generates the RdTypeEditorViewModel. + /// + [ExportViewModelFactory(ViewModelNames.RdTypeEditorVM)] + private class Factory : ViewModelFactory + { + protected override RdTypeEditorVM CreateViewModel(IServiceProvider provider) + => new(provider); + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/RdTypeEditorVM.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/RdTypeEditorVM.cs new file mode 100644 index 0000000..3f64e8f --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RdTypeEditor/RdTypeEditorVM.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; +using RootDesignerDemo.Protocol.DataTransport; +using RootDesignerDemo.Protocol.Endpoints; +using Microsoft.DotNet.DesignTools.ViewModels; +using RootDesignerDemo.Controls; + +namespace RootDesignerDemo.Designer.Server +{ + /// + /// The server-side ViewModel for controlling the RdTypeEditor UI. + /// + /// + /// 'ViewModel' in this context is a class which holds the logic/properties to control the UI. This is the + /// server-side part, but there is also a client-side part of that ViewModel. The server-side provides the logic based + /// on the real types of the RdTypeEditor, running in the context of the TFM of the custom control. It communicates + /// to the client-side ViewModel part, which _then_ controls the client-side hosted UI, which in turn runs in the + /// TFM-context of Visual Studio. + /// + internal partial class RdTypeEditorVM : ViewModel + { + public RdTypeEditorVM(IServiceProvider provider) + : base(provider) + { + } + + public CreateRdTypeEditorVMResponse Initialize(object propertyStoreObject) + { + var propertyStore = (RdPropertyStore)propertyStoreObject; + + return new CreateRdTypeEditorVMResponse( + this, + propertyStore is null + ? null + : new RdPropertyStoreData( + propertyStore.SomeMustHaveId, + propertyStore.DateCreated, + propertyStore.ListOfStrings?.ToArray(), + (byte)propertyStore.CustomEnumValue)); + } + + internal void OKClick(RdPropertyStoreData propertyStoreData) + { + // We're constructing the actual PropertyStore content based + // on the data that the user edited and the View sent to the server. + + PropertyStore = new( + propertyStoreData.SomeMustHaveId, + propertyStoreData.DateCreated, + propertyStoreData.ListOfStrings?.ToList(), + (RdPropertyStoreEnum)propertyStoreData.CustomEnumValue); + + // So, the server-side ViewModel now holds the edited, commited result. + // The question now is: How does the ViewModel property find the way back + // to the control? + // That's been done client-side: On the client, the client-side ViewModel holds the reference to the this + // PropertyStore property over a ProxyObject. When the User clicks OK in the editor, that codeflow is + // returned to the client-side part of the TypeEditor. That is, where the assignment from this ViewModel + // to the actual Property of the Control happens. + } + + public RdPropertyStore? PropertyStore { get; set; } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.SampleRootDesignerView.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.SampleRootDesignerView.cs new file mode 100644 index 0000000..8a6a2ec --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.SampleRootDesignerView.cs @@ -0,0 +1,52 @@ +using System.Drawing; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using Microsoft.DotNet.DesignTools.Designers; + +namespace RootDesignerDemo.Designer.Server; + +public partial class ShapeRootDesigner +{ + // RootDesignerView is a simple control that will be displayed + // in the designer window. + private class SampleRootDesignerView : RootDesignerView + { + private ShapeRootDesigner _designer; + private System.Threading.Timer _timer; + private bool _guard; + private int _counter = 0; + + public SampleRootDesignerView(ShapeRootDesigner designer) + { + _designer = designer; + BackColor = Color.LightGray; + Font = new Font(Font.FontFamily.Name, 24.0f); + + _timer = new System.Threading.Timer(new TimerCallback(TimerProc), null, 0, 2000); + } + + private async void TimerProc(object? state) + { + if (_guard) + return; + + _guard = true; + + await Task.Delay(0); + + Invalidate(); + + _counter++; + _guard = false; + } + + protected override void OnPaint(PaintEventArgs pe) + { + base.OnPaint(pe); + + // Draws the name of the component in large letters. + pe.Graphics.DrawString($"{_designer.Component.Site.Name}: {_counter}", Font, Brushes.Black, ClientRectangle); + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs new file mode 100644 index 0000000..ab24e0f --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs @@ -0,0 +1,42 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using Microsoft.DotNet.DesignTools.Designers; + +namespace RootDesignerDemo.Designer.Server; + +[ToolboxItemFilter(ToolboxCategory, ToolboxItemFilterType.Require)] +public partial class ShapeRootDesigner : ComponentDesigner, IRootDesigner +{ + private const string ToolboxCategory = "SdkShapeRootDesigner"; + + // Member field of custom type RootDesignerView, a control that + // will be shown in the Forms designer view. This member is + // cached to reduce processing needed to recreate the + // view control on each call to GetView(). + private RootDesignerView? _designerSurface; + + public ViewTechnology[] SupportedTechnologies => new[] { ViewTechnology.Default }; + + // This method returns an instance of the view for this root + // designer. The "view" is the user interface that is presented + // in a document window for the user to manipulate. + object IRootDesigner.GetView(ViewTechnology technology) + { + if (technology != ViewTechnology.Default) + { + throw new ArgumentException("Not a supported view technology", "technology"); + } + + if (_designerSurface == null) + { + // Some type of displayable Form or control is required + // for a root designer that overrides GetView(). In this + // example, a Control of type RootDesignerView is used. + // Any class that inherits from Control will work. + _designerSurface = new SampleRootDesignerView(this); + } + + return _designerSurface; + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesignerDemo.Server.csproj b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesignerDemo.Server.csproj new file mode 100644 index 0000000..1291e95 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesignerDemo.Server.csproj @@ -0,0 +1,14 @@ + + + + net6.0-windows + true + enable + true + + + + + + + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/TypeRoutingProvider.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/TypeRoutingProvider.cs new file mode 100644 index 0000000..547fc91 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/TypeRoutingProvider.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Microsoft.DotNet.DesignTools.TypeRouting; + +namespace RootDesignerDemo.Designer.Server +{ + /// + /// Class holding the TypeRoutings for resolving the control designer type on the server. + /// + [ExportTypeRoutingDefinitionProvider] + internal class TypeRoutingProvider : TypeRoutingDefinitionProvider + { + public override IEnumerable GetDefinitions() + { + return new[] + { + new TypeRoutingDefinition( + TypeRoutingKinds.Designer, + nameof(RdControlDesigner), + typeof(RdControlDesigner)), + + new TypeRoutingDefinition( + TypeRoutingKinds.Designer, + nameof(ShapeRootDesigner), + typeof(ShapeRootDesigner)) + }; + + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.sln b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.sln new file mode 100644 index 0000000..bfa4f58 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.sln @@ -0,0 +1,77 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32407.343 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RootDesignerDemo.Protocol", "RootDesignerDemo.Protocol\RootDesignerDemo.Protocol.csproj", "{855DB9BD-6C22-416B-A708-549D746149DE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ControlDesigners", "ControlDesigners", "{D247B836-28E7-4022-9FEF-12AA0A6B1184}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RootDesignerDemo.Server", "RootDesignerDemo.Server\RootDesignerDemo.Server.csproj", "{A6E65470-05AA-4DAA-92AF-0EC47A5CB140}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Controls", "Controls", "{89AEA44E-519A-4200-8467-17F5524C6E51}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RootDesignerDemo.Controls", "RootDesignerDemo.Controls\RootDesignerDemo.Controls.csproj", "{A1AFE219-25B5-4B8F-B9C2-0514A71731B5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RootDesignerDemo.Package", "RootDesignerDemo.Package\RootDesignerDemo.Package.csproj", "{119E53BE-06D5-40FA-87B8-FED0F8D2A750}" + ProjectSection(ProjectDependencies) = postProject + {58EFB943-5A3B-427A-A6C2-0ADE29F5A4A8} = {58EFB943-5A3B-427A-A6C2-0ADE29F5A4A8} + {855DB9BD-6C22-416B-A708-549D746149DE} = {855DB9BD-6C22-416B-A708-549D746149DE} + {A1AFE219-25B5-4B8F-B9C2-0514A71731B5} = {A1AFE219-25B5-4B8F-B9C2-0514A71731B5} + {A6E65470-05AA-4DAA-92AF-0EC47A5CB140} = {A6E65470-05AA-4DAA-92AF-0EC47A5CB140} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Solution Items", "_Solution Items", "{80223DA1-D034-43FE-A3D9-B9FCE6B30CE4}" + ProjectSection(SolutionItems) = preProject + Directory.Build.targets = Directory.Build.targets + NuGet.config = NuGet.config + readme.md = readme.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RootDesignerTestApp", "RootDesignerTestApp\RootDesignerTestApp.csproj", "{A2522661-E23A-4ADF-8B1F-2306ADB0CA26}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RootDesignerDemo.Client", "RootDesignerDemo.Client\RootDesignerDemo.Client.csproj", "{58EFB943-5A3B-427A-A6C2-0ADE29F5A4A8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {855DB9BD-6C22-416B-A708-549D746149DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {855DB9BD-6C22-416B-A708-549D746149DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {855DB9BD-6C22-416B-A708-549D746149DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {855DB9BD-6C22-416B-A708-549D746149DE}.Release|Any CPU.Build.0 = Release|Any CPU + {A6E65470-05AA-4DAA-92AF-0EC47A5CB140}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6E65470-05AA-4DAA-92AF-0EC47A5CB140}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6E65470-05AA-4DAA-92AF-0EC47A5CB140}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6E65470-05AA-4DAA-92AF-0EC47A5CB140}.Release|Any CPU.Build.0 = Release|Any CPU + {A1AFE219-25B5-4B8F-B9C2-0514A71731B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1AFE219-25B5-4B8F-B9C2-0514A71731B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1AFE219-25B5-4B8F-B9C2-0514A71731B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1AFE219-25B5-4B8F-B9C2-0514A71731B5}.Release|Any CPU.Build.0 = Release|Any CPU + {119E53BE-06D5-40FA-87B8-FED0F8D2A750}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {119E53BE-06D5-40FA-87B8-FED0F8D2A750}.Debug|Any CPU.Build.0 = Debug|Any CPU + {119E53BE-06D5-40FA-87B8-FED0F8D2A750}.Release|Any CPU.ActiveCfg = Release|Any CPU + {119E53BE-06D5-40FA-87B8-FED0F8D2A750}.Release|Any CPU.Build.0 = Release|Any CPU + {A2522661-E23A-4ADF-8B1F-2306ADB0CA26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2522661-E23A-4ADF-8B1F-2306ADB0CA26}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2522661-E23A-4ADF-8B1F-2306ADB0CA26}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2522661-E23A-4ADF-8B1F-2306ADB0CA26}.Release|Any CPU.Build.0 = Release|Any CPU + {58EFB943-5A3B-427A-A6C2-0ADE29F5A4A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58EFB943-5A3B-427A-A6C2-0ADE29F5A4A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58EFB943-5A3B-427A-A6C2-0ADE29F5A4A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58EFB943-5A3B-427A-A6C2-0ADE29F5A4A8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {855DB9BD-6C22-416B-A708-549D746149DE} = {D247B836-28E7-4022-9FEF-12AA0A6B1184} + {A6E65470-05AA-4DAA-92AF-0EC47A5CB140} = {D247B836-28E7-4022-9FEF-12AA0A6B1184} + {A1AFE219-25B5-4B8F-B9C2-0514A71731B5} = {89AEA44E-519A-4200-8467-17F5524C6E51} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D80B6075-E0F0-4F58-9558-C41445569497} + EndGlobalSection +EndGlobal diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.Designer.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.Designer.cs new file mode 100644 index 0000000..b2d22ae --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.Designer.cs @@ -0,0 +1,83 @@ +namespace RootDesignerTestApp +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + rdControl1 = new RootDesignerDemo.Controls.RdControl(); + button1 = new Button(); + checkBox1 = new CheckBox(); + SuspendLayout(); + // + // rdControl1 + // + rdControl1.Location = new Point(112, 101); + rdControl1.Name = "rdControl1"; + rdControl1.Size = new Size(418, 215); + rdControl1.TabIndex = 0; + rdControl1.Text = "rdControl1"; + // + // button1 + // + button1.Location = new Point(143, 32); + button1.Name = "button1"; + button1.Size = new Size(112, 34); + button1.TabIndex = 1; + button1.Text = "button1"; + button1.UseVisualStyleBackColor = true; + // + // checkBox1 + // + checkBox1.AutoSize = true; + checkBox1.Location = new Point(540, 385); + checkBox1.Name = "checkBox1"; + checkBox1.Size = new Size(121, 29); + checkBox1.TabIndex = 2; + checkBox1.Text = "checkBox1"; + checkBox1.UseVisualStyleBackColor = true; + // + // Form1 + // + AutoScaleDimensions = new SizeF(10F, 25F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(checkBox1); + Controls.Add(button1); + Controls.Add(rdControl1); + Name = "Form1"; + Text = "Form1"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private RootDesignerDemo.Controls.RdControl rdControl1; + private Button button1; + private CheckBox checkBox1; + } +} \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.cs new file mode 100644 index 0000000..386892c --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.cs @@ -0,0 +1,10 @@ +namespace RootDesignerTestApp +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.resx new file mode 100644 index 0000000..a395bff --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Program.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Program.cs new file mode 100644 index 0000000..d0d9384 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Program.cs @@ -0,0 +1,17 @@ +namespace RootDesignerTestApp +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new Form1()); + } + } +} \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/RootDesignerTestApp.csproj b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/RootDesignerTestApp.csproj new file mode 100644 index 0000000..a25f70f --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/RootDesignerTestApp.csproj @@ -0,0 +1,15 @@ + + + + WinExe + net6.0-windows + enable + true + enable + + + + + + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.cs new file mode 100644 index 0000000..c2b250e --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.cs @@ -0,0 +1,16 @@ +using RootDesignerDemo.Designer.Server; + +namespace RootDesignerDemo +{ + // This sample demonstrates how to provide the root designer view, or + // design mode background view, by overriding IRootDesigner.GetView(). + + // This sample component inherits from RootDesignedComponent which + // uses the SampleRootDesigner. + public class ShapeDocument : ShapeDocumentBase + { + public ShapeDocument() + { + } + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/readme.md b/Samples/RootDesigner/Net/ClientServerSample/readme.md new file mode 100644 index 0000000..d7eb454 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/readme.md @@ -0,0 +1,320 @@ +# Introduction to the Template Solution + +Since .NET 3.1 started to support the WinForms Runtime, a new WinForms designer +was needed to support .NET applications. This work required a near-complete +re-architect of the designer, as we responded to the differences between .NET +and the .NET Framework based WinForms designer everyone knows and loves. + +Until we added support for .NET Core applications there was only a single +process, *devenv.exe*, that both the Visual Studio environment and the application +being designed ran within. But .NET Framework and .NET Core can’t both run +together within *devenv.exe*, and as a result we had to take the designer out of +process. We call the existing process – the process that Visual Studio runs in – +the client process or the Visual Studio process, and the process which shows the +actual Form at design time, the server process or short *DesignToolsServer*. + +## Enter the DesignToolsServer + +While simple control designer scenarios like type converters, action lists or +CodeDom serializers don’t need any substantial rewrites, type editors are a +different beast altogether. + +To illustrate the additional requirements which arose by introducing different +processes, let’s look at a typical type editor for any property of type +`Image` like the Button’s *BackgroundImage* property: While the actual image +that you picked will be rendered on a button in the server process, the dialog +you picked the Image *with* runs in the context of Visual Studio. That in turn +means there is communication between the two processes necessary, which custom +type editors for the modern WinForms Designer need to take care of. In addition, +type editor solutions also need to provide a NuGet package whose individual +assemblies gets partly loaded into the Visual Studio process and partly into the +DesignToolsServer. And to that end, this NuGet needs to have a special +structure, which a dedicated Package project takes care of. If you want to learn +more about the concept of the modern WinForms Designer: [This blog +post](https://devblogs.microsoft.com/dotnet/state-of-the-windows-forms-designer-for-net-applications/) +describes the concept of the different processes in greater detail. + +## Projects which the templates create + +Setting all these things up manually means coordinating a lot of moving parts, +and there is a huge potential that things go wrong. The individual projects +created by this template help to prevent falling into those traps. The templates +create a series of projects and important solution folders, depending on your +needs for both C\# and Visual Basic. Let’s look at the projects which are part +of the template solution in detail: + +* **\_Solution Items:** This is not really a project, but rather a solution + folder, which holds the readme, the *Directory.Build* Target which determines + the NuGet package version for the used Designer SDK version and the + *NuGet.config* setting. If at any point you would need to change the Designer + SDK version which is used throughout the solution, you would only need to + change them in one spot: here. +* **RootDesignerDemo.Client** This is a project of the same target framework + version as Visual Studio, and it holds the actual type editor UI running in + the context of Visual Studio. It also contains the so-called client *view + model*, which is a UI controller class. It communicates on the one side with + its pendant in the server process and controls the client-based UI (a modal + WinForms Dialog) on the other side based on the server-provided data. +* **RootDesignerDemo.Server:** This project holds every aspect of the + control designer, which needs to be executed in the context of the server + process. Those are + + * The server-side view model, which provides the necessary data to the + client-side view model. + * The factory class, which generates the server-side view model. + * A custom CodeDom serializer for the custom property type the type editor is + handling, should one be needed. + * A custom designer action list which can be accessed at design time through + the designer action glyph of the control. Please note, that although these + classes are hosted purely in the server-side designer assembly, the UI for + the respective action list is still shown in the context of Visual Studio. + The necessary communication with the client is done completely behind the + scenes by the Designer SDK. So, even if it looks like the designer action + lists are handled exclusively by the server process, they are not. + * The actual control designer, which – as one example – paints the adornments + for the controls. This is the only part of the UI which is actually rendered + server-side, and although it looks like this rendering is done in the + context of Visual Studio, it is not. The rendering of the Form and all its + components at design time is done by the DesignToolsServer and just + projected on the client-area of Visual Studio Design surface. But! Although + rendered on the server-side, there is no direct interaction with the message + queue of the server. Every keyboard- and mouse-input is still received in the + Visual Studio-based client process, and the results of that are communicated + to the server. That is the way the WinForms Designer ensures that no + deadlocks will occur due to competing message queues of different processes. + +* **RootDesignerDemo.Protocol:** This project contains all the classes + which are necessary for the communication between the client and the server + process via [JSON-RPC](https://www.jsonrpc.org/). The Designer SDK provides + a series of base classes which are optimized for transferring + WinForms-typical data types between the client- and the server-process. A + typical protocol library for a control designer builds on those classes. + +* **RootDesignerDemo:** This is the project, which contains your actual + custom control(s). + +* **RootDesignerDemo.Package:** This is the project which creates the NuGet + package. This NuGet package organizes the individual control designer + components for the DesignToolsServer server process and the Visual Studio + client process in respective folders, so that the required parts are + available for the processes at design time. + +## Invoking Type Editors, In Process vs. Out-Of-Process + +In the classic framework, invoking of a type editor is a straightforward +procedure. Here is what happens, when the user starts to edit a value of a +property by opening a type editor via the Visual Studio’s property browser: + +* The user wants to set a value for a property of a control which either + doesn’t have a default string representation (like an image or a sound file) + or is a composite property type, which demands a more complex user + interaction. A type editor for that property type is defined by the + `EditorAttribute` (see class `RdPropertyStore` in the template + project as an example). + +* The custom type editor class, which is usually provided along with the type + the custom control provides for that special property, is instantiated when + the user clicks on the …-Button in the property’s cell of Visual Studio’s + property browser. + +* The property browser now calls the `EditValue` method of the type editor + and passes the value of the property to set. In other words: The type editor + receives the instance of the custom property. In the example of the + `BackgroundImage` property of the Button control, the instance would be + the actual image. In our template example, that instance would be of type + `RdPropertyStore`. + +* The type editor now gets the `UIDialogService`, which enables the type + editor to display a modal (WinForms) dialog in the context of Visual Studio. + It is important to show the dialog in the context of Visual Studio, because + otherwise Windows message processing queues of different processes would run + concurrently, compete and quickly dead-lock each other, so + that Visual Studio would freeze. + +* The UI converts the value in an editable format, gets the updates from the + users, and then converts the edits back to the type of that control’s custom + property. The value, which the type editor returns, is now assigned by the + property browser to the property. + +And here now is the all-important difference compared to the out-of-process +Designer scenario: When the property browser asks the UITypeEditor to display +the visual representation of the value, that type’s value is not available in +the context of Visual Studio. The reason: The property browser runs in a process +targeting a different .NET version than the process that defines the type. +Visual Studio runs, for example, against .NET Framework 4.7.2 while the custom +control library you are developing is e. g. targeting .NET 7. There is simply no +supported way that .NET Framework can deal with types defined in or based on +types defined .NET 7. So, instead of giving the UITypeEditor the control’s +custom/special property’s value directly, it’s handing it via a so-called *proxy +object*. + +The concept of proxy objects in the client (Visual Studio) process does require +a special infrastructure for handling user inputs in custom type editors. Let’s +look at what infrastructure components of the Designer we need to understand, +before we talk about the workflow for setting the value in the OOP scenario: + +* **Using View Models:** View models are for controlling aspects of a UI + without having a direct reference to the UI specific components. Don’t + confuse view models in the context of the WinForms Designer with view models + you might know from XAML languages, though! They are only remote relatives. + Yes, they are controlling the UI in a UI-technology independent way – and + that’s the main aspect of a view model. But no, in contrast to XAML, they + are not doing this by direct data binding. View models in the context of the + Designer are rather used to sync certain conditions of the UI between the + client and the server process. The class `RdTypeEditorVMClient` + provides a static method `Create`, which is the dedicated way to create a + view model. You pass it the service provider and also the proxy object of + the instance of the property value to edit, which the client-side type + editor just got from the property browser. + +* **Sessions and the DesignToolsClient:** For the communication with the + DesignToolsServer server process, the Designer not only need a communication + endpoint on the server, but also on the client side. The + `DesignToolsClient` class represents that client-side endpoint and + provides the basic mechanisms for communication with the server. To separate + the concerns of each open designable WinForms document within Visual Studio, + each open designer is associated with a session. The `Create` method in + the sample shows how to retrieve a session along with and the + `DesignToolsClient` through the service provider, and can now, with both + objects, talk to the server – in this case to create the respective + *server-side* view model. + +* **Proxy classes:** These classes solve the basic challenge: Representing + objects of server-side .NET version types which are not known to the client. + If you select a component in the Designer, what the property browser “sees” + is a proxy object which kind of points to the real object in the server + process. A value of a property of a complex type is also represented by a + proxy object, since – again – its type only exists on the server, because + it’s targeting a different .NET version. And yet again: Also, the view model + returned from the server is not the actual server-side view model instance + (it can’t, because, again, it might contain or be based on types that are + not existing in the client-side target framework). The client-side view + model will need this view model-proxy to synchronize necessary data across + the process boundaries. + +* **Data transport and remote procedure calls:** The communication between + client and server is always synchronous, so blocking: You define endpoints + in the server-process, which the client calls. The client waits, until the + server has finished processing those remote procedure calls. Basically, each + endpoint needs three dedicated classes: A *Request* class, defined in the + Protocol project (see below), which transports necessary data to the + DesignToolsServer. A *Response* class, which transports result data back to + the client process – also defined in the Protocol project. And lastly a + *Handler* class, which is the server-side remote-procedure to call, if you + will. In this template, two endpoints are already predefined: + `CreateRdTypeEditorVM` creates the server-side view model, whose + instance is then hosted as a proxy-object in the client-side view model, so + the communication and data exchange can be simplified over those two + instances. And then there is also the `TypeEditorOKClick` endpoint: This + method is called when the user clicked the OK button of the type editor + during design time to indicate that they changed the value passed by the + property browser. Since the custom property type only exists in the + DesignToolsServer, the client can only pass over the individual data + fragments from what the user entered in the dialog to the server process. + But it is the server which then creates the actual instance of the value of + what it got passed from the client. And it eventually assigns that value to + the property of the user control. + +Now, with these important basics in mind, here is the workflow for setting a +property value via a type editor in the out-of-process Designer scenario in +detail: + +* As in the classic in-process-Scenario, the user wants to set a value for a +custom property. And again, a type editor for that property type is defined by +the `EditorAttribute` (see class `RdPropertyStore` in the template +project). The first important difference: Since the type in question might not +be available in the client process’ target framework, the type can only be +defined as a string. Also as before, the custom type editor class is +instantiated, when the user clicks on the …-Button in the property’s cell of the +property browser. Now, here is a first exciting challenge that the modern +designer faces: When the custom control lives only in the server process, and +the actual type editor lives only in the client, how does the WinForms Designer +finds the type editor on the client side? This is where an important component +in the client designer project comes into play: the `TypeRoutingProvider`. It +holds a table of `TypeRoutingDefinition` objects and assigns the names of the +editors to the actual types. That means, if you were ever to add additional type +editors for other property types or controls to your control library solution, +this table must be ament and maintained accordingly. It’s best practice to use +the `EditorNames`definitions in the Protocol project to that end, since it +minimizes typos by providing IntelliSense support. + +* Now, yet again, the property browser calls the `EditValue` method of the + type editor and passes the value of the property to set. But the value now is + not the actual value of the property. It’s rather the proxy object, which + points to the actual instance of the value in the server process. This also + means, processing the value must be happening in the server-process. To this + end, the two view model types to control the edit procedure need now to be + used: one on the client side (`RdTypeEditorVMClient`), and one on the + server side (`RdTypeEditorVM`). The template creates both classes for + you, along with the infrastructure methods to set them up. + +* The static `Create` method of the client-side view model has now all the + information to create the actual client-side view model by calling the + `CreateViewModelClient` method of the Designer service provider, and for + that it passes the server-side proxy to the server view model. + +* The type editor’s main task is to edit the value of type + `RdPropertyStore`. To keep the example simple, this is just a composite + type, composed of a `string`, a `DateTime`, a list of `string` elements and a + custom Enum. As a reminder: since this type only exists server-side, the UI + (being in the context of Visual Studio) cannot use this type. This is where + the Protocol project/assembly comes into play. The Protocol project defines + all the transport classes, which can be used in either process. It is defined + as a .NET standard library, so all its types can be projected and used in both + .NET and .NET Framework projects equally. So, to solve this requirement, we + mirror the `RdPropertyStore` type with a special data class we define in + the Protocol project named `RdPropertyStoreData`. This type also provides + the necessary methods to convert the data its hosting into the JSON format and + back from it, which is needed to transport it across the process’s boundaries. + With that, the response class for the endpoint to create the server-side view + model not only takes the proxy of the server-side view model, but also the + original values of the types, the custom property type is composed of. And + this data we now use to populate the type editor’s dialog client side. + +* The user now edits the values. + +* When the user clicks *OK*, we validate the data on the client inside the + `RdTypeEditorDialog`. And if the validation passes, the dialog returns + `DialogResult.OK`, and we call the `ExecuteOKCommand` method of the client + view model to kick of the data transfer to the server. This method now sends + the `RdTypeEditorOKClickRequest` to the server and passes the individual + retrieved data from the user’s input of the dialog along. The endpoint’s + handler gets those data and passes - in turn - that data to the server-side + view model, which then again calls its `OnClick` method, composes the actual + instance of the custom control’s property type, and stores it in the + `PropertyStore` property of the server-side view model. And with that the call + chain seems to end here. So, the server-side view model now holds the edited + and committed result. But wait! How does the view model property find the way + back to the control’s property? That last step is done client-side, and it’s + kind of subtle: Remember? When the client-side view model got created, it not + only triggered the creation of the server-side view model. It also requested + the proxy of that view model to be returned to the client side. On the client, + the client-side view model holds the reference to the server-side view model’s + `PropertyStore` property over a proxy object. When the user clicks *OK* in the + editor, that code flow is returned to the type editor (running in the context + of Visual Studio), which had opened the modal dialog to begin with. Now, back in + the actual type editor class, it is where the assignment from this view model + to the actual property of the control happens: + +```cs + var dialogResult = editorService.ShowDialog(_customTypeEditorDialog); + if (dialogResult == DialogResult.OK) + { + // By now, the UI of the Editor has asked its (client-side) ViewModel + // to run the code which updates the property value. It passes the data to + // the server, which in turn updates the server-side ViewModel. + // When it's time to return the value from the client-side ViewModel back to the + // Property Browser (which has called the type editor in the first place), the client-side + // ViewModel accesses its PropertyStore property, which in turn gets the required PropertyStore + // proxy object directly from the server-side ViewModel. + value = viewModelClient.PropertyStore; + } +``` + +The `PropertyStore` property of the `ViewModelClient` doesn’t have a dedicated +backing field to hold the value. Rather, it uses the infrastructure of the proxy +to communicate with the server-side view model to get the just created proxy of +the server-side view model’s `PropertyStore` content directly. And the proxy +object is what we need here: Again, since the client doesn’t know the type, it +can only deal with the proxy objects which point and represent the server types +instead. diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/CustomControl/SimpleCustomControl.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/CustomControl/SimpleCustomControl.cs new file mode 100644 index 0000000..d6b7f1f --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/CustomControl/SimpleCustomControl.cs @@ -0,0 +1,10 @@ +using System.ComponentModel; +using RootDesignerDemo.Design; + +namespace RootDesignerDemo; + +[Designer(typeof(SimpleCustomControlDesigner))] +public class SimpleCustomControl : Panel +{ + public bool SampleProperty { get; set; } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/CustomControl/SimpleCustomControlDesigner.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/CustomControl/SimpleCustomControlDesigner.cs new file mode 100644 index 0000000..314c182 --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/CustomControl/SimpleCustomControlDesigner.cs @@ -0,0 +1,80 @@ +using Microsoft.DotNet.DesignTools.Designers.Actions; +using Microsoft.DotNet.DesignTools.Designers; + +using System.ComponentModel; + +namespace RootDesignerDemo.Design +{ + /// + /// Control Designer for the + /// + internal partial class SimpleCustomControlDesigner : ControlDesigner + { + /// + /// Hooks up the Action lists. + /// + /// + /// Action lists for the OOP-Designer can be implemented exactly like for the in-process Designer. The Designer + /// has to be compiled though against the Designer SDK, and ActionList related classes must come from the + /// namespace. + /// + public override DesignerActionListCollection ActionLists + => new() + { + new ActionList(this) + }; + + protected override void OnPaintAdornments(PaintEventArgs pe) + { + base.OnPaintAdornments(pe); + } + + /// + /// Action lists implementation for the . + /// + /// + /// Note: Action lists for the OOP-Designer can be implemented exactly like for the in-process Designer. The Designer + /// has to be compiled though against the Designer SDK, and ActionList related classes must come from the + /// namespace. + /// + private class ActionList : DesignerActionList + { + private const string Behavior = nameof(Behavior); + private const string Data = nameof(Data); + + private readonly ComponentDesigner _designer; + + public ActionList(SimpleCustomControlDesigner designer) + : base(designer.Component) + { + _designer = designer; + } + + public bool SampleProperty + { + get => ((SimpleCustomControl)Component!).SampleProperty; + + // Do this instead: + set => + TypeDescriptor.GetProperties(Component!)[nameof(SampleProperty)]! + .SetValue(Component, value); + } + + public override DesignerActionItemCollection GetSortedActionItems() + { + DesignerActionItemCollection actionItems = new(); + + actionItems.Add(new DesignerActionHeaderItem(Behavior)); + actionItems.Add(new DesignerActionHeaderItem(Data)); + + actionItems.Add(new DesignerActionPropertyItem( + nameof(SampleProperty), + "Some Sample Property", + Behavior, + "A demo property to have something to show for the Action List.")); + + return actionItems; + } + } + } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner.Lib.csproj b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner.Lib.csproj new file mode 100644 index 0000000..88c43e2 --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner.Lib.csproj @@ -0,0 +1,14 @@ + + + + net7.0-windows + enable + true + enable + + + + + + + diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/SampleRootDesigner.SampleRootDesignerView.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/SampleRootDesigner.SampleRootDesignerView.cs new file mode 100644 index 0000000..9733d8b --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/SampleRootDesigner.SampleRootDesignerView.cs @@ -0,0 +1,58 @@ +using System.Diagnostics; +using Microsoft.DotNet.DesignTools.AsyncToolbox; +using Microsoft.DotNet.DesignTools.Designers; + +namespace RootDesignerDemo; + +public partial class ShapeRootDesigner +{ + // RootDesignerView is a simple control that will be displayed + // in the designer window. + private class SampleRootDesignerView : RootDesignerView + { + private ShapeRootDesigner _designer; + private IAsyncToolboxService _asyncToolboxService; + private System.Threading.Timer _timer; + private bool _guard; + private int _counter = 0; + + public SampleRootDesignerView(ShapeRootDesigner designer) + { + _designer = designer; + BackColor = Color.LightGray; + Font = new Font(Font.FontFamily.Name, 24.0f); + + _asyncToolboxService = designer.GetRequiredService(); + _timer = new System.Threading.Timer(new TimerCallback(TimerProc), null, 0, 2000); + } + + private async void TimerProc(object? state) + { + if (_guard) + return; + + _guard = true; + + if (Debugger.IsAttached) + Debugger.Break(); + + if (_asyncToolboxService != null) + { + await _asyncToolboxService.SetCursorAsync(); + } + + Invalidate(); + + _counter++; + _guard = false; + } + + protected override void OnPaint(PaintEventArgs pe) + { + base.OnPaint(pe); + + // Draws the name of the component in large letters. + pe.Graphics.DrawString($"{_designer.Component.Site.Name}: {_counter}", Font, Brushes.Black, ClientRectangle); + } + } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/SampleRootDesigner.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/SampleRootDesigner.cs new file mode 100644 index 0000000..293363c --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/SampleRootDesigner.cs @@ -0,0 +1,114 @@ +using System.ComponentModel; +using System.ComponentModel.Design; +using Microsoft.DotNet.DesignTools.Designers; + +namespace RootDesignerDemo; + +[ToolboxItemFilter(ToolboxCategory, ToolboxItemFilterType.Require)] +public partial class ShapeRootDesigner : ComponentDesigner, IRootDesigner //, IToolboxUser +{ + private const string ToolboxCategory = "ShapeRootDesigner"; + + // Member field of custom type RootDesignerView, a control that + // will be shown in the Forms designer view. This member is + // cached to reduce processing needed to recreate the + // view control on each call to GetView(). + private RootDesignerView? _designerSurface; + + //private IToolboxService? _toolboxService = null; + //private ToolboxItemCollection? _tools; + + public ViewTechnology[] SupportedTechnologies => new[] { ViewTechnology.Default }; + + //public bool GetToolSupported(ToolboxItem tool) + //{ + // return !(tool.Properties[ToolboxCategory] is null); + //} + + //public void ToolPicked(ToolboxItem tool) + //{ + // // TODO: Add the code, which adds a new shape to the designer surface. + //} + + // This method returns an instance of the view for this root + // designer. The "view" is the user interface that is presented + // in a document window for the user to manipulate. + object IRootDesigner.GetView(ViewTechnology technology) + { + if (technology != ViewTechnology.Default) + { + throw new ArgumentException("Not a supported view technology", "technology"); + } + + if (_designerSurface == null) + { + // Some type of displayable Form or control is required + // for a root designer that overrides GetView(). In this + // example, a Control of type RootDesignerView is used. + // Any class that inherits from Control will work. + _designerSurface = new SampleRootDesignerView(this); + + //_toolboxService = (IToolboxService)this.GetService(typeof(IToolboxService)); + //// If an IToolboxService was located, update the + //// category list. + //if (_toolboxService is null) + //{ + // MessageBox.Show("Couldn't retrieve Toolbox Service!"); + //} + //else + //{ + // SetupToolboxItems(); + //} + } + + return _designerSurface; + } + + //private void SetupToolboxItems() + //{ + // CreateToolboxItem("Line Tool", "LineTool", "ShapeRootDesigner", + // RootDesignerDemo.Properties.Resources.Rectangle); + // CreateToolboxItem("Rectangle Tool", "RectangleTool", "ShapeRootDesigner", + // RootDesignerDemo.Properties.Resources.Rectangle); + // CreateToolboxItem("Text Tool", "TextTool", "ShapeRootDesigner", + // RootDesignerDemo.Properties.Resources.Rectangle); + //} + + private void CreateToolboxItem(string toolDisplayName, string toolTypeName, string toolboxFilterString, Bitmap toolboxBitmap) + { + //ToolboxItem toolboxItem; + //ToolboxItemFilterAttribute toolboxItemFilterAttribute; + //ToolboxItemFilterAttribute[] toolboxItemFilterAttributeArray; + + //string toolboxItemName =$"{ToolboxCategory}.{toolTypeName}"; + + //foreach (ToolboxItem existingToolboxItem in _toolboxService.GetToolboxItems(ToolboxCategory)) + //{ + // if (existingToolboxItem.TypeName != toolboxItemName) + // { + // continue; + // } + + // // We found the item, so remove it... + // _toolboxService.RemoveToolboxItem(existingToolboxItem); + // break; + //} + + //// ...and add it again. + //toolboxItem = new ToolboxItem() + //{ + // TypeName = toolboxItemName, + // DisplayName = toolDisplayName, + // Description = $"Description of {toolDisplayName}", + // Bitmap = toolboxBitmap + //}; + + //toolboxItemFilterAttribute = new ToolboxItemFilterAttribute(toolboxFilterString, ToolboxItemFilterType.Require); + //toolboxItemFilterAttributeArray = new ToolboxItemFilterAttribute[] { toolboxItemFilterAttribute }; + //toolboxItem.Filter = (ICollection)toolboxItemFilterAttributeArray; + //toolboxItem.Properties[ToolboxCategory] = toolTypeName; + //_toolboxService.AddToolboxItem(toolboxItem, ToolboxCategory); + + return; + } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/ShapeDocumentBase.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/ShapeDocumentBase.cs new file mode 100644 index 0000000..e400362 --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/ShapeDocumentBase.cs @@ -0,0 +1,19 @@ +using System.ComponentModel; +using System.ComponentModel.Design; + +namespace RootDesignerDemo; + +// The following attribute associates the SampleRootDesigner designer +// with the SampleComponent component. +[Designer(typeof(ShapeRootDesigner), typeof(IRootDesigner)), + ToolboxItem(false)] +public class ShapeDocumentBase : Component +{ + public ShapeDocumentBase() + { + } + + private void InitializeComponent() + { + } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/ShapeDocumentBase.resx b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/ShapeDocumentBase.resx new file mode 100644 index 0000000..e5858cc --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/RootDesigner/ShapeDocumentBase.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.Designer.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.Designer.cs new file mode 100644 index 0000000..de7415a --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.Designer.cs @@ -0,0 +1,35 @@ +namespace RootDesignerDemo.ShapeComponents; + +partial class SimpleBoxComponent +{ + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.cs new file mode 100644 index 0000000..239f16c --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; + +namespace RootDesignerDemo.ShapeComponents; + +public partial class SimpleBoxComponent : Component +{ + public SimpleBoxComponent() + { + InitializeComponent(); + } + + public SimpleBoxComponent(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.resx b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesigner.Lib/ShapeComponents/SimpleBoxComponent.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo.sln b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo.sln new file mode 100644 index 0000000..4b497da --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32130.36 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RootDesigner.Lib", "RootDesigner.Lib\RootDesigner.Lib.csproj", "{9B043351-707C-4875-8465-457824F07EC3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RootDesignerDemo", "RootDesignerDemo\RootDesignerDemo.csproj", "{D6ED5824-17EC-4304-A763-5D72DF2483FE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9B043351-707C-4875-8465-457824F07EC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B043351-707C-4875-8465-457824F07EC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B043351-707C-4875-8465-457824F07EC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B043351-707C-4875-8465-457824F07EC3}.Release|Any CPU.Build.0 = Release|Any CPU + {D6ED5824-17EC-4304-A763-5D72DF2483FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6ED5824-17EC-4304-A763-5D72DF2483FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6ED5824-17EC-4304-A763-5D72DF2483FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6ED5824-17EC-4304-A763-5D72DF2483FE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {ED24AAF5-3FB6-43A3-991E-9E10A798B727} + EndGlobalSection +EndGlobal diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.Designer.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.Designer.cs new file mode 100644 index 0000000..e7576bd --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.Designer.cs @@ -0,0 +1,57 @@ +namespace RootDesignerDemo +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + simpleCustomControl1 = new SimpleCustomControl(); + SuspendLayout(); + // + // simpleCustomControl1 + // + simpleCustomControl1.Location = new Point(90, 64); + simpleCustomControl1.Name = "simpleCustomControl1"; + simpleCustomControl1.SampleProperty = true; + simpleCustomControl1.Size = new Size(462, 283); + simpleCustomControl1.TabIndex = 0; + // + // Form1 + // + AutoScaleDimensions = new SizeF(10F, 25F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(simpleCustomControl1); + Name = "Form1"; + Text = "Form1"; + ResumeLayout(false); + } + + #endregion + + private SimpleCustomControl simpleCustomControl1; + } +} \ No newline at end of file diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.cs new file mode 100644 index 0000000..48c7d28 --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace RootDesignerDemo +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + } + } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.resx b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.resx new file mode 100644 index 0000000..a395bff --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Program.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Program.cs new file mode 100644 index 0000000..ea0542a --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/Program.cs @@ -0,0 +1,17 @@ +namespace RootDesignerDemo; + +internal static class Program +{ + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + + Application.Run(new Form1()); + } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/RootDesignerDemo.csproj b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/RootDesignerDemo.csproj new file mode 100644 index 0000000..2bc9ad9 --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/RootDesignerDemo.csproj @@ -0,0 +1,15 @@ + + + + WinExe + net7.0-windows + enable + true + enable + + + + + + + diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/ShapeDocument.cs b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/ShapeDocument.cs new file mode 100644 index 0000000..0774242 --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/ShapeDocument.cs @@ -0,0 +1,14 @@ +namespace RootDesignerDemo +{ + // This sample demonstrates how to provide the root designer view, or + // design mode background view, by overriding IRootDesigner.GetView(). + + // This sample component inherits from RootDesignedComponent which + // uses the SampleRootDesigner. + public class ShapeDocument : ShapeDocumentBase + { + public ShapeDocument() + { + } + } +} diff --git a/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/ShapeDocument.resx b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/ShapeDocument.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Samples/RootDesigner/Net/Simple Sample/RootDesignerDemo/ShapeDocument.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557.zip b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557.zip new file mode 100644 index 0000000000000000000000000000000000000000..49a49d2c905cded514352560b1aa5d6070a1d7ea GIT binary patch literal 47108 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 + + + TileRepeater.Package + 1.234.121557 + TileRepeater.Package + Package Description + + + + + + \ No newline at end of file diff --git a/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/[Content_Types].xml b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/[Content_Types].xml new file mode 100644 index 0000000..f30e5d8 --- /dev/null +++ b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/[Content_Types].xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/_rels/.rels b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/_rels/.rels new file mode 100644 index 0000000..69b24e5 --- /dev/null +++ b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/_rels/.rels @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/Server/TileRepeater.ClientServerProtocol.dll b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/Server/TileRepeater.ClientServerProtocol.dll new file mode 100644 index 0000000000000000000000000000000000000000..6efc124df64bff900442793254613d63339edfa7 GIT binary patch literal 13312 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 literal 0 HcmV?d00001 diff --git a/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/Server/TileRepeater.Designer.Server.dll b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/Server/TileRepeater.Designer.Server.dll new file mode 100644 index 0000000000000000000000000000000000000000..a3e46b33c466d532c190f1bdaf7a3158daf4624c GIT binary patch literal 17408 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 S2K?ft_aXcLMgE_Q!2bfEeI0fH literal 0 HcmV?d00001 diff --git a/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/TileRepeater.ClientServerProtocol.dll b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/TileRepeater.ClientServerProtocol.dll new file mode 100644 index 0000000000000000000000000000000000000000..7c57c98bf4216e4f7287eca4c99f4868ff09e0cd GIT binary patch literal 13312 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 literal 0 HcmV?d00001 diff --git a/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/TileRepeater.Designer.Client.dll b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/Design/WinForms/TileRepeater.Designer.Client.dll new file mode 100644 index 0000000000000000000000000000000000000000..19780f8cf00ff21965b16f1c3f8642387782de37 GIT binary patch literal 18944 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 b$oc#58h(uHfcp1RkKp+B|F8e|Jn(-2(dJf$ literal 0 HcmV?d00001 diff --git a/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/TileRepeater.Controls.dll b/Samples/TypeEditor/Dotnet/TileRepeater_Medium/NuGet/BuildOut/TileRepeater.Package.1.234.121557/lib/net6.0/TileRepeater.Controls.dll new file mode 100644 index 0000000000000000000000000000000000000000..d20e734a05119a54d50490b5c6111c0f56e4069f GIT binary patch literal 20992 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 + + TileRepeater.Package + Package Description + TileRepeater.Package + 1.234.121557 + + NuGet.Build.Tasks.Pack, Version=6.6.0.57, Culture=neutral, PublicKeyToken=31bf3856ad364e35;Microsoft Windows NT 10.0.22621.0;.NET Framework 4.7.2 + \ No newline at end of file From 58b850bb4d5210ce8bad3dbdc316dfe699a3f8a5 Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Tue, 9 May 2023 12:52:01 -0700 Subject: [PATCH 02/11] Update RootDesigner OOP demo. --- .../RootDesignerProxy/ShapeRootProxyDesigner.cs | 8 +++----- .../RootDesigner/ShapeRootDesigner.cs | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs index 446408c..229bd35 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs @@ -1,6 +1,5 @@ using System.Collections; using System.ComponentModel; -using System.Diagnostics; using System.Drawing; using System.Drawing.Design; using System.Windows.Forms; @@ -8,7 +7,6 @@ namespace RootDesignerDemo.Client.RootDesignerProxy { - [ToolboxItemFilter(ToolboxCategory, ToolboxItemFilterType.Require)] public class ShapeRootProxyDesigner : RootComponentProxyDesigner, IToolboxUser { private const string ToolboxCategory = "SdkShapeRootDesigner"; @@ -25,11 +23,11 @@ public override void Initialize(IComponent component) private void SetupToolboxItems() { - CreateToolboxItem("Line Tool", "LineTool", "ShapeRootDesigner", + CreateToolboxItem("Line Tool", "LineTool", ToolboxCategory, RootDesignerDemo.Client.Properties.Resources.Line); - CreateToolboxItem("Rectangle Tool", "RectangleTool", "ShapeRootDesigner", + CreateToolboxItem("Rectangle Tool", "RectangleTool", ToolboxCategory, RootDesignerDemo.Client.Properties.Resources.Rectangle); - CreateToolboxItem("Text Tool", "TextTool", "ShapeRootDesigner", + CreateToolboxItem("Text Tool", "TextTool", ToolboxCategory, RootDesignerDemo.Client.Properties.Resources.Text); } diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs index ab24e0f..07c4ebf 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs @@ -6,7 +6,7 @@ namespace RootDesignerDemo.Designer.Server; [ToolboxItemFilter(ToolboxCategory, ToolboxItemFilterType.Require)] -public partial class ShapeRootDesigner : ComponentDesigner, IRootDesigner +public partial class ShapeRootDesigner : ComponentDesigner, IRootDesigner { private const string ToolboxCategory = "SdkShapeRootDesigner"; From aacff1f81be148dcdeda7f3e88712809db41ac0c Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Tue, 20 Jun 2023 17:23:10 -0700 Subject: [PATCH 03/11] Update demo/versions. --- .../RootDesignerDemo/Form1.Designer.cs | 51 +++++--- .../Controls/Controls.cs | 18 +++ .../RootDesignerSupportLib.csproj | 3 + .../Directory.Build.targets | 2 +- .../ShapeRootProxyDesigner.cs | 1 + .../RootDesignerDemo.Controls/RdControl.resx | 120 ++++++++++++++++++ .../RootDesignerTestApp/Form1.Designer.cs | 38 ++++-- .../RootDesignerTestApp/Form1.resx | 3 + 8 files changed, 206 insertions(+), 30 deletions(-) create mode 100644 Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Controls/Controls.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdControl.resx diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.Designer.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.Designer.cs index 85553d5..77e4fe1 100644 --- a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.Designer.cs +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerDemo/Form1.Designer.cs @@ -36,12 +36,13 @@ private void InitializeComponent() this.checkBox1 = new System.Windows.Forms.CheckBox(); this.comboBox1 = new System.Windows.Forms.ComboBox(); this.label1 = new System.Windows.Forms.Label(); + this.textBoxEx1 = new RootDesignerDemo.Controls.TextBoxEx(); + this.textBoxEx2 = new RootDesignerDemo.Controls.TextBoxEx(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); // // menuStrip1 // - this.menuStrip1.GripMargin = new System.Windows.Forms.Padding(2, 2, 0, 2); this.menuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32); this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.lkjlkjhlkfhjlkfToolStripMenuItem, @@ -49,14 +50,14 @@ private void InitializeComponent() this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Padding = new System.Windows.Forms.Padding(4, 2, 0, 2); - this.menuStrip1.Size = new System.Drawing.Size(811, 33); + this.menuStrip1.Size = new System.Drawing.Size(721, 28); this.menuStrip1.TabIndex = 0; this.menuStrip1.Text = "menuStrip1"; // // lkjlkjhlkfhjlkfToolStripMenuItem // this.lkjlkjhlkfhjlkfToolStripMenuItem.Name = "lkjlkjhlkfhjlkfToolStripMenuItem"; - this.lkjlkjhlkfhjlkfToolStripMenuItem.Size = new System.Drawing.Size(124, 29); + this.lkjlkjhlkfhjlkfToolStripMenuItem.Size = new System.Drawing.Size(105, 24); this.lkjlkjhlkfhjlkfToolStripMenuItem.Text = "lkjlkjhlkfhjlkf"; // // hkkjhkjhkjkjhkToolStripMenuItem @@ -65,28 +66,28 @@ private void InitializeComponent() this.kjhkjhkjhkToolStripMenuItem, this.klkjlkjljToolStripMenuItem}); this.hkkjhkjhkjkjhkToolStripMenuItem.Name = "hkkjhkjhkjkjhkToolStripMenuItem"; - this.hkkjhkjhkjkjhkToolStripMenuItem.Size = new System.Drawing.Size(138, 29); + this.hkkjhkjhkjkjhkToolStripMenuItem.Size = new System.Drawing.Size(113, 24); this.hkkjhkjhkjkjhkToolStripMenuItem.Text = "hkkjhkjhkjkjhk"; // // kjhkjhkjhkToolStripMenuItem // this.kjhkjhkjhkToolStripMenuItem.Name = "kjhkjhkjhkToolStripMenuItem"; - this.kjhkjhkjhkToolStripMenuItem.Size = new System.Drawing.Size(192, 34); + this.kjhkjhkjhkToolStripMenuItem.Size = new System.Drawing.Size(156, 26); this.kjhkjhkjhkToolStripMenuItem.Text = "kjhkjhkjhk"; // // klkjlkjljToolStripMenuItem // this.klkjlkjljToolStripMenuItem.Name = "klkjlkjljToolStripMenuItem"; - this.klkjlkjljToolStripMenuItem.Size = new System.Drawing.Size(192, 34); + this.klkjlkjljToolStripMenuItem.Size = new System.Drawing.Size(156, 26); this.klkjlkjljToolStripMenuItem.Text = "klkjlkjlj"; // // checkBox1 // this.checkBox1.AutoSize = true; - this.checkBox1.Location = new System.Drawing.Point(165, 334); - this.checkBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.checkBox1.Location = new System.Drawing.Point(147, 267); + this.checkBox1.Margin = new System.Windows.Forms.Padding(4); this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(113, 24); + this.checkBox1.Size = new System.Drawing.Size(95, 20); this.checkBox1.TabIndex = 1; this.checkBox1.Text = "checkBox1"; this.checkBox1.UseVisualStyleBackColor = true; @@ -94,27 +95,43 @@ private void InitializeComponent() // comboBox1 // this.comboBox1.FormattingEnabled = true; - this.comboBox1.Location = new System.Drawing.Point(393, 334); - this.comboBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.comboBox1.Location = new System.Drawing.Point(349, 267); + this.comboBox1.Margin = new System.Windows.Forms.Padding(4); this.comboBox1.Name = "comboBox1"; - this.comboBox1.Size = new System.Drawing.Size(354, 28); + this.comboBox1.Size = new System.Drawing.Size(315, 24); this.comboBox1.TabIndex = 2; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(166, 125); + this.label1.Location = new System.Drawing.Point(148, 100); this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(51, 20); + this.label1.Size = new System.Drawing.Size(44, 16); this.label1.TabIndex = 3; this.label1.Text = "label1"; // + // textBoxEx1 + // + this.textBoxEx1.Location = new System.Drawing.Point(157, 151); + this.textBoxEx1.Name = "textBoxEx1"; + this.textBoxEx1.Size = new System.Drawing.Size(377, 22); + this.textBoxEx1.TabIndex = 4; + // + // textBoxEx2 + // + this.textBoxEx2.Location = new System.Drawing.Point(228, 239); + this.textBoxEx2.Name = "textBoxEx2"; + this.textBoxEx2.Size = new System.Drawing.Size(100, 22); + this.textBoxEx2.TabIndex = 5; + // // Form3 // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(811, 414); + this.ClientSize = new System.Drawing.Size(721, 331); + this.Controls.Add(this.textBoxEx2); + this.Controls.Add(this.textBoxEx1); this.Controls.Add(this.label1); this.Controls.Add(this.comboBox1); this.Controls.Add(this.checkBox1); @@ -140,6 +157,8 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox checkBox1; private System.Windows.Forms.ComboBox comboBox1; private System.Windows.Forms.Label label1; + private Controls.TextBoxEx textBoxEx1; + private Controls.TextBoxEx textBoxEx2; } } diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Controls/Controls.cs b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Controls/Controls.cs new file mode 100644 index 0000000..01ef2bc --- /dev/null +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/Controls/Controls.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; +using System.Windows.Forms; + +namespace RootDesignerDemo.Controls +{ + [ToolboxItemFilter("System.Windows.Forms")] + public class TextBoxEx : TextBox + { + } + + public class ButtonEx : Button + { + } + + public class LabelEx : Label + { + } +} diff --git a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesignerSupportLib.csproj b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesignerSupportLib.csproj index 019f4e8..5e545b5 100644 --- a/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesignerSupportLib.csproj +++ b/Samples/RootDesigner/Framework/RootDesignerDemo/RootDesignerSupportLib/RootDesignerSupportLib.csproj @@ -186,6 +186,9 @@ + + Component + True True diff --git a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets index 57f285a..e75670b 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets +++ b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets @@ -2,7 +2,7 @@ - + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs index 229bd35..66838f4 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs @@ -7,6 +7,7 @@ namespace RootDesignerDemo.Client.RootDesignerProxy { + [ToolboxItemFilter(ToolboxCategory, ToolboxItemFilterType.Require)] public class ShapeRootProxyDesigner : RootComponentProxyDesigner, IToolboxUser { private const string ToolboxCategory = "SdkShapeRootDesigner"; diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdControl.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdControl.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RdControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.Designer.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.Designer.cs index b2d22ae..2f63fb8 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.Designer.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.Designer.cs @@ -28,22 +28,16 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - rdControl1 = new RootDesignerDemo.Controls.RdControl(); button1 = new Button(); checkBox1 = new CheckBox(); + checkBox2 = new CheckBox(); + printDialog1 = new PrintDialog(); SuspendLayout(); // - // rdControl1 - // - rdControl1.Location = new Point(112, 101); - rdControl1.Name = "rdControl1"; - rdControl1.Size = new Size(418, 215); - rdControl1.TabIndex = 0; - rdControl1.Text = "rdControl1"; - // // button1 // - button1.Location = new Point(143, 32); + button1.Location = new Point(142, 32); + button1.Margin = new Padding(2); button1.Name = "button1"; button1.Size = new Size(112, 34); button1.TabIndex = 1; @@ -54,20 +48,37 @@ private void InitializeComponent() // checkBox1.AutoSize = true; checkBox1.Location = new Point(540, 385); + checkBox1.Margin = new Padding(2); checkBox1.Name = "checkBox1"; checkBox1.Size = new Size(121, 29); checkBox1.TabIndex = 2; checkBox1.Text = "checkBox1"; checkBox1.UseVisualStyleBackColor = true; // + // checkBox2 + // + checkBox2.AutoSize = true; + checkBox2.Location = new Point(290, 212); + checkBox2.Margin = new Padding(4, 4, 4, 4); + checkBox2.Name = "checkBox2"; + checkBox2.Size = new Size(121, 29); + checkBox2.TabIndex = 3; + checkBox2.Text = "checkBox2"; + checkBox2.UseVisualStyleBackColor = true; + // + // printDialog1 + // + printDialog1.UseEXDialog = true; + // // Form1 // AutoScaleDimensions = new SizeF(10F, 25F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(800, 450); + Controls.Add(checkBox2); Controls.Add(checkBox1); Controls.Add(button1); - Controls.Add(rdControl1); + Margin = new Padding(2); Name = "Form1"; Text = "Form1"; ResumeLayout(false); @@ -76,8 +87,9 @@ private void InitializeComponent() #endregion - private RootDesignerDemo.Controls.RdControl rdControl1; private Button button1; private CheckBox checkBox1; + private CheckBox checkBox2; + private PrintDialog printDialog1; } -} \ No newline at end of file +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.resx index a395bff..a9d7fb8 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.resx +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/Form1.resx @@ -117,4 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file From 75c2c30d941dd148d0c86be71cc7efb72a728402 Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Fri, 23 Jun 2023 12:08:36 -0700 Subject: [PATCH 04/11] Update sample to match new public API. --- .../ClientServerSample/Directory.Build.targets | 2 +- .../RootDesignerProxy/ShapeRootProxyDesigner.cs | 15 --------------- .../RootDesigner/ShapeRootDesigner.cs | 6 ++++++ 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets index e75670b..40ef405 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets +++ b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets @@ -2,7 +2,7 @@ - + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs index 66838f4..746e330 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs @@ -2,7 +2,6 @@ using System.ComponentModel; using System.Drawing; using System.Drawing.Design; -using System.Windows.Forms; using Microsoft.DotNet.DesignTools.Client.Designers; namespace RootDesignerDemo.Client.RootDesignerProxy @@ -78,19 +77,5 @@ bool IToolboxUser.GetToolSupported(ToolboxItem tool) void IToolboxUser.ToolPicked(ToolboxItem tool) { } - - protected override void OnAfterGetView() - { - // If an IToolboxService was located, update the - // category list. - if (_toolboxService is null) - { - MessageBox.Show("Couldn't retrieve Toolbox Service!"); - } - else - { - SetupToolboxItems(); - } - } } } diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs index 07c4ebf..c964cc3 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs @@ -1,6 +1,7 @@ using System; using System.ComponentModel; using System.ComponentModel.Design; +using System.Diagnostics; using Microsoft.DotNet.DesignTools.Designers; namespace RootDesignerDemo.Designer.Server; @@ -27,6 +28,11 @@ object IRootDesigner.GetView(ViewTechnology technology) { throw new ArgumentException("Not a supported view technology", "technology"); } + + if (Debugger.IsAttached) + { + Debugger.Break(); + } if (_designerSurface == null) { From 7c2913be4a16409be353c62b150cfc0415598746 Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Tue, 4 Jul 2023 10:02:49 -0700 Subject: [PATCH 05/11] Update samples to new API. --- .../Directory.Build.targets | 2 +- .../ShapeRootProxyDesigner.cs | 9 ++++++--- ...=> ShapeRootDesigner.ShapeDesignerView.cs} | 17 +++++++--------- .../RootDesigner/ShapeRootDesigner.cs | 20 ++++--------------- 4 files changed, 18 insertions(+), 30 deletions(-) rename Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/{ShapeRootDesigner.SampleRootDesignerView.cs => ShapeRootDesigner.ShapeDesignerView.cs} (70%) diff --git a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets index 40ef405..6c67725 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets +++ b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets @@ -2,7 +2,7 @@ - + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs index 746e330..d6adf44 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Client/RootDesignerProxy/ShapeRootProxyDesigner.cs @@ -7,7 +7,7 @@ namespace RootDesignerDemo.Client.RootDesignerProxy { [ToolboxItemFilter(ToolboxCategory, ToolboxItemFilterType.Require)] - public class ShapeRootProxyDesigner : RootComponentProxyDesigner, IToolboxUser + public class ShapeRootProxyDesigner : ComponentProxyDesigner, IToolboxUser { private const string ToolboxCategory = "SdkShapeRootDesigner"; @@ -17,7 +17,6 @@ public class ShapeRootProxyDesigner : RootComponentProxyDesigner, IToolboxUser public override void Initialize(IComponent component) { base.Initialize(component); - _toolboxService = (IToolboxService?) GetService(typeof(IToolboxService)); } @@ -39,7 +38,7 @@ private void CreateToolboxItem(string toolDisplayName, string toolTypeName, stri string toolboxItemName = $"{ToolboxCategory}.{toolTypeName}"; - foreach (ToolboxItem existingToolboxItem in _toolboxService.GetToolboxItems(ToolboxCategory)) + foreach (ToolboxItem existingToolboxItem in _toolboxService!.GetToolboxItems(ToolboxCategory)) { if (existingToolboxItem.TypeName != toolboxItemName) { @@ -69,6 +68,10 @@ private void CreateToolboxItem(string toolDisplayName, string toolTypeName, stri return; } + protected override RootDesignerSupport EnableRootDesigner() => RootDesignerSupport.Default; + + protected override void PopulateToolbox() => SetupToolboxItems(); + bool IToolboxUser.GetToolSupported(ToolboxItem tool) { return !(tool.Properties[ToolboxCategory] is null); diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.SampleRootDesignerView.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs similarity index 70% rename from Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.SampleRootDesignerView.cs rename to Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs index 8a6a2ec..83cff71 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.SampleRootDesignerView.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs @@ -1,25 +1,24 @@ -using System.Drawing; +using System.ComponentModel.Design; +using System.Drawing; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.DotNet.DesignTools.Designers; - +using Timer = System.Threading.Timer; namespace RootDesignerDemo.Designer.Server; public partial class ShapeRootDesigner { // RootDesignerView is a simple control that will be displayed // in the designer window. - private class SampleRootDesignerView : RootDesignerView + private class ShapeDesignerView : DesignerScrollableControl { - private ShapeRootDesigner _designer; - private System.Threading.Timer _timer; + private Timer? _timer; private bool _guard; private int _counter = 0; - public SampleRootDesignerView(ShapeRootDesigner designer) + public ShapeDesignerView(IRootDesigner rootDesigner) : base(rootDesigner) { - _designer = designer; BackColor = Color.LightGray; Font = new Font(Font.FontFamily.Name, 24.0f); @@ -43,10 +42,8 @@ private async void TimerProc(object? state) protected override void OnPaint(PaintEventArgs pe) { - base.OnPaint(pe); - // Draws the name of the component in large letters. - pe.Graphics.DrawString($"{_designer.Component.Site.Name}: {_counter}", Font, Brushes.Black, ClientRectangle); + pe.Graphics.DrawString($"{RootDesigner?.Component?.Site?.Name}: {_counter}", Font, Brushes.Black, ClientRectangle); } } } diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs index c964cc3..66fc8aa 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs @@ -15,7 +15,7 @@ public partial class ShapeRootDesigner : ComponentDesigner, IRootDesigner // will be shown in the Forms designer view. This member is // cached to reduce processing needed to recreate the // view control on each call to GetView(). - private RootDesignerView? _designerSurface; + private ShapeDesignerView? _designerView; public ViewTechnology[] SupportedTechnologies => new[] { ViewTechnology.Default }; @@ -29,20 +29,8 @@ object IRootDesigner.GetView(ViewTechnology technology) throw new ArgumentException("Not a supported view technology", "technology"); } - if (Debugger.IsAttached) - { - Debugger.Break(); - } - - if (_designerSurface == null) - { - // Some type of displayable Form or control is required - // for a root designer that overrides GetView(). In this - // example, a Control of type RootDesignerView is used. - // Any class that inherits from Control will work. - _designerSurface = new SampleRootDesignerView(this); - } - - return _designerSurface; + // Important: This method must return the same instance every time it is called! + _designerView ??= new ShapeDesignerView(this); + return _designerView; } } From bbd867121514def0f587596883c1eb72ae919dbb Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Thu, 10 Aug 2023 01:13:03 -0700 Subject: [PATCH 06/11] Update sample to new version. --- .../Directory.Build.targets | 2 +- .../ShapeRootDesigner.ShapeDesignerView.cs | 64 ++++++++++++++++++- .../RootDesigner/ShapeRootDesigner.cs | 1 - 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets index 6c67725..f5c458c 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets +++ b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets @@ -2,7 +2,7 @@ - + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs index 83cff71..2083751 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs @@ -1,4 +1,6 @@ -using System.ComponentModel.Design; +using System; +using System.ComponentModel.Design; +using System.Diagnostics; using System.Drawing; using System.Threading; using System.Threading.Tasks; @@ -16,6 +18,10 @@ private class ShapeDesignerView : DesignerScrollableControl private Timer? _timer; private bool _guard; private int _counter = 0; + private bool _drawControlInProgress; + private Rectangle _currentSelectionArea; + private Point _initialPosition; + private int _debugCount; public ShapeDesignerView(IRootDesigner rootDesigner) : base(rootDesigner) { @@ -25,6 +31,11 @@ public ShapeDesignerView(IRootDesigner rootDesigner) : base(rootDesigner) _timer = new System.Threading.Timer(new TimerCallback(TimerProc), null, 0, 2000); } + // We want a transparent overlay window automatically created to draw adorners on. + // To that end, we return true here. The paint event for that transparent adorner window + // will then surface in the PostPaint event, passing the Graphics object of the adorner window. + protected override bool SupportPostPaint => true; + private async void TimerProc(object? state) { if (_guard) @@ -45,5 +56,56 @@ protected override void OnPaint(PaintEventArgs pe) // Draws the name of the component in large letters. pe.Graphics.DrawString($"{RootDesigner?.Component?.Site?.Name}: {_counter}", Font, Brushes.Black, ClientRectangle); } + + protected override void OnPostPaint(PaintEventArgs e) + { + base.OnPostPaint(e); + } + + protected override void OnMouseDown(MouseButtonDispatchEventArgs e) + { + base.OnMouseDown(e); + _drawControlInProgress= true; + } + + protected override void OnMouseUp(MouseButtonDispatchEventArgs e) + { + _drawControlInProgress = false; + // TODO: OnDrawSelectionFinished. + _initialPosition = Point.Empty; + _currentSelectionArea = Rectangle.Empty; + _debugCount = 0; + } + + protected override void OnMouseMove(InputDispatchEventArgs e) + { + base.OnMouseMove(e); + + if (!_drawControlInProgress) + return; + + _debugCount++; + if (_debugCount>50) + { + if (Debugger.IsAttached) + Debugger.Break(); + + _debugCount = 0; + } + + if (!_initialPosition.IsEmpty) + { + ControlPaint.DrawReversibleFrame(_currentSelectionArea, Color.Black, FrameStyle.Thick); + } + else + { + _initialPosition = e.Location; + } + + Size rectangleSize = new Size(Math.Abs(_initialPosition.X - _initialPosition.X), Math.Abs(e.Location.Y - e.Location.Y)); + _currentSelectionArea = new(_initialPosition, rectangleSize); + + ControlPaint.DrawReversibleFrame(_currentSelectionArea, Color.Black, FrameStyle.Thick); + } } } diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs index 66fc8aa..4248ad6 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.cs @@ -1,7 +1,6 @@ using System; using System.ComponentModel; using System.ComponentModel.Design; -using System.Diagnostics; using Microsoft.DotNet.DesignTools.Designers; namespace RootDesignerDemo.Designer.Server; From 209560686bca5bfe70bf8283c40da32b56033019 Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Thu, 10 Aug 2023 17:23:01 -0700 Subject: [PATCH 07/11] Bump up sample to latest version. --- .../Directory.Build.targets | 2 +- .../ShapeRootDesigner.ShapeDesignerView.cs | 47 +++++++++---------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets index f5c458c..2e270f9 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets +++ b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets @@ -2,7 +2,7 @@ - + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs index 2083751..fe61ef8 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs @@ -1,6 +1,5 @@ using System; using System.ComponentModel.Design; -using System.Diagnostics; using System.Drawing; using System.Threading; using System.Threading.Tasks; @@ -19,9 +18,8 @@ private class ShapeDesignerView : DesignerScrollableControl private bool _guard; private int _counter = 0; private bool _drawControlInProgress; - private Rectangle _currentSelectionArea; private Point _initialPosition; - private int _debugCount; + private Rectangle _screenRectangle; public ShapeDesignerView(IRootDesigner rootDesigner) : base(rootDesigner) { @@ -45,38 +43,40 @@ private async void TimerProc(object? state) await Task.Delay(0); - Invalidate(); + // We are requesting an Invalidation of the internal adorner windows, which we inserted in the stack, + // since this component overwrites SupportPostPaint, and therefore requests a transparent overlay window + // to be created. Its paint event can then be handled in OnPostPaint. + RequestPostPaint(); _counter++; _guard = false; } - protected override void OnPaint(PaintEventArgs pe) - { - // Draws the name of the component in large letters. - pe.Graphics.DrawString($"{RootDesigner?.Component?.Site?.Name}: {_counter}", Font, Brushes.Black, ClientRectangle); - } - + // When SupportPostPaint returns true, we create a transparent overlay, and its OnPaint is handled here. protected override void OnPostPaint(PaintEventArgs e) { - base.OnPostPaint(e); + // Draws the name of the component in large letters. + e.Graphics.DrawString($"{RootDesigner?.Component?.Site?.Name}: {_counter}", Font, Brushes.Black, ClientRectangle); } + // Note: This is NOT the original mouse down, but rather the mouse down, which is + // triggered by the input dispatcher (and originates from the input shield in the client). protected override void OnMouseDown(MouseButtonDispatchEventArgs e) { base.OnMouseDown(e); _drawControlInProgress= true; } + // Note: See note above. protected override void OnMouseUp(MouseButtonDispatchEventArgs e) { _drawControlInProgress = false; // TODO: OnDrawSelectionFinished. _initialPosition = Point.Empty; - _currentSelectionArea = Rectangle.Empty; - _debugCount = 0; + _screenRectangle = Rectangle.Empty; } + // Note: See note above. protected override void OnMouseMove(InputDispatchEventArgs e) { base.OnMouseMove(e); @@ -84,28 +84,23 @@ protected override void OnMouseMove(InputDispatchEventArgs e) if (!_drawControlInProgress) return; - _debugCount++; - if (_debugCount>50) - { - if (Debugger.IsAttached) - Debugger.Break(); - - _debugCount = 0; - } - if (!_initialPosition.IsEmpty) { - ControlPaint.DrawReversibleFrame(_currentSelectionArea, Color.Black, FrameStyle.Thick); + ControlPaint.DrawReversibleFrame(_screenRectangle, Color.Black, FrameStyle.Thick); } else { _initialPosition = e.Location; } - Size rectangleSize = new Size(Math.Abs(_initialPosition.X - _initialPosition.X), Math.Abs(e.Location.Y - e.Location.Y)); - _currentSelectionArea = new(_initialPosition, rectangleSize); + Size rectangleSize = new Size(Math.Abs(_initialPosition.X - e.Location.X), Math.Abs(_initialPosition.Y - e.Location.Y)); + Rectangle currentSelectionArea = new(_initialPosition, rectangleSize); + + Point topLeft = PointToScreen(new Point(currentSelectionArea.Left, currentSelectionArea.Top)); + Point bottomRight = PointToScreen(new Point(currentSelectionArea.Right, currentSelectionArea.Bottom)); + _screenRectangle = new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y); - ControlPaint.DrawReversibleFrame(_currentSelectionArea, Color.Black, FrameStyle.Thick); + ControlPaint.DrawReversibleFrame(_screenRectangle, Color.Black, FrameStyle.Thick); } } } From 637ee0355f70579ec08a48b91c25dd84a10bb298 Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Fri, 11 Aug 2023 12:55:21 -0700 Subject: [PATCH 08/11] Introduce basic Shape classes. --- .../RootDesignerDemo.Controls/EllipseShape.cs | 7 + .../RootDesignerDemo.Controls/LineShape.cs | 7 + .../RectangleShape.cs | 7 + .../RectangleShape.resx | 126 ++++++++++++++++++ .../RootDesignerDemo.Controls/ShapeBase.cs | 59 ++++++++ .../RootDesignerDemo.Controls/ShapeBase.resx | 126 ++++++++++++++++++ 6 files changed, 332 insertions(+) create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/EllipseShape.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/LineShape.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RectangleShape.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RectangleShape.resx create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.cs create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.resx diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/EllipseShape.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/EllipseShape.cs new file mode 100644 index 0000000..63722e3 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/EllipseShape.cs @@ -0,0 +1,7 @@ +namespace RootDesignerDemo.Designer.Server; + +public class EllipseShape : ShapeBase +{ + public override void Render(Graphics g) + => g.DrawEllipse(CurrentPen, new Rectangle(Location, Size)); +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/LineShape.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/LineShape.cs new file mode 100644 index 0000000..8658852 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/LineShape.cs @@ -0,0 +1,7 @@ +namespace RootDesignerDemo.Designer.Server; + +public class LineShape : ShapeBase +{ + public override void Render(Graphics g) + => g.DrawLine(CurrentPen, Location, Location + Size); +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RectangleShape.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RectangleShape.cs new file mode 100644 index 0000000..05fa8db --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RectangleShape.cs @@ -0,0 +1,7 @@ +namespace RootDesignerDemo.Designer.Server; + +public class RectangleShape : ShapeBase +{ + public override void Render(Graphics g) + => g.DrawRectangle(CurrentPen, new Rectangle(Location, Size)); +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RectangleShape.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RectangleShape.resx new file mode 100644 index 0000000..d28be67 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/RectangleShape.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 33, 33 + + + False + + \ No newline at end of file diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.cs new file mode 100644 index 0000000..a91ab36 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.cs @@ -0,0 +1,59 @@ +using System.ComponentModel; + +namespace RootDesignerDemo.Designer.Server; + +public class ShapeBase : Component +{ + public ShapeBase() + { + CurrentPen = Pens.DarkBlue; + CurrentBrush = (SolidBrush)Brushes.DarkBlue; + Location = DefaultLocation; + } + + public static Point DefaultLocation => new Point(20, 20); + public static Size DefaultSize => new Size(40, 40); + + protected Pen CurrentPen { get; } + protected SolidBrush CurrentBrush { get; } + + public Point Location { get; set; } + public Size Size { get; set; } + + public Color PenColor + { + get => CurrentPen.Color; + + set + { + if (CurrentPen.Color == value) + { + return; + } + + CurrentPen.Color = value; + } + } + + public Color FillColor + { + get => CurrentBrush.Color; + + set + { + if (CurrentBrush.Color == value) + { + return; + } + + CurrentBrush.Color = value; + } + } + + public virtual void Render(Graphics g) { } + + private void InitializeComponent() + { + + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.resx b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.resx new file mode 100644 index 0000000..0ab4d62 --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 33, 33 + + + False + + \ No newline at end of file From 07c89e4121acef13e00a3b002e48f291ab6a82f0 Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Thu, 7 Sep 2023 18:36:59 -0700 Subject: [PATCH 09/11] Fix sample to reflect new API (Invalidate of DesignerScrollableControl). --- .../Net/ClientServerSample/Directory.Build.targets | 2 +- .../RootDesignerDemo.Controls/ShapeBase.cs | 5 ----- .../RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs | 5 ++++- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets index 2e270f9..ef5584c 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets +++ b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets @@ -2,7 +2,7 @@ - + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.cs index a91ab36..23163b5 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Controls/ShapeBase.cs @@ -51,9 +51,4 @@ public Color FillColor } public virtual void Render(Graphics g) { } - - private void InitializeComponent() - { - - } } diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs index fe61ef8..0d6c6c4 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs @@ -27,6 +27,9 @@ public ShapeDesignerView(IRootDesigner rootDesigner) : base(rootDesigner) Font = new Font(Font.FontFamily.Name, 24.0f); _timer = new System.Threading.Timer(new TimerCallback(TimerProc), null, 0, 2000); + + // Add a Label and a Button to the Controls Collection: + } // We want a transparent overlay window automatically created to draw adorners on. @@ -46,7 +49,7 @@ private async void TimerProc(object? state) // We are requesting an Invalidation of the internal adorner windows, which we inserted in the stack, // since this component overwrites SupportPostPaint, and therefore requests a transparent overlay window // to be created. Its paint event can then be handled in OnPostPaint. - RequestPostPaint(); + Invalidate(); _counter++; _guard = false; From d09369a7a58bf87bc81eabce7e3720dacb8c2fea Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Sun, 3 Dec 2023 18:09:12 -0800 Subject: [PATCH 10/11] Refactor to use new 1.9-dev APIs. --- .../Directory.Build.targets | 2 +- .../CallerArgumentExpressionAttribute.cs | 3 + .../GlobalUtilities/NullableAttributes.cs | 7 +- .../GlobalUtilities/ThrowHelper.cs | 2 +- .../RootDesigner/BufferedRenderer.cs | 159 ++++++++++++++++++ .../ShapeRootDesigner.ShapeDesignerView.cs | 117 ++++++++++--- .../RootDesignerTestApp/ShapeDocument.cs | 3 - 7 files changed, 262 insertions(+), 31 deletions(-) create mode 100644 Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/BufferedRenderer.cs diff --git a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets index ef5584c..afe6de0 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets +++ b/Samples/RootDesigner/Net/ClientServerSample/Directory.Build.targets @@ -2,7 +2,7 @@ - + diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/CallerArgumentExpressionAttribute.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/CallerArgumentExpressionAttribute.cs index 06b6dc6..f1acd5f 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/CallerArgumentExpressionAttribute.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/CallerArgumentExpressionAttribute.cs @@ -8,6 +8,8 @@ namespace System.Runtime.CompilerServices; +#if NETFRAMEWORK + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] internal sealed class CallerArgumentExpressionAttribute : Attribute { @@ -19,3 +21,4 @@ public CallerArgumentExpressionAttribute(string parameterName) public string ParameterName { get; } } +#endif diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/NullableAttributes.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/NullableAttributes.cs index 83bf2b9..bfa5d93 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/NullableAttributes.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/NullableAttributes.cs @@ -5,10 +5,10 @@ // Note: These attributes were introduced in .NET Core 3.0 and .NET 5. #nullable disable +#if NETFRAMEWORK + namespace System.Diagnostics.CodeAnalysis { - - /// Specifies that null is allowed as an input even if the corresponding type disallows it. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] internal sealed class AllowNullAttribute : Attribute @@ -149,5 +149,6 @@ public MemberNotNullWhenAttribute(bool returnValue, params string[] members) /// Gets field or property member names. public string[] Members { get; } } - } + +#endif diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/ThrowHelper.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/ThrowHelper.cs index ef3186c..fcd5c5a 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/ThrowHelper.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Protocol/GlobalUtilities/ThrowHelper.cs @@ -7,7 +7,7 @@ namespace Microsoft.WinForms.Utilities.Shared; internal static class ThrowHelper { /// - /// Thows an . + /// Throws an . /// /// /// This is marked with NoInlining to ensure that the JIT can better inline calling code. diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/BufferedRenderer.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/BufferedRenderer.cs new file mode 100644 index 0000000..e95b64e --- /dev/null +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/BufferedRenderer.cs @@ -0,0 +1,159 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using Microsoft.DotNet.DesignTools.Designers; + +namespace RootDesignerDemo.Designer.Server; + +public class BufferedRenderer : IDisposable +{ + [DllImport("user32.dll")] + public static extern IntPtr WindowFromDC(IntPtr hdc); + + public event PaintEventHandler? Paint; + + private Bitmap? _activeBitmap; + private Bitmap? _upcomingBitmap; + private DesignerScrollableControl _parentControl; + private bool _disposedValue; + private Control? _adornerOverlay; + + public BufferedRenderer(DesignerScrollableControl parentControl) + { + _parentControl = parentControl ?? throw new ArgumentNullException(nameof(parentControl)); + _parentControl.Resize += OnParentControlResize; + _parentControl.PostPaint += OnParentPostPaint; + } + + private void InitializeBitmaps() + { + if (_disposedValue) + { + throw new ObjectDisposedException(nameof(BufferedRenderer)); + } + + _activeBitmap?.Dispose(); + _upcomingBitmap?.Dispose(); + + if (_parentControl.ClientSize.Width == 0 || _parentControl.ClientSize.Height == 0) + { + return; + } + + _activeBitmap = new Bitmap(_parentControl.ClientSize.Width, _parentControl.ClientSize.Height, PixelFormat.Format32bppArgb); + _upcomingBitmap = new Bitmap(_parentControl.ClientSize.Width, _parentControl.ClientSize.Height, PixelFormat.Format32bppArgb); + + _activeBitmap.MakeTransparent(); + _upcomingBitmap.MakeTransparent(); + + _activeBitmap.Tag = "activeBitmap"; + _upcomingBitmap.Tag = "upcomingBitmap"; + } + + private void OnParentControlResize(object? sender, EventArgs e) + { + InitializeBitmaps(); + Invalidate(); + _adornerOverlay?.Invalidate(); + } + + private void OnParentPostPaint(object? sender, PaintEventArgs e) + { + if (_adornerOverlay is null) + { + IntPtr hwnd = WindowFromDC(e.Graphics.GetHdc()); + _adornerOverlay = Control.FromHandle(hwnd); + } + + if (_activeBitmap is null) + { + return; + } + + OnPaintInternal(); + } + + protected virtual void OnPaint(PaintEventArgs e) + => Paint?.Invoke(this, e); + + public void Invalidate() + { + OnPaintInternal(); + } + + private void OnPaintInternal() + { + if (_upcomingBitmap is null + || _activeBitmap is null + || _adornerOverlay is null) + { + return; + } + + using (Graphics g = Graphics.FromImage(_activeBitmap)) + { + g.Clear(Color.Transparent); + OnPaint(new PaintEventArgs(g, _adornerOverlay.ClientRectangle)); + //SwapBitmaps(); + } + + using (Graphics parentGraphics = _adornerOverlay.CreateGraphics()) + { + var bitmapRectangle = new Rectangle(0, 0, _activeBitmap.Width, _activeBitmap.Height); + + ImageAttributes imageAttributes = new ImageAttributes(); + imageAttributes.SetColorKey(Color.Transparent, Color.Transparent); + + parentGraphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; + + try + { + parentGraphics.DrawImage( + image: _activeBitmap!, + destRect: bitmapRectangle, + srcX: 0, + srcY: 0, + srcWidth: bitmapRectangle.Width, + srcHeight: bitmapRectangle.Height, + srcUnit: GraphicsUnit.Pixel, + imageAttributes); + } + catch (Exception ex) + { + MessageBox.Show($"{ex.Message}\n{ex.StackTrace}"); + } + } + } + + private void SwapBitmaps() + { + var temp = _activeBitmap; + _activeBitmap = _upcomingBitmap; + _upcomingBitmap = temp; + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + _parentControl.Resize -= OnParentControlResize; + _parentControl.PostPaint -= OnParentPostPaint; + _activeBitmap?.Dispose(); + _upcomingBitmap?.Dispose(); + } + + _disposedValue = true; + } + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs index 0d6c6c4..995add5 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs @@ -1,11 +1,12 @@ using System; using System.ComponentModel.Design; using System.Drawing; +using System.Drawing.Drawing2D; using System.Threading; -using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.DotNet.DesignTools.Designers; using Timer = System.Threading.Timer; + namespace RootDesignerDemo.Designer.Server; public partial class ShapeRootDesigner @@ -20,16 +21,32 @@ private class ShapeDesignerView : DesignerScrollableControl private bool _drawControlInProgress; private Point _initialPosition; private Rectangle _screenRectangle; + private BufferedRenderer? _surfaceRenderer; + private GraphicsPath? _currentSelectionRenderer; public ShapeDesignerView(IRootDesigner rootDesigner) : base(rootDesigner) { BackColor = Color.LightGray; + ForeColor = Color.Black; + Font = new Font(Font.FontFamily.Name, 24.0f); _timer = new System.Threading.Timer(new TimerCallback(TimerProc), null, 0, 2000); // Add a Label and a Button to the Controls Collection: + Controls.Add(new Label() + { + Text = "Hello World", + Location = new Point(10, 200), + Size= new Size(200, 50) + }); + Controls.Add(new Button() + { + Text = "Click Me", + Location = new Point(10, 250), + Size = new Size(200, 50) + }); } // We want a transparent overlay window automatically created to draw adorners on. @@ -37,29 +54,71 @@ public ShapeDesignerView(IRootDesigner rootDesigner) : base(rootDesigner) // will then surface in the PostPaint event, passing the Graphics object of the adorner window. protected override bool SupportPostPaint => true; - private async void TimerProc(object? state) + protected override void OnHandleCreated(EventArgs e) { - if (_guard) - return; + base.OnHandleCreated(e); - _guard = true; + // If we had recreate the handle, we need to re-register the SurfaceRenderer. + if (_surfaceRenderer is not null) + { + _surfaceRenderer.Dispose(); + } - await Task.Delay(0); + _surfaceRenderer = new BufferedRenderer(this); + _surfaceRenderer.Paint += SurfaceRendererPaint; + } + protected override void Dispose(bool disposing) + { + if (_surfaceRenderer is not null) + { + _surfaceRenderer.Paint -= SurfaceRendererPaint; + } + base.Dispose(disposing); + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + base.OnPaintBackground(e); + } + + private void TimerProc(object? state) + { // We are requesting an Invalidation of the internal adorner windows, which we inserted in the stack, // since this component overwrites SupportPostPaint, and therefore requests a transparent overlay window // to be created. Its paint event can then be handled in OnPostPaint. - Invalidate(); + if (!this.IsHandleCreated) + { + return; + } - _counter++; - _guard = false; + this.BeginInvoke(new Action(() => + { + try + { + if (_guard) + return; + + _guard = true; + _surfaceRenderer?.Invalidate(); + + _counter++; + _guard = false; + + } + catch (Exception) + { + } + })); } - // When SupportPostPaint returns true, we create a transparent overlay, and its OnPaint is handled here. - protected override void OnPostPaint(PaintEventArgs e) + // When SupportPostPaint returns true, we create a transparent overlay, and route the paint event + // to the Surface Renderer, which is a BufferedRenderer, which will do the adorner painting. + private void SurfaceRendererPaint(object? sender, PaintEventArgs e) { // Draws the name of the component in large letters. - e.Graphics.DrawString($"{RootDesigner?.Component?.Site?.Name}: {_counter}", Font, Brushes.Black, ClientRectangle); + e.Graphics.DrawString($"{RootDesigner?.Component?.Site?.Name}: {_counter}", Font, Brushes.Blue, ClientRectangle); + e.Graphics.DrawPath(Pens.Blue, CurrentSelectionRenderer); } // Note: This is NOT the original mouse down, but rather the mouse down, which is @@ -73,10 +132,27 @@ protected override void OnMouseDown(MouseButtonDispatchEventArgs e) // Note: See note above. protected override void OnMouseUp(MouseButtonDispatchEventArgs e) { + if (!_drawControlInProgress) + return; + + CurrentSelectionRenderer.Reset(); _drawControlInProgress = false; - // TODO: OnDrawSelectionFinished. _initialPosition = Point.Empty; _screenRectangle = Rectangle.Empty; + _surfaceRenderer?.Invalidate(); + } + + internal GraphicsPath CurrentSelectionRenderer + { + get + { + if (_currentSelectionRenderer is null) + { + _currentSelectionRenderer = new GraphicsPath(); + } + + return _currentSelectionRenderer; + } } // Note: See note above. @@ -87,11 +163,7 @@ protected override void OnMouseMove(InputDispatchEventArgs e) if (!_drawControlInProgress) return; - if (!_initialPosition.IsEmpty) - { - ControlPaint.DrawReversibleFrame(_screenRectangle, Color.Black, FrameStyle.Thick); - } - else + if (_initialPosition.IsEmpty) { _initialPosition = e.Location; } @@ -99,11 +171,10 @@ protected override void OnMouseMove(InputDispatchEventArgs e) Size rectangleSize = new Size(Math.Abs(_initialPosition.X - e.Location.X), Math.Abs(_initialPosition.Y - e.Location.Y)); Rectangle currentSelectionArea = new(_initialPosition, rectangleSize); - Point topLeft = PointToScreen(new Point(currentSelectionArea.Left, currentSelectionArea.Top)); - Point bottomRight = PointToScreen(new Point(currentSelectionArea.Right, currentSelectionArea.Bottom)); - _screenRectangle = new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y); - - ControlPaint.DrawReversibleFrame(_screenRectangle, Color.Black, FrameStyle.Thick); + _screenRectangle = currentSelectionArea; + CurrentSelectionRenderer.Reset(); + CurrentSelectionRenderer.AddRectangle(_screenRectangle); + _surfaceRenderer?.Invalidate(); } } } diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.cs index c2b250e..a3695ec 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerTestApp/ShapeDocument.cs @@ -2,9 +2,6 @@ namespace RootDesignerDemo { - // This sample demonstrates how to provide the root designer view, or - // design mode background view, by overriding IRootDesigner.GetView(). - // This sample component inherits from RootDesignedComponent which // uses the SampleRootDesigner. public class ShapeDocument : ShapeDocumentBase From 48f456015536d4118511854df2a213e5a4985789 Mon Sep 17 00:00:00 2001 From: Klaus Loeffelmann Date: Sun, 17 Nov 2024 11:22:23 -0800 Subject: [PATCH 11/11] Updates. --- .../MauiEdit.WinForms.csproj | 5 +- .../RootDesigner/BufferedRenderer.cs | 62 ++++++++++--------- .../ShapeRootDesigner.ShapeDesignerView.cs | 6 +- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/Samples/CommandBinding/MauiEdit.WinForms/MauiEdit.WinForms.csproj b/Samples/CommandBinding/MauiEdit.WinForms/MauiEdit.WinForms.csproj index 5263f9d..2e045e9 100644 --- a/Samples/CommandBinding/MauiEdit.WinForms/MauiEdit.WinForms.csproj +++ b/Samples/CommandBinding/MauiEdit.WinForms/MauiEdit.WinForms.csproj @@ -1,8 +1,9 @@  - true - WinExe + true + true + WinExe net7.0-windows true 10.0 diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/BufferedRenderer.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/BufferedRenderer.cs index e95b64e..866927f 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/BufferedRenderer.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/BufferedRenderer.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; @@ -18,13 +19,16 @@ public class BufferedRenderer : IDisposable private Bitmap? _upcomingBitmap; private DesignerScrollableControl _parentControl; private bool _disposedValue; - private Control? _adornerOverlay; + private Graphics? _adornerGraphics; public BufferedRenderer(DesignerScrollableControl parentControl) { _parentControl = parentControl ?? throw new ArgumentNullException(nameof(parentControl)); _parentControl.Resize += OnParentControlResize; _parentControl.PostPaint += OnParentPostPaint; + + InitializeBitmaps(); + _parentControl.Invalidate(); } private void InitializeBitmaps() @@ -55,16 +59,14 @@ private void InitializeBitmaps() private void OnParentControlResize(object? sender, EventArgs e) { InitializeBitmaps(); - Invalidate(); - _adornerOverlay?.Invalidate(); + _parentControl.Invalidate(); } private void OnParentPostPaint(object? sender, PaintEventArgs e) { - if (_adornerOverlay is null) + if (_adornerGraphics is null) { - IntPtr hwnd = WindowFromDC(e.Graphics.GetHdc()); - _adornerOverlay = Control.FromHandle(hwnd); + _adornerGraphics = Graphics.FromHdc(e.Graphics.GetHdc()); } if (_activeBitmap is null) @@ -72,6 +74,9 @@ private void OnParentPostPaint(object? sender, PaintEventArgs e) return; } + // Draw something on the screen + e.Graphics.DrawLine(Pens.Blue, 10, 10, 100, 100); + OnPaintInternal(); } @@ -87,7 +92,7 @@ private void OnPaintInternal() { if (_upcomingBitmap is null || _activeBitmap is null - || _adornerOverlay is null) + || _adornerGraphics is null) { return; } @@ -95,35 +100,32 @@ private void OnPaintInternal() using (Graphics g = Graphics.FromImage(_activeBitmap)) { g.Clear(Color.Transparent); - OnPaint(new PaintEventArgs(g, _adornerOverlay.ClientRectangle)); + OnPaint(new PaintEventArgs(g, _parentControl.ClientRectangle)); //SwapBitmaps(); } - using (Graphics parentGraphics = _adornerOverlay.CreateGraphics()) - { - var bitmapRectangle = new Rectangle(0, 0, _activeBitmap.Width, _activeBitmap.Height); + var bitmapRectangle = new Rectangle(0, 0, _activeBitmap.Width, _activeBitmap.Height); - ImageAttributes imageAttributes = new ImageAttributes(); - imageAttributes.SetColorKey(Color.Transparent, Color.Transparent); + ImageAttributes imageAttributes = new ImageAttributes(); + imageAttributes.SetColorKey(Color.Transparent, Color.Transparent); - parentGraphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; + _adornerGraphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; - try - { - parentGraphics.DrawImage( - image: _activeBitmap!, - destRect: bitmapRectangle, - srcX: 0, - srcY: 0, - srcWidth: bitmapRectangle.Width, - srcHeight: bitmapRectangle.Height, - srcUnit: GraphicsUnit.Pixel, - imageAttributes); - } - catch (Exception ex) - { - MessageBox.Show($"{ex.Message}\n{ex.StackTrace}"); - } + try + { + //_adornerGraphics.DrawImage( + // image: _activeBitmap!, + // destRect: bitmapRectangle, + // srcX: 0, + // srcY: 0, + // srcWidth: bitmapRectangle.Width, + // srcHeight: bitmapRectangle.Height, + // srcUnit: GraphicsUnit.Pixel, + // imageAttributes); + } + catch (Exception ex) + { + MessageBox.Show($"{ex.Message}\n{ex.StackTrace}"); } } diff --git a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs index 995add5..b344e98 100644 --- a/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs +++ b/Samples/RootDesigner/Net/ClientServerSample/RootDesignerDemo.Server/RootDesigner/ShapeRootDesigner.ShapeDesignerView.cs @@ -66,6 +66,7 @@ protected override void OnHandleCreated(EventArgs e) _surfaceRenderer = new BufferedRenderer(this); _surfaceRenderer.Paint += SurfaceRendererPaint; + Invalidate(); } protected override void Dispose(bool disposing) @@ -77,11 +78,6 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - protected override void OnPaintBackground(PaintEventArgs e) - { - base.OnPaintBackground(e); - } - private void TimerProc(object? state) { // We are requesting an Invalidation of the internal adorner windows, which we inserted in the stack,