├── .gitignore ├── LICENSE ├── README.md ├── Smart.FormDesigner.sln ├── examples └── SimpleDesignerExample │ ├── CustomDesignerControl.Designer.cs │ ├── CustomDesignerControl.cs │ ├── CustomDesignerControl.resx │ ├── MainForm.Designer.cs │ ├── MainForm.cs │ ├── MainForm.resx │ ├── Program.cs │ ├── Properties │ ├── Resources.Designer.cs │ └── Resources.resx │ ├── SimpleDesignerExample.csproj │ ├── Toolbox.cs │ └── images │ ├── align_bottom_16x.png │ ├── align_bottom_on_16x16.png │ ├── align_center_16x.png │ ├── align_left_16x.png │ ├── align_middlle_16x.png │ ├── align_right_16x.png │ ├── align_toGrid_16x.png │ ├── align_top_16x.png │ ├── arrow_cursor_16px.png │ ├── copy_16x.png │ ├── cut_16x.png │ ├── delete_16x.png │ ├── new_form_16x.png │ ├── open_file_16x.png │ ├── preview_16x.png │ ├── redo_16x.png │ ├── same_height_16x.png │ ├── same_size_16x.png │ ├── same_width_16x.png │ ├── save_16x.png │ ├── save_all_16x.png │ └── undo_16x.png └── src └── Smart.FormDesigner ├── AbstractService.cs ├── Constants.cs ├── Controls ├── DesignerControl.cs ├── DesignerControl.resx ├── PropertyboxControl.cs ├── PropertyboxControl.resx ├── Toolbox │ ├── IToolbox.cs │ ├── ToolboxBaseItem.cs │ ├── ToolboxCategoryCollection.cs │ ├── ToolboxCategoryItem.cs │ ├── ToolboxCategoryState.cs │ ├── ToolboxItemDragEventArgs.cs │ ├── ToolboxItemUsedArgs.cs │ ├── ToolboxListControl.cs │ ├── ToolboxPointerItem.cs │ └── ToolboxService.cs ├── ToolboxControl.cs └── ToolboxControl.resx ├── Designer ├── AddingVerbEventArgs.cs ├── AlignType.cs ├── DefaultDesignerTransaction.cs ├── Designer.cs ├── DesignerHost.cs ├── FilterEventArgs.cs ├── Internal │ ├── DesignSurface.cs │ ├── DesignerActions │ │ ├── AddAction.cs │ │ ├── ChangeAction.cs │ │ ├── DesignerAction.cs │ │ ├── MegaAction.cs │ │ └── RemoveAction.cs │ ├── DesignerSite.cs │ ├── ExtenderProvidedProperty.cs │ ├── NestedContainer.cs │ └── RootDesigner.cs ├── ResizeType.cs ├── Serialization │ ├── BinarySerializationAttribute.cs │ ├── DefaultDesignerLoader.cs │ ├── IDesignerLoader.cs │ ├── Internal │ │ ├── ComponentProperty.cs │ │ ├── Extender.cs │ │ ├── InstanceDescriptorLoader.cs │ │ ├── ReferencedCollection.cs │ │ └── ReferencedItem.cs │ ├── LoadModes.cs │ ├── Reader │ │ ├── IReader.cs │ │ ├── ReaderBase.cs │ │ ├── ReaderState.cs │ │ └── XmlFormReader.cs │ ├── StoreEventArgs.cs │ └── Writer │ │ ├── IWriter.cs │ │ └── XmlFormWriter.cs └── Services │ ├── BaseEventBindingService.cs │ ├── ContainerService.cs │ ├── DefaultDesignerOptionService.cs │ ├── DefaultEventBindingService.cs │ ├── DefaultMenuCommandService.cs │ ├── DictionaryService.cs │ ├── EventService.cs │ ├── NameCreationService.cs │ ├── SelectionService.cs │ ├── TypeDescriptorFilterService.cs │ ├── TypeDiscoveryService.cs │ └── TypeResolutionService.cs ├── Disposable.cs ├── Extensions ├── ControlExtensions.cs ├── IDesignerHostExtensions.cs ├── IServiceProviderExtensions.cs ├── ObjectExtensions.cs ├── PointExtensions.cs ├── StringExtensions.cs ├── TypeConverterExtensions.cs └── TypeExtensions.cs ├── Properties ├── Resources.Designer.cs └── Resources.resx ├── Resources ├── arrow_cursor_16px.png ├── launch_16x.png └── normal_16x.png └── Smart.FormDesigner.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ljf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Smart.FormDesigner 2 | FormDesigner 是一个基于.NET C# 开发的 Winform 自定义表单设计组件。支持Xml保存和加载表单,支持控件的拖放和属性设置,支持复制、粘贴、对齐、撤销、重做等设计时操作。 3 | 4 | Install via NuGet 5 | ------------ 6 | ``` 7 | PM> Install-Package Smart.FormDesigner 8 | ``` 9 | Link [https://www.nuget.org/packages/Smart.FormDesigner](https://www.nuget.org/packages/Smart.FormDesigner) 10 | 11 | Requirements 12 | ------------ 13 | * .NET Framework 4.0 and above. 14 | 15 | Components 16 | ------------ 17 | * Designer 18 | * DefaultDesignerLoader 19 | 20 | Controls 21 | ------------ 22 | * DesignerControl 23 | * ToolboxControl 24 | * PropertyboxControl 25 | 26 | Demo 27 | ------------ 28 | ![Demo](https://github.com/SmallAnts/FormDesigner.Demo/blob/master/images/demo1.png) 29 | -------------------------------------------------------------------------------- /Smart.FormDesigner.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32602.215 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Smart.FormDesigner", "src\Smart.FormDesigner\Smart.FormDesigner.csproj", "{B75B4A45-A86B-4C9D-9DA1-38FC3ABA9BCD}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleDesignerExample", "examples\SimpleDesignerExample\SimpleDesignerExample.csproj", "{FCEA9F76-90C4-4A7A-8A07-28450A03838B}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {B75B4A45-A86B-4C9D-9DA1-38FC3ABA9BCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {B75B4A45-A86B-4C9D-9DA1-38FC3ABA9BCD}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {B75B4A45-A86B-4C9D-9DA1-38FC3ABA9BCD}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {B75B4A45-A86B-4C9D-9DA1-38FC3ABA9BCD}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {FCEA9F76-90C4-4A7A-8A07-28450A03838B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {FCEA9F76-90C4-4A7A-8A07-28450A03838B}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {FCEA9F76-90C4-4A7A-8A07-28450A03838B}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {FCEA9F76-90C4-4A7A-8A07-28450A03838B}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {4A54EF72-BA69-42FE-8353-D2F32BB5682A} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/CustomDesignerControl.Designer.cs: -------------------------------------------------------------------------------- 1 | using Smart.FormDesigner; 2 | using Smart.FormDesigner.Serialization; 3 | 4 | namespace SimpleDesignerExample 5 | { 6 | partial class CustomDesignerControl 7 | { 8 | 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | protected override void Dispose(bool disposing) 12 | { 13 | if (disposing && (components != null)) 14 | { 15 | components.Dispose(); 16 | } 17 | base.Dispose(disposing); 18 | } 19 | 20 | #region Windows Form Designer generated code 21 | 22 | private void InitializeComponent() 23 | { 24 | this.components = new System.ComponentModel.Container(); 25 | this.defaultDesignerLoader1 = new Smart.FormDesigner.Serialization.DefaultDesignerLoader(); 26 | this.designer1 = new Smart.FormDesigner.Designer(); 27 | this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components); 28 | ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit(); 29 | this.SuspendLayout(); 30 | // 31 | // designer1 32 | // 33 | this.designer1.DesignedForm = this; 34 | this.designer1.DesignerLoader = this.defaultDesignerLoader1; 35 | this.designer1.GridSize = new System.Drawing.Size(8, 8); 36 | // 37 | // PrintDesignerControl 38 | // 39 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 40 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 41 | this.BackColor = System.Drawing.Color.White; 42 | this.Name = "PrintDesignerControl"; 43 | this.Size = new System.Drawing.Size(420, 267); 44 | ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit(); 45 | this.ResumeLayout(false); 46 | 47 | } 48 | 49 | #endregion 50 | private DefaultDesignerLoader defaultDesignerLoader1; 51 | private Designer designer1; 52 | private System.Windows.Forms.BindingSource bindingSource1; 53 | } 54 | } -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/CustomDesignerControl.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | 5 | namespace SimpleDesignerExample 6 | { 7 | public partial class CustomDesignerControl : UserControl 8 | { 9 | public CustomDesignerControl() 10 | { 11 | InitializeComponent(); 12 | } 13 | 14 | #region Browsable false 15 | 16 | [Browsable(false)] 17 | protected override bool DoubleBuffered { get { return base.DoubleBuffered; } set { base.DoubleBuffered = value; } } 18 | [Browsable(false)] 19 | public new string AccessibleDescription { get { return base.AccessibleDescription; } } 20 | [Browsable(false)] 21 | public new string AccessibleName { get { return base.AccessibleName; } } 22 | [Browsable(false)] 23 | public new AccessibleRole AccessibleRole { get { return base.AccessibleRole; } } 24 | [Browsable(false)] 25 | public override bool AllowDrop { get { return base.AllowDrop; } } 26 | [ReadOnly(true)] 27 | [Browsable(false)] 28 | public new AutoScaleMode AutoScaleMode { get; set; } 29 | [Browsable(false)] 30 | public override bool AutoScroll { get { return base.AutoScroll; } } 31 | [Browsable(false)] 32 | public new Size AutoScrollMargin { get { return base.AutoScrollMargin; } } 33 | [Browsable(false)] 34 | public new Size AutoScrollMinSize { get { return base.AutoScrollMinSize; } } 35 | [Browsable(false)] 36 | public override bool AutoSize { get { return base.AutoSize; } } 37 | [Browsable(false)] 38 | public new AutoSizeMode AutoSizeMode { get { return base.AutoSizeMode; } } 39 | [Browsable(false)] 40 | public override AutoValidate AutoValidate { get { return base.AutoValidate; } } 41 | [Browsable(false)] 42 | public override Color BackColor { get { return base.BackColor; } } 43 | [Browsable(false)] 44 | public override Image BackgroundImage { get { return base.BackgroundImage; } } 45 | [Browsable(false)] 46 | public override ImageLayout BackgroundImageLayout { get { return base.BackgroundImageLayout; } } 47 | [Browsable(false)] 48 | public new bool CausesValidation { get { return base.CausesValidation; } } 49 | [Browsable(false)] 50 | public override ContextMenuStrip ContextMenuStrip { get { return base.ContextMenuStrip; } } 51 | [Browsable(false)] 52 | public override Cursor Cursor { get { return base.Cursor; } } 53 | [Browsable(false)] 54 | [DefaultValue(null)] 55 | public new ControlBindingsCollection DataBindings { get { return null; } } 56 | [Browsable(false)] 57 | public new bool Enabled { get { return base.Enabled; } } 58 | [Browsable(false)] 59 | public override Font Font { get { return base.Font; } } 60 | [Browsable(false)] 61 | public override Color ForeColor { get { return base.ForeColor; } } 62 | [Browsable(false)] 63 | public new ImeMode ImeMode { get { return base.ImeMode; } } 64 | [Browsable(false)] 65 | public new Point Location { get { return base.Location; } set { base.Location = value; } } 66 | [Browsable(false)] 67 | public new Padding Margin { get { return base.Margin; } } 68 | [Browsable(false)] 69 | public override Size MaximumSize { get { return base.MaximumSize; } } 70 | [Browsable(false)] 71 | public override Size MinimumSize { get { return base.MinimumSize; } } 72 | [Browsable(false)] 73 | public new Padding Padding { get { return base.Padding; } } 74 | [Browsable(false)] 75 | public override RightToLeft RightToLeft { get { return base.RightToLeft; } } 76 | [Browsable(false)] 77 | public new object Tag { get { return base.Tag; } } 78 | [Browsable(false)] 79 | public new bool UseWaitCursor { get { return base.UseWaitCursor; } } 80 | #endregion 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/CustomDesignerControl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 211, 17 125 | 126 | 127 | 321, 17 128 | 129 | -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.Design; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Windows.Forms; 6 | using Smart.FormDesigner; 7 | 8 | namespace SimpleDesignerExample 9 | { 10 | public partial class MainForm : Form 11 | { 12 | private DesignerControl designerControl; 13 | private Designer designer => designerControl?.Designer; 14 | 15 | public MainForm() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | 21 | 22 | private void Designed_KeyDown(object sender, KeyEventArgs e) 23 | { 24 | if (e.KeyCode == Keys.Delete) 25 | this.designer.DeleteSelected(); 26 | else if (e.Control == true && e.KeyCode == Keys.A) 27 | this.designer.SelectAll(); 28 | else if (e.Control == true && e.KeyCode == Keys.C) 29 | this.designer.CopyControls(); 30 | else if (e.Control == true && e.KeyCode == Keys.V) 31 | this.designer.PasteControls(); 32 | else if (e.Control == true && e.KeyCode == Keys.Z) 33 | this.designer.Undo(); 34 | else if (e.Control == true && e.KeyCode == Keys.Y) 35 | this.designer.Redo(); 36 | } 37 | 38 | 39 | private void SelectionChanged(object sender, EventArgs e) 40 | { 41 | var selectionService = (ISelectionService)sender; 42 | int selectionCount = selectionService.SelectionCount; 43 | 44 | // 更新按钮状态 45 | EnableAlignResize(selectionCount > 1); 46 | if (selectionCount >= 1) 47 | { 48 | //this.tbDeleteSelection.Enabled = true; 49 | //this.tbCopy.Enabled = true; 50 | this.tbDelete.Enabled = true; 51 | } 52 | else 53 | { 54 | //this.tbDeleteSelection.Enabled = false; 55 | //this.tbCopy.Enabled = false; 56 | this.tbDelete.Enabled = false; 57 | } 58 | 59 | // /更新属性框 60 | this.propertyBox.Designer = this.designerControl.Designer; 61 | if (selectionCount == 0) 62 | { 63 | this.propertyBox.SetSelectedObjects(this.designerControl.DesignedForm); 64 | } 65 | else 66 | { 67 | var selected = new object[selectionCount]; 68 | selectionService.GetSelectedComponents().CopyTo(selected, 0); 69 | this.propertyBox.SetSelectedObjects(selected); 70 | } 71 | } 72 | private void ComponentAdded(object sender, ComponentEventArgs e) 73 | { 74 | this.propertyBox.SetComponents(this.designer.DesignerHost.Container.Components); 75 | 76 | EnableUndoRedo(); 77 | } 78 | private void ComponentRemoved(object sender, ComponentEventArgs e) 79 | { 80 | this.propertyBox.SetComponents(this.designer.DesignerHost.Container.Components); 81 | 82 | EnableUndoRedo(); 83 | } 84 | private void ComponentChanged(object sender, ComponentChangedEventArgs e) 85 | { 86 | EnableUndoRedo(); 87 | } 88 | 89 | private void EnableAlignResize(bool enable) 90 | { 91 | this.tbAlignBottom.Enabled = enable; 92 | this.tbAlignMiddle.Enabled = enable; 93 | this.tbAlignTop.Enabled = enable; 94 | this.tbAlignCenter.Enabled = enable; 95 | this.tbAlignRight.Enabled = enable; 96 | this.tbAlignLeft.Enabled = enable; 97 | 98 | this.tbAlignBottom.Enabled = enable; 99 | this.tbAlignMiddle.Enabled = enable; 100 | this.tbAlignTop.Enabled = enable; 101 | this.tbAlignCenter.Enabled = enable; 102 | this.tbAlignLeft.Enabled = enable; 103 | this.tbAlignRight.Enabled = enable; 104 | 105 | this.tbSameBoth.Enabled = enable; 106 | this.tbSameWidth.Enabled = enable; 107 | this.tbSameHeight.Enabled = enable; 108 | 109 | this.tbSameBoth.Enabled = enable; 110 | this.tbSameWidth.Enabled = enable; 111 | this.tbSameHeight.Enabled = enable; 112 | } 113 | 114 | private void EnableUndoRedo() 115 | { 116 | tbUndo.Enabled = (this.designer?.UndoCount > 0); 117 | tbRedo.Enabled = (this.designer?.RedoCount > 0); 118 | 119 | tbUndo.Enabled = (this.designer?.UndoCount > 0); 120 | tbRedo.Enabled = (this.designer?.RedoCount > 0); 121 | } 122 | 123 | private void tbNewForm_Click(object sender, EventArgs e) 124 | { 125 | if (designerControl != null) 126 | { 127 | designerControl.Dispose(); 128 | } 129 | 130 | designerControl = new DesignerControl(new CustomDesignerControl()); 131 | designerControl.Dock = DockStyle.Fill; 132 | designerControl.BackColor = Color.WhiteSmoke; 133 | designerControl.Designer.SelectionService.SelectionChanged += SelectionChanged; 134 | designerControl.Designer.ComponentChangeService.ComponentAdded += ComponentAdded; 135 | designerControl.Designer.ComponentChangeService.ComponentRemoved += ComponentRemoved; 136 | designerControl.Designer.ComponentChangeService.ComponentChanged += ComponentChanged; 137 | this.splitContainer1.Panel1.Controls.Add(designerControl); 138 | this.toolbox1.Designer = designerControl.Designer; 139 | this.designer.KeyDown += Designed_KeyDown; 140 | tbSaveForm.Enabled = true; 141 | 142 | } 143 | 144 | private void tbOpenForm_Click(object sender, EventArgs e) 145 | { 146 | var openFileName = new OpenFileDialog(); 147 | 148 | openFileName.Filter = "XML text format (*.xml)|*.xml"; 149 | openFileName.FilterIndex = 1; 150 | openFileName.RestoreDirectory = true; 151 | 152 | if (openFileName.ShowDialog() == DialogResult.OK) 153 | { 154 | tbNewForm_Click(sender, e); 155 | 156 | if (openFileName.FilterIndex == 1) 157 | { 158 | var txtReader = new StreamReader(openFileName.FileName); 159 | string layoutString = txtReader.ReadToEnd(); 160 | txtReader.Close(); 161 | 162 | this.designer.LayoutXML = layoutString; 163 | } 164 | else 165 | { 166 | this.designer.LoadFromFile(openFileName.FileName); 167 | } 168 | tbSaveForm.Enabled = true; 169 | } 170 | } 171 | 172 | private void tbSaveForm_Click(object sender, EventArgs e) 173 | { 174 | var saveFileName = new SaveFileDialog(); 175 | saveFileName.Filter = "XML Form (*.xml)|*.xml"; 176 | saveFileName.FilterIndex = 1; 177 | saveFileName.RestoreDirectory = true; 178 | 179 | if (saveFileName.ShowDialog() == DialogResult.OK) 180 | { 181 | string test = this.designer.LayoutXML; 182 | 183 | TextWriter txtWriter = new StreamWriter(saveFileName.FileName); 184 | txtWriter.Write(test); 185 | txtWriter.Close(); 186 | } 187 | } 188 | 189 | private void tbPreview_Click(object sender, EventArgs e) 190 | { 191 | 192 | } 193 | 194 | private void tbUndo_Click(object sender, EventArgs e) 195 | { 196 | this.designer.Undo(); 197 | tbUndo.Enabled = (this.designer.UndoCount != 0); 198 | tbRedo.Enabled = (this.designer.RedoCount != 0); 199 | } 200 | 201 | private void tbRedo_Click(object sender, EventArgs e) 202 | { 203 | this.designer.Redo(); 204 | tbUndo.Enabled = (this.designer.UndoCount != 0); 205 | tbRedo.Enabled = (this.designer.RedoCount != 0); 206 | } 207 | 208 | private void tbDelete_Click(object sender, EventArgs e) 209 | { 210 | this.designer.DeleteSelected(); 211 | } 212 | 213 | private void tbAlignLeft_Click(object sender, EventArgs e) 214 | { 215 | this.designer.Align(AlignType.Left); 216 | } 217 | 218 | private void tbAlignCenter_Click(object sender, EventArgs e) 219 | { 220 | this.designer.Align(AlignType.Center); 221 | } 222 | 223 | private void tbAlignRight_Click(object sender, EventArgs e) 224 | { 225 | this.designer.Align(AlignType.Right); 226 | } 227 | 228 | private void tbAlignTop_Click(object sender, EventArgs e) 229 | { 230 | this.designer.Align(AlignType.Top); 231 | } 232 | 233 | private void tbAlignMiddle_Click(object sender, EventArgs e) 234 | { 235 | this.designer.Align(AlignType.Middle); 236 | } 237 | 238 | private void tbAlignBottom_Click(object sender, EventArgs e) 239 | { 240 | this.designer.Align(AlignType.Bottom); 241 | } 242 | 243 | private void tbSameWidth_Click(object sender, EventArgs e) 244 | { 245 | this.designer.MakeSameSize(ResizeType.SameWidth); 246 | } 247 | 248 | private void tbSameHeight_Click(object sender, EventArgs e) 249 | { 250 | this.designer.MakeSameSize(ResizeType.SameHeight); 251 | } 252 | 253 | private void tbSameBoth_Click(object sender, EventArgs e) 254 | { 255 | this.designer.MakeSameSize(ResizeType.SameHeight | ResizeType.SameWidth); 256 | } 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/MainForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 174, 6 122 | 123 | 124 | 30, 10 125 | 126 | 127 | 286, 9 128 | 129 | 130 | 47 131 | 132 | -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace SimpleDesignerExample 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// 应用程序的主入口点。 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new MainForm()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/SimpleDesignerExample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net40 5 | true 6 | 7 | WinExe 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | True 18 | True 19 | Resources.resx 20 | 21 | 22 | ResXFileCodeGenerator 23 | Resources.Designer.cs 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/Toolbox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing.Design; 5 | using System.Windows.Forms; 6 | using SimpleDesignerExample.Properties; 7 | using Smart.FormDesigner; 8 | using Smart.FormDesigner.Toolbox; 9 | 10 | namespace SimpleDesignerExample 11 | { 12 | internal class Toolbox : ToolStrip, IToolbox 13 | { 14 | private ToolboxService _toolboxService; 15 | 16 | public Toolbox() 17 | { 18 | this.DoubleBuffered = true; 19 | this.ItemClicked += Toolbox_ItemClicked; 20 | this._toolboxService = new ToolboxService(this); 21 | this.LoadItems(); 22 | } 23 | 24 | private void LoadItems() 25 | { 26 | this.Items.Add(new ToolStripButton(Resources.arrow_cursor_16px)); 27 | this._toolboxService.AddToolboxItem(CreateToolboxItem(typeof(Label))); 28 | this._toolboxService.AddToolboxItem(CreateToolboxItem(typeof(PictureBox))); 29 | this._toolboxService.AddToolboxItem(CreateToolboxItem(typeof(DataGridView))); 30 | this._toolboxService.AddToolboxItem(CreateToolboxItem(typeof(BindingSource))); 31 | } 32 | 33 | private void Toolbox_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 34 | { 35 | if (e.ClickedItem.Tag is ToolboxBaseItem baseItem && baseItem.Tag is ToolboxItem item) 36 | { 37 | this.SelectedItem = item; 38 | return; 39 | } 40 | this.SelectedItem = null; 41 | } 42 | private void Button_MouseMove(object sender, MouseEventArgs e) 43 | { 44 | if ((e.Button & MouseButtons.Left) != 0) 45 | { 46 | if (BeginDragAndDrop != null) 47 | { 48 | if (((ToolStripButton)sender).Tag is ToolboxBaseItem item) 49 | { 50 | this.SelectedItem = item.Tag as ToolboxItem; 51 | BeginDragAndDrop.Invoke(this, new ToolboxItemDragEventArgs(item)); 52 | } 53 | } 54 | return; 55 | } 56 | 57 | } 58 | private void Button_DoubleClick(object sender, EventArgs e) 59 | { 60 | var item = (ToolStripButton)sender; 61 | if (item.Tag is ToolboxBaseItem && DropControl != null) 62 | DropControl(this, EventArgs.Empty); 63 | } 64 | private ToolboxItem CreateToolboxItem(Type type) 65 | { 66 | try 67 | { 68 | if (!(TypeDescriptor.GetAttributes(type)[typeof(ToolboxItemAttribute)] is ToolboxItemAttribute attr)) 69 | { 70 | return new ToolboxItem(type); 71 | } 72 | 73 | var ctor = attr.ToolboxItemType.GetConstructor(new Type[] { }); 74 | if (ctor == null) 75 | { 76 | return new ToolboxItem(type); 77 | } 78 | var tbi = (ToolboxItem)ctor.Invoke(default); 79 | tbi.Initialize(type); 80 | return tbi; 81 | } 82 | catch (Exception) 83 | { 84 | //throw ex; 85 | return new ToolboxItem(type); 86 | } 87 | 88 | } 89 | 90 | [Browsable(false)] 91 | [DefaultValue(null)] 92 | public Designer Designer 93 | { 94 | set 95 | { 96 | _toolboxService.Designer = value; 97 | } 98 | get 99 | { 100 | return _toolboxService.Designer; 101 | } 102 | } 103 | 104 | ToolboxCategoryCollection IToolbox.Items 105 | { 106 | get 107 | { 108 | var tbItems = new ToolboxCategoryItem[1]; 109 | var items = new List(); 110 | foreach (ToolStripItem item in this.Items) 111 | { 112 | if (item.Tag is ToolboxBaseItem baseItem) 113 | { 114 | items.Add((ToolboxItem)baseItem.Tag); 115 | } 116 | } 117 | tbItems[0] = new ToolboxCategoryItem("controls", new ToolboxItemCollection(items.ToArray())); 118 | return new ToolboxCategoryCollection(tbItems); 119 | } 120 | } 121 | 122 | [Browsable(false)] 123 | [DefaultValue(null)] 124 | public ToolboxItem SelectedItem { get; set; } 125 | 126 | [Browsable(false)] 127 | [DefaultValue(null)] 128 | public string SelectedCategory { get; set; } 129 | 130 | public event EventHandler BeginDragAndDrop; 131 | public event EventHandler DropControl; 132 | 133 | public void AddItem(ToolboxItem item, string category) 134 | { 135 | var button = new ToolStripButton() { Image = item.Bitmap, Tag = new ToolboxBaseItem(item.DisplayName, 0, item), DoubleClickEnabled = true }; 136 | button.DoubleClick += Button_DoubleClick; 137 | button.MouseMove += Button_MouseMove; 138 | this.Items.Add(button); 139 | } 140 | 141 | public void RemoveItem(ToolboxItem item, string category) 142 | { 143 | this.Items.RemoveByKey(item.DisplayName); 144 | } 145 | 146 | public void AddCategory(string text) => throw new NotImplementedException(); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/align_bottom_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/align_bottom_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/align_bottom_on_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/align_bottom_on_16x16.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/align_center_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/align_center_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/align_left_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/align_left_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/align_middlle_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/align_middlle_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/align_right_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/align_right_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/align_toGrid_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/align_toGrid_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/align_top_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/align_top_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/arrow_cursor_16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/arrow_cursor_16px.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/copy_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/copy_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/cut_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/cut_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/delete_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/delete_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/new_form_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/new_form_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/open_file_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/open_file_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/preview_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/preview_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/redo_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/redo_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/same_height_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/same_height_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/same_size_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/same_size_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/same_width_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/same_width_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/save_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/save_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/save_all_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/save_all_16x.png -------------------------------------------------------------------------------- /examples/SimpleDesignerExample/images/undo_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/examples/SimpleDesignerExample/images/undo_16x.png -------------------------------------------------------------------------------- /src/Smart.FormDesigner/AbstractService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Smart.FormDesigner 4 | { 5 | public abstract class AbstractService : Disposable 6 | { 7 | protected IServiceProvider ServiceProvider { get; private set; } 8 | 9 | public AbstractService() 10 | { 11 | 12 | } 13 | 14 | public AbstractService(IServiceProvider serviceProvider) 15 | { 16 | this.ServiceProvider = serviceProvider; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Smart.FormDesigner 7 | { 8 | internal class Constants 9 | { 10 | public const string CLIPBOARD_FORMAT = "_SmartFormDesigner_Controls"; 11 | 12 | public const string DEFAULT_NAME_DESIGNSURFACE = "DesignSurface1"; 13 | 14 | public const string ADD_RANGE_METHOD_NAME = "AddRange"; 15 | 16 | public const string ATTR_COLLECTION = "collection"; 17 | public const string ATTR_CONTENT = "content"; 18 | public const string ATTR_CONTROL = "control"; 19 | 20 | public const string ATTR_MODE = "mode"; 21 | public const string ATTR_MODE_BINARY = "binary"; 22 | public const string ATTR_MODE_CONSTRUCTOR = "constructor"; 23 | public const string ATTR_MODE_INSTANCE_DESCRIPTOR = "instance_descriptor"; 24 | public const string ATTR_MODE_REFERENCE = "reference"; 25 | 26 | public const string ATTR_NAME = "name"; 27 | public const string ATTR_EVENT_NAME = "event_name"; 28 | public const string ATTR_LENGTH="Length"; 29 | 30 | public const string ATTR_NULL = "null"; 31 | 32 | public const string ATTR_PROVIDER = "provider"; 33 | public const string ATTR_PROP_TYPE = "prop_type"; 34 | 35 | public const string ATTR_TYPE = "type"; 36 | public const string ATTR_VERSION = "version"; 37 | 38 | public const string NODE_DATA = "Data"; 39 | public const string NODE_EVENT = "Event"; 40 | public const string NODE_OBJECT = "Object"; 41 | public const string NODE_OBJECT_COLLECTION = "ObjectCollection"; 42 | public const string NODE_PARAM = "Param"; 43 | 44 | public const string DESIGNED_FORM = "DesignedForm"; 45 | public const string VERSION_ID = "1.0"; 46 | 47 | public const string PROP_NAME_CONTROLS = "Controls"; 48 | public const string PROP_NAME_NAME = "Name"; 49 | public const string PROP_NAME_LENGTH = "Length"; 50 | public const string PROP_NAME_VISIBLE = "Visible"; 51 | public const string PROP_NAME_SIZE = "Size"; 52 | public const string PROP_NAME_LOCATION = "Location"; 53 | 54 | public const string STR_TRUE = "true"; 55 | public const string TYPE_ARRAY_STRING = "String[]"; 56 | 57 | public const string STYLE_KEY_HIGHLIGHTCOLOR = "HighlightColor"; 58 | public const string STYLE_KEY_DIALOGFONT = "DialogFont"; 59 | 60 | public const string DESIGNER_OPTION_USESNAPLINES = "UseSnapLines"; 61 | public const string DESIGNER_OPTION_SNAPTOGRID = "SnapToGrid"; 62 | public const string DESIGNER_OPTION_SHOWGRID = "ShowGrid"; 63 | public const string DESIGNER_OPTION_GRIDSIZE = "GridSize"; 64 | public const string DESIGNER_OPTION_OBSTAS = "ObjectBoundSmartTagAutoShow"; 65 | public const string DESIGNER_OPTION_USESMARTTAGS = "UseSmartTags"; 66 | 67 | public const string FILE_EXT_XML = ".xml"; 68 | 69 | public const string TRANS_PRASE = "Paste controls"; 70 | public const string TRANS_SENDTOBACK ="Send To Back"; 71 | public const string TRANS_MAKESAMESIZE = "Make Same Size"; 72 | public const string TRANS_ALIGN = "Align"; 73 | public const string TRANS_ADD_COMPONENT = "Add component"; 74 | public const string TRANS_REMOVE_COMPONENT = "Remove component"; 75 | public const string TRANS_CREATE_COMPONENT = "Create component"; 76 | 77 | 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/DesignerControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using Smart.FormDesigner.Serialization; 4 | 5 | namespace Smart.FormDesigner 6 | { 7 | /// 8 | /// 9 | /// 10 | public partial class DesignerControl : UserControl 11 | { 12 | public Control DesignedForm 13 | { 14 | get { return this.Designer.DesignedForm; } 15 | private set { this.Designer.DesignedForm = value; } 16 | } 17 | 18 | public IDesignerLoader DesignerLoader { get => this.Designer?.DesignerLoader; } 19 | 20 | public Designer Designer { get => this.designer; } 21 | 22 | #region 构造函数 23 | 24 | public DesignerControl() 25 | { 26 | InitializeComponent(); 27 | } 28 | 29 | public DesignerControl(Control root) : this() 30 | { 31 | this.DesignedForm = root; 32 | } 33 | 34 | public DesignerControl(Control root, string layoutXml) : this() 35 | { 36 | this.DesignedForm = root; 37 | this.Designer.LayoutXML = layoutXml; 38 | } 39 | 40 | #endregion 41 | 42 | protected override void OnLoad(EventArgs e) 43 | { 44 | base.OnLoad(e); 45 | if (DesignMode) return; 46 | 47 | this.Designer.DesignContainer = this; 48 | this.Dock = DockStyle.Fill; 49 | if (this.DesignedForm != null) 50 | { 51 | this.Designer.Active = true; 52 | } 53 | } 54 | 55 | #region 设计器自动生成的代码 56 | 57 | /// 58 | /// 必需的设计器变量。 59 | /// 60 | private System.ComponentModel.IContainer components = null; 61 | 62 | /// 63 | /// 清理所有正在使用的资源。 64 | /// 65 | /// 如果应释放托管资源,为 true;否则为 false。 66 | protected override void Dispose(bool disposing) 67 | { 68 | if (disposing && (components != null)) 69 | { 70 | components.Dispose(); 71 | } 72 | base.Dispose(disposing); 73 | } 74 | 75 | /// 76 | /// 设计器支持所需的方法 - 不要修改 77 | /// 使用代码编辑器修改此方法的内容。 78 | /// 79 | private void InitializeComponent() 80 | { 81 | this.defaultDesignerLoader = new Smart.FormDesigner.Serialization.DefaultDesignerLoader(); 82 | this.designer = new Smart.FormDesigner.Designer(); 83 | this.SuspendLayout(); 84 | // 85 | // designer 86 | // 87 | this.designer.DesignerLoader = this.defaultDesignerLoader; 88 | this.designer.GridSize = new System.Drawing.Size(8, 8); 89 | // 90 | // DesignerControl 91 | // 92 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 93 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 94 | this.BackColor = System.Drawing.Color.White; 95 | this.Name = "DesignerControl"; 96 | this.Size = new System.Drawing.Size(339, 374); 97 | this.ResumeLayout(false); 98 | 99 | } 100 | 101 | private DefaultDesignerLoader defaultDesignerLoader; 102 | private Designer designer; 103 | 104 | #endregion 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/DesignerControl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 120, 17 122 | 123 | 124 | 17, 17 125 | 126 | 127 | True 128 | 129 | 130 | 54 131 | 132 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/PropertyboxControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Drawing; 4 | using System.Windows.Forms; 5 | using System.Windows.Forms.Design; 6 | using Smart.FormDesigner.Internal; 7 | 8 | namespace Smart.FormDesigner 9 | { 10 | /// 11 | /// 设计时属性控件 12 | /// 13 | public class PropertyboxControl : UserControl 14 | { 15 | private PropertyGrid propertyGrid; 16 | private ComboBox comboBox; 17 | 18 | public bool ShowEventTab { get; set; } 19 | 20 | private Designer _designer; 21 | public Designer Designer 22 | { 23 | get { return _designer; } 24 | set 25 | { 26 | if (this._designer != value) 27 | { 28 | this._designer = value; 29 | if (ShowEventTab) 30 | { 31 | this.propertyGrid.PropertyTabs.AddTabType(typeof(EventsTab)); 32 | } 33 | } 34 | } 35 | } 36 | 37 | public PropertyboxControl() 38 | { 39 | this.InitializeComponent(); 40 | } 41 | 42 | private void ComboBox_SelectedIndexChanged(object sender, EventArgs e) 43 | { 44 | var selectionService = this._designer.SelectionService; 45 | if (this.comboBox.SelectedItem != null) 46 | { 47 | selectionService.SetSelectedComponents(new object[] { 48 | this.comboBox.SelectedItem 49 | }); 50 | } 51 | } 52 | 53 | protected virtual void ComboBox_DrawItem(object sender, DrawItemEventArgs e) 54 | { 55 | if (e.Index < 0 || e.Index >= this.comboBox.Items.Count) 56 | { 57 | return; 58 | } 59 | 60 | var g = e.Graphics; 61 | var stringColor = SystemBrushes.ControlText; 62 | 63 | if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) 64 | { 65 | if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) 66 | { 67 | g.FillRectangle(SystemBrushes.Highlight, e.Bounds); 68 | stringColor = SystemBrushes.HighlightText; 69 | } 70 | else 71 | { 72 | g.FillRectangle(SystemBrushes.Window, e.Bounds); 73 | } 74 | } 75 | else 76 | { 77 | g.FillRectangle(SystemBrushes.Window, e.Bounds); 78 | } 79 | 80 | object item = this.comboBox.Items[e.Index]; 81 | int xPos = e.Bounds.X; 82 | 83 | if (item is IComponent component) 84 | { 85 | string name = string.Empty; 86 | if (component.Site != null) 87 | { 88 | name = component.Site.Name; 89 | } 90 | else if (item is Control control) 91 | { 92 | name = control.Name; 93 | } 94 | if (string.IsNullOrEmpty(name)) 95 | { 96 | name = item.GetType().Name; 97 | } 98 | using (var font = new Font(this.comboBox.Font, FontStyle.Bold)) 99 | { 100 | g.DrawString(name, font, stringColor, xPos, e.Bounds.Y); 101 | xPos += (int)g.MeasureString($"{name}-", font).Width; 102 | } 103 | } 104 | 105 | string typeString = item.GetType().ToString(); 106 | g.DrawString(typeString, this.comboBox.Font, stringColor, xPos, e.Bounds.Y); 107 | } 108 | 109 | /// 110 | /// 设置下拉列表数据源 111 | /// 112 | /// 113 | public void SetComponents(ComponentCollection components) 114 | { 115 | this.comboBox.Items.Clear(); 116 | if (components != null) 117 | { 118 | foreach (object obj in components) 119 | { 120 | this.comboBox.Items.Add(obj); 121 | } 122 | } 123 | this.comboBox.SelectedItem = this.propertyGrid.SelectedObject; 124 | } 125 | 126 | /// 127 | /// 设置当前选中控件 128 | /// 129 | /// 130 | public void SetSelectedObjects(params object[] selectedObjects) 131 | { 132 | if (selectedObjects?.Length == 0) 133 | { 134 | this.propertyGrid.SelectedObject = null; 135 | } 136 | else if (selectedObjects.Length == 1) 137 | { 138 | var selectedObject = selectedObjects[0]; 139 | //this.PreFilterProperties(selectedObject); 140 | this.propertyGrid.SelectedObject = selectedObject; 141 | this.comboBox.SelectedItem = selectedObject; 142 | } 143 | else 144 | { 145 | this.propertyGrid.SelectedObjects = selectedObjects; 146 | this.comboBox.SelectedItem = null; 147 | } 148 | } 149 | 150 | #region 设计器自动生成的代码 151 | 152 | private void InitializeComponent() 153 | { 154 | this.comboBox = new System.Windows.Forms.ComboBox(); 155 | this.propertyGrid = new System.Windows.Forms.PropertyGrid(); 156 | this.SuspendLayout(); 157 | // 158 | // comboBox 159 | // 160 | this.comboBox.Dock = System.Windows.Forms.DockStyle.Top; 161 | this.comboBox.DrawMode = DrawMode.OwnerDrawFixed; 162 | this.comboBox.DropDownStyle = ComboBoxStyle.DropDownList; 163 | this.comboBox.FormattingEnabled = true; 164 | this.comboBox.Location = new System.Drawing.Point(0, 0); 165 | this.comboBox.Name = "comboBox"; 166 | this.comboBox.Size = new System.Drawing.Size(288, 20); 167 | this.comboBox.Sorted = true; 168 | this.comboBox.TabIndex = 0; 169 | this.comboBox.DrawItem += this.ComboBox_DrawItem; 170 | this.comboBox.SelectedIndexChanged += ComboBox_SelectedIndexChanged; 171 | // 172 | // propertyGrid 173 | // 174 | this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill; 175 | this.propertyGrid.Location = new System.Drawing.Point(0, 20); 176 | this.propertyGrid.Name = "propertyGrid"; 177 | this.propertyGrid.Size = new System.Drawing.Size(288, 413); 178 | this.propertyGrid.TabIndex = 1; 179 | // 180 | // PropertyboxControl 181 | // 182 | this.Controls.Add(this.propertyGrid); 183 | this.Controls.Add(this.comboBox); 184 | this.Name = "PropertyboxControl"; 185 | this.Size = new System.Drawing.Size(288, 433); 186 | this.ResumeLayout(false); 187 | 188 | } 189 | 190 | #endregion 191 | 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/PropertyboxControl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | True 122 | 123 | 124 | True 125 | 126 | 127 | True 128 | 129 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/IToolbox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing.Design; 3 | 4 | namespace Smart.FormDesigner.Toolbox 5 | { 6 | /// 7 | /// 工具箱接口类 8 | /// 9 | public interface IToolbox 10 | { 11 | /// 12 | /// 开始拖放控件事件 13 | /// 14 | event EventHandler BeginDragAndDrop; 15 | 16 | /// 17 | /// 控件拖放完成事件 18 | /// 19 | event EventHandler DropControl; 20 | 21 | /// 22 | /// 获取工具箱分类集合 23 | /// 24 | ToolboxCategoryCollection Items { get; } 25 | 26 | /// 27 | /// 当前选中的控件 28 | /// 29 | ToolboxItem SelectedItem { get; set; } 30 | 31 | /// 32 | /// 当前选择中控件的分类 33 | /// 34 | string SelectedCategory { get; set; } 35 | 36 | /// 37 | /// 向工具箱添加控件分类 38 | /// 39 | /// 40 | void AddCategory(string text); 41 | 42 | /// 43 | /// 向工具箱添加控件 44 | /// 45 | /// 控件信息对象 46 | /// 分类 47 | void AddItem(ToolboxItem item, string category = null); 48 | 49 | /// 50 | /// 从工具箱移除指定控件 51 | /// 52 | /// 控件信息对象 53 | /// 分类 54 | void RemoveItem(ToolboxItem item, string category = null); 55 | 56 | /// 57 | /// 刷新工具箱的状态 58 | /// 59 | void Refresh(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/ToolboxBaseItem.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing.Design; 2 | 3 | namespace Smart.FormDesigner.Toolbox 4 | { 5 | /// 6 | /// 7 | /// 8 | public class ToolboxBaseItem 9 | { 10 | /// 11 | /// 显示文本 12 | /// 13 | public string Text { get; set; } 14 | 15 | /// 16 | /// 图标索引 17 | /// 18 | public int ImageIndex { get; set; } 19 | 20 | /// 21 | /// 是否分组项 22 | /// 23 | public bool IsGroup { get; set; } 24 | 25 | /// 26 | /// ToolboxItem 27 | /// 28 | public object Tag { get; set; } 29 | 30 | /// 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | public ToolboxBaseItem(string text, int imageIndex, bool isGroup) 37 | { 38 | this.Text = text; 39 | this.ImageIndex = imageIndex; 40 | this.IsGroup = isGroup; 41 | if (isGroup) this.Tag = ToolboxCategoryState.Expanded; 42 | } 43 | 44 | /// 45 | /// 46 | /// 47 | /// 48 | /// 49 | /// 50 | public ToolboxBaseItem(string text, int image, ToolboxItem toolboxItem) 51 | { 52 | this.Text = text; 53 | this.ImageIndex = image; 54 | this.IsGroup = false; 55 | this.Tag = toolboxItem; 56 | } 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/ToolboxCategoryCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace Smart.FormDesigner.Toolbox 5 | { 6 | public class ToolboxCategoryCollection : ReadOnlyCollection 7 | { 8 | public ToolboxCategoryCollection(IList list) : base(list) 9 | { 10 | } 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/ToolboxCategoryItem.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing.Design; 2 | 3 | namespace Smart.FormDesigner.Toolbox 4 | { 5 | public class ToolboxCategoryItem 6 | { 7 | public string Name { get; set; } 8 | 9 | public ToolboxItemCollection Items { get; set; } 10 | 11 | public ToolboxCategoryItem(string name) 12 | { 13 | this.Name = name; 14 | } 15 | 16 | public ToolboxCategoryItem(string name, ToolboxItemCollection items) 17 | { 18 | this.Name = name; 19 | this.Items = items; 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/ToolboxCategoryState.cs: -------------------------------------------------------------------------------- 1 | namespace Smart.FormDesigner.Toolbox 2 | { 3 | /// 4 | /// 5 | /// 6 | public enum ToolboxCategoryState 7 | { 8 | /// 9 | /// 10 | /// 11 | Expanded, 12 | 13 | /// 14 | /// 15 | /// 16 | Collapsed 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/ToolboxItemDragEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Smart.FormDesigner.Toolbox 4 | { 5 | public class ToolboxItemDragEventArgs : EventArgs 6 | { 7 | public ToolboxBaseItem Item { get; set; } 8 | 9 | public ToolboxItemDragEventArgs(ToolboxBaseItem item) 10 | { 11 | this.Item = item; 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/ToolboxItemUsedArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing.Design; 3 | 4 | namespace Smart.FormDesigner.Toolbox 5 | { 6 | public class ToolboxItemUsedArgs : EventArgs 7 | { 8 | public ToolboxItem UsedItem { get; set; } 9 | 10 | public ToolboxItemUsedArgs(ToolboxItem usedItem) 11 | { 12 | this.UsedItem = usedItem; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/ToolboxListControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Drawing; 4 | using System.Windows.Forms; 5 | 6 | namespace Smart.FormDesigner.Toolbox 7 | { 8 | internal class ToolboxListControl : ListBox 9 | { 10 | private int underMouseItemIndex = -1; 11 | private Point mouseClickOrigin; 12 | private readonly int DragDistance = 3; 13 | 14 | public event EventHandler ItemDrag; 15 | 16 | [Category("Appearance")] 17 | [DefaultValue("ActiveCaption")] 18 | public Color ItemHoverBackColor { get; set; } = SystemColors.ActiveCaption; 19 | 20 | [Category("Appearance")] 21 | [DefaultValue("GradientActiveCaption")] 22 | public Color SelectedItemHoverBackColor { get; set; } = SystemColors.GradientActiveCaption; 23 | 24 | [Category("Appearance")] 25 | [DefaultValue("GradientInactiveCaption")] 26 | public Color SelectedItemBackColor { get; set; } = SystemColors.GradientInactiveCaption; 27 | 28 | [Category("Appearance")] 29 | [DefaultValue("ActiveBorder")] 30 | public Color SelectedItemBorderColor { get; set; } = SystemColors.ActiveBorder; 31 | 32 | [Category("Appearance")] 33 | [DefaultValue("Window")] 34 | public Color GroupBackColor { get; set; } = SystemColors.Window; 35 | 36 | [Category("Appearance")] 37 | public ImageList Images { get; set; } 38 | 39 | [Browsable(false)] 40 | [DefaultValue(null)] 41 | public new ToolboxBaseItem SelectedItem 42 | { 43 | get => (_selectedIndex >= 0) ? Items[_selectedIndex] as ToolboxBaseItem : null; 44 | set 45 | { 46 | int index = -1; 47 | if (value != null) 48 | { 49 | index = this.Items.IndexOf(value); 50 | } 51 | if (index != _selectedIndex) 52 | { 53 | ChangeSelection(index); 54 | } 55 | } 56 | } 57 | 58 | private int _selectedIndex = -1; 59 | public override int SelectedIndex 60 | { 61 | get => _selectedIndex; 62 | set => ChangeSelection(value); 63 | } 64 | 65 | 66 | private void ChangeSelection(int newSelectedIndex) 67 | { 68 | if (newSelectedIndex == _selectedIndex) 69 | return; 70 | 71 | if (_selectedIndex >= 0) 72 | { 73 | int saveSelected = _selectedIndex; 74 | 75 | _selectedIndex = -1; 76 | PaintItem(saveSelected, false, null); 77 | } 78 | 79 | if (newSelectedIndex >= 0) 80 | { 81 | _selectedIndex = newSelectedIndex; 82 | PaintItem(_selectedIndex, false, null); 83 | } 84 | } 85 | 86 | private int GetItemIndex(Point pt) 87 | { 88 | int index = TopIndex, count = Items.Count; 89 | 90 | while (index < count) 91 | { 92 | var bounds = this.GetItemRectangle(index); 93 | if (bounds.Contains(pt)) 94 | return index; 95 | index++; 96 | } 97 | return -1; 98 | } 99 | 100 | protected void PaintItem(int index, bool hover, Graphics graphics) 101 | { 102 | var g = (graphics == null) ? Graphics.FromHwnd(this.Handle) : graphics; 103 | 104 | var bounds = GetItemRectangle(index); 105 | 106 | bool isSelected = (index == _selectedIndex); 107 | var tbItem = Items[index] as ToolboxBaseItem; 108 | string text = tbItem.Text; 109 | hover = (hover && !tbItem.IsGroup); 110 | 111 | var backColor = this.BackColor; 112 | if (tbItem.IsGroup && isSelected) 113 | backColor = this.SelectedItemBackColor; 114 | else if (tbItem.IsGroup) 115 | backColor = this.GroupBackColor; 116 | else if (hover && isSelected) 117 | backColor = this.SelectedItemHoverBackColor; 118 | else if (hover) 119 | backColor = this.ItemHoverBackColor; 120 | else if (isSelected) 121 | backColor = this.SelectedItemBackColor; 122 | 123 | var backBrush = new SolidBrush(backColor); 124 | var foreBrush = new SolidBrush(this.ForeColor); 125 | 126 | g.FillRectangle(backBrush, bounds); 127 | if (hover || isSelected) 128 | { 129 | using (var pen = new Pen(SelectedItemBorderColor, 1)) 130 | { 131 | bounds.Size = new Size(bounds.Size.Width - 1, bounds.Size.Height - 1); 132 | g.DrawRectangle(pen, bounds); 133 | } 134 | } 135 | bounds = GetItemRectangle(index); 136 | 137 | int imageHeight = 0; 138 | int imageWidth = 0; 139 | 140 | if (this.Images != null) 141 | { 142 | imageHeight = this.Images.ImageSize.Height; 143 | imageWidth = this.Images.ImageSize.Width; 144 | 145 | int offset = tbItem.IsGroup ? 2 : 4; 146 | int imgLeft = bounds.Left + offset; 147 | if (RightToLeft == RightToLeft.Yes) 148 | imgLeft = bounds.Right - offset - imageWidth; 149 | 150 | if (tbItem.ImageIndex >= 0) 151 | this.Images.Draw(g, imgLeft + 4, bounds.Top + offset, imageWidth, imageHeight, tbItem.ImageIndex); 152 | } 153 | 154 | var size = g.MeasureString(text, this.Font); 155 | int vOffset = (bounds.Height - (int)size.Height) / 2; 156 | int hOffset = 1; 157 | 158 | var textFont = this.Font; 159 | if (tbItem.IsGroup) 160 | textFont = new Font(textFont.FontFamily, textFont.Size, FontStyle.Bold); 161 | 162 | var sf = new StringFormat(); 163 | if (RightToLeft == RightToLeft.Yes) 164 | { 165 | sf.FormatFlags = StringFormatFlags.DirectionRightToLeft; 166 | bounds.Size = new Size(bounds.Width - imageWidth - 2, bounds.Height); 167 | } 168 | else 169 | { 170 | bounds.Location = new Point(bounds.Left + imageWidth + 10, bounds.Top); 171 | } 172 | 173 | bounds.Inflate(-hOffset, -vOffset); 174 | g.DrawString(text, textFont, foreBrush, bounds, sf); 175 | 176 | foreBrush.Dispose(); 177 | backBrush.Dispose(); 178 | 179 | if (tbItem.IsGroup) 180 | textFont.Dispose(); 181 | 182 | if (graphics == null) 183 | g.Dispose(); 184 | } 185 | 186 | protected override void OnMouseMove(MouseEventArgs e) 187 | { 188 | if ((e.Button & MouseButtons.Left) != 0) 189 | { 190 | if (_selectedIndex >= 0 && mouseClickOrigin.Distance(Control.MousePosition) > DragDistance) 191 | { 192 | if (ItemDrag != null) 193 | { 194 | var dItem = Items[_selectedIndex] as ToolboxBaseItem; 195 | ItemDrag(this, new ToolboxItemDragEventArgs(dItem)); 196 | } 197 | } 198 | return; 199 | } 200 | 201 | var mousePoint = PointToClient(Control.MousePosition); 202 | int itemIndex = GetItemIndex(mousePoint); 203 | 204 | if (itemIndex != -1 && underMouseItemIndex != itemIndex) 205 | { 206 | if (underMouseItemIndex != -1) 207 | PaintItem(underMouseItemIndex, false, null); 208 | 209 | underMouseItemIndex = itemIndex; 210 | PaintItem(underMouseItemIndex, true, null); 211 | } 212 | 213 | base.OnMouseMove(e); 214 | } 215 | 216 | protected override void OnMouseLeave(EventArgs e) 217 | { 218 | if (underMouseItemIndex != -1) 219 | { 220 | PaintItem(underMouseItemIndex, false, null); 221 | underMouseItemIndex = -1; 222 | } 223 | base.OnMouseLeave(e); 224 | } 225 | 226 | protected override void OnDrawItem(DrawItemEventArgs e) 227 | { 228 | if (e.Index < 0 || e.Index >= Items.Count) 229 | return; 230 | 231 | Point mousePosition = this.PointToClient(Control.MousePosition); 232 | Rectangle bounds = GetItemRectangle(e.Index); 233 | 234 | bool underMouse = bounds.Contains(mousePosition) & (Control.MouseButtons == 0); 235 | PaintItem(e.Index, underMouse, e.Graphics); 236 | } 237 | 238 | protected override void OnMouseDown(MouseEventArgs e) 239 | { 240 | mouseClickOrigin = Control.MousePosition; 241 | int index = this.GetItemIndex(this.PointToClient(Control.MousePosition)); 242 | if (index >= 0) 243 | ChangeSelection(index); 244 | 245 | base.OnMouseDown(e); 246 | } 247 | 248 | 249 | 250 | } 251 | 252 | } 253 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/Toolbox/ToolboxPointerItem.cs: -------------------------------------------------------------------------------- 1 | namespace Smart.FormDesigner.Toolbox 2 | { 3 | public class ToolboxPointerItem : ToolboxBaseItem 4 | { 5 | public ToolboxPointerItem(string text) : this(text, 2) 6 | { 7 | } 8 | public ToolboxPointerItem(int imageIndex) : this("指针", imageIndex) 9 | { 10 | } 11 | public ToolboxPointerItem(string text, int imageIndex) : base(text, imageIndex, false) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/ToolboxControl.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/src/Smart.FormDesigner/Controls/ToolboxControl.cs -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Controls/ToolboxControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/AddingVerbEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.ComponentModel.Design; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace Smart.FormDesigner 9 | { 10 | public class AddingVerbEventArgs : EventArgs 11 | { 12 | public AddingVerbEventArgs() { } 13 | 14 | public AddingVerbEventArgs(IComponent component, DesignerVerb verb) 15 | { 16 | this.Component = component; 17 | this.Verb = verb; 18 | } 19 | public IComponent Component { get; set; } 20 | public DesignerVerb Verb { get; set; } 21 | 22 | public bool Cancel { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/AlignType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Smart.FormDesigner 4 | { 5 | /// 6 | /// 对齐方式 7 | /// 8 | [Flags] 9 | public enum AlignType 10 | { 11 | /// 12 | /// 左对齐 13 | /// 14 | Left = 1, 15 | /// 16 | /// 右对齐 17 | /// 18 | Right = 2, 19 | /// 20 | /// 水平居中 21 | /// 22 | Center = 4, 23 | /// 24 | /// 顶端对齐 25 | /// 26 | Top = 8, 27 | /// 28 | /// 垂直居中 29 | /// 30 | Middle = 16, 31 | /// 32 | /// 底端对齐 33 | /// 34 | Bottom = 32, 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/DefaultDesignerTransaction.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.Design; 2 | 3 | namespace Smart.FormDesigner.Internal 4 | { 5 | /// 6 | public class DefaultDesignerTransaction : DesignerTransaction 7 | { 8 | private DesignerHost _host; 9 | 10 | public DefaultDesignerTransaction(DesignerHost host) 11 | { 12 | this._host = host; 13 | } 14 | 15 | public DefaultDesignerTransaction(DesignerHost host, string name) : base(name) 16 | { 17 | this._host = host; 18 | } 19 | 20 | protected override void Dispose(bool disposing) 21 | { 22 | if (!base.Committed && !base.Canceled) 23 | { 24 | base.Cancel(); 25 | } 26 | base.Dispose(disposing); 27 | } 28 | 29 | protected override void OnCommit() 30 | { 31 | this._host.TransactionCommiting(this); 32 | } 33 | 34 | protected override void OnCancel() 35 | { 36 | this._host.TransactionCanceling(this); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/FilterEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | namespace Smart.FormDesigner 5 | { 6 | public class FilterEventArgs : EventArgs 7 | { 8 | public IDictionary Data { get; set; } 9 | 10 | public bool Caching { get; set; } 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/DesignSurface.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.ComponentModel.Design; 4 | using System.Drawing; 5 | using System.Windows.Forms; 6 | 7 | namespace Smart.FormDesigner.Internal 8 | { 9 | internal class DesignSurface : UserControl //System.ComponentModel.Design.DesignSurface 10 | { 11 | private Control _savedParent; 12 | 13 | private Control _designedControl; 14 | internal Control DesignedControl 15 | { 16 | set 17 | { 18 | if (_designedControl != null) 19 | { 20 | _designedControl.BackColorChanged -= new EventHandler(FormBackColorChanged); 21 | _designedControl.BackgroundImageChanged -= new EventHandler(FormBackgroundImageChanged); 22 | _designedControl.BackgroundImageLayoutChanged -= new EventHandler(FormBackgroundImageLayoutChanged); 23 | _designedControl.FontChanged -= new EventHandler(FormFontChanged); 24 | _designedControl.ForeColorChanged -= new EventHandler(FormForeColorChanged); 25 | 26 | if (_designedControl is ScrollableControl scrollableControl) 27 | { 28 | scrollableControl.AutoScroll = AutoScroll; 29 | } 30 | } 31 | 32 | if (value != null) 33 | { 34 | Control control = value; 35 | while (control != null && control.BackColor == Color.Transparent) 36 | { 37 | control = control.Parent; 38 | } 39 | 40 | if (control != null) 41 | { 42 | BackColor = control.BackColor; 43 | } 44 | else 45 | { 46 | BackColor = SystemColors.Control; 47 | } 48 | BackgroundImage = value.BackgroundImage; 49 | BackgroundImageLayout = value.BackgroundImageLayout; 50 | Font = value.Font; 51 | ForeColor = value.ForeColor; 52 | value.BackColorChanged += new EventHandler(FormBackColorChanged); 53 | value.BackgroundImageChanged += new EventHandler(FormBackgroundImageChanged); 54 | value.BackgroundImageLayoutChanged += new EventHandler(FormBackgroundImageLayoutChanged); 55 | value.FontChanged += new EventHandler(FormFontChanged); 56 | value.ForeColorChanged += new EventHandler(FormForeColorChanged); 57 | if (value is ScrollableControl scrollableControl) 58 | { 59 | AutoScroll = scrollableControl.AutoScroll; 60 | scrollableControl.AutoScroll = false; 61 | } 62 | } 63 | _designedControl = value; 64 | } 65 | } 66 | 67 | public override ISite Site 68 | { 69 | get 70 | { 71 | return base.Site; 72 | } 73 | set 74 | { 75 | if (value != null) 76 | { 77 | if (value.GetService(typeof(IDesignerHost)) is IDesignerHost designerHost) 78 | { 79 | designerHost.AddService(typeof(DesignSurface), this); 80 | } 81 | } 82 | else if (base.Site != null) 83 | { 84 | if (base.Site.GetService(typeof(IDesignerHost)) is IDesignerHost designerHost) 85 | { 86 | designerHost.RemoveService(typeof(DesignSurface)); 87 | } 88 | } 89 | base.Site = value; 90 | } 91 | } 92 | 93 | public DesignSurface() 94 | { 95 | _savedParent = Parent; 96 | if (_savedParent != null) 97 | { 98 | _savedParent.SizeChanged += new EventHandler(OnParentResize); 99 | } 100 | } 101 | 102 | protected override void Dispose(bool disposing) 103 | { 104 | if (_savedParent != null) 105 | { 106 | _savedParent.SizeChanged -= new EventHandler(OnParentResize); 107 | } 108 | base.Dispose(disposing); 109 | } 110 | 111 | protected override void OnLocationChanged(EventArgs e) 112 | { 113 | if (!AutoScroll && (Left != 0 || Top != 0)) 114 | { 115 | Location = new Point(0, 0); 116 | if (Parent is ScrollableControl scrollableControl 117 | && (scrollableControl.AutoScrollPosition.X != 0 || scrollableControl.AutoScrollPosition.Y != 0)) 118 | { 119 | scrollableControl.AutoScrollPosition = new Point(0, 0); 120 | } 121 | } 122 | base.OnLocationChanged(e); 123 | } 124 | 125 | protected override void OnParentChanged(EventArgs e) 126 | { 127 | if (_savedParent != null) 128 | { 129 | _savedParent.SizeChanged -= new EventHandler(OnParentResize); 130 | } 131 | _savedParent = Parent; 132 | if (Parent != null) 133 | { 134 | Parent.SizeChanged += new EventHandler(OnParentResize); 135 | if (Parent is ScrollableControl scrollableControl) 136 | { 137 | scrollableControl.AutoScroll = false; 138 | } 139 | } 140 | base.OnParentChanged(e); 141 | } 142 | 143 | private void FormForeColorChanged(object sender, EventArgs e) 144 | { 145 | ForeColor = _designedControl.ForeColor; 146 | } 147 | 148 | private void FormFontChanged(object sender, EventArgs e) 149 | { 150 | Font = _designedControl.Font; 151 | } 152 | 153 | private void FormBackgroundImageChanged(object sender, EventArgs e) 154 | { 155 | BackgroundImage = _designedControl.BackgroundImage; 156 | } 157 | 158 | private void FormBackgroundImageLayoutChanged(object sender, EventArgs e) 159 | { 160 | BackgroundImageLayout = _designedControl.BackgroundImageLayout; 161 | } 162 | 163 | private void FormBackColorChanged(object sender, EventArgs e) 164 | { 165 | BackColor = _designedControl.BackColor; 166 | } 167 | 168 | private void OnParentResize(object o, EventArgs e) 169 | { 170 | SuspendLayout(); 171 | var selectionService = Site.GetService(); 172 | var selectedComponents = selectionService.GetSelectedComponents(); 173 | selectionService.SetSelectedComponents(null); 174 | Size = ((Control)o).ClientSize; 175 | Location = new Point(0, 0); 176 | selectionService.SetSelectedComponents(selectedComponents); 177 | ResumeLayout(); 178 | } 179 | 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/DesignerActions/AddAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.ComponentModel; 4 | using System.ComponentModel.Design; 5 | using System.Windows.Forms; 6 | 7 | namespace Smart.FormDesigner.Internal 8 | { 9 | internal class AddAction : DesignerAction 10 | { 11 | private Type _type = null; 12 | private Control _parent = null; 13 | 14 | protected string parentName = string.Empty; 15 | protected Hashtable properties; 16 | 17 | public AddAction(IDesignerHost host, object component, MegaAction owner) 18 | : base(host, component, owner) 19 | { 20 | this._type = component.GetType(); 21 | if (component is Control control) 22 | { 23 | this._parent = control.Parent; 24 | this.parentName = base.ComponentName(this._parent); 25 | } 26 | } 27 | 28 | public override void Undo() 29 | { 30 | var container = this.host.GetService(); 31 | IComponent component = container.Components[this.name]; 32 | if (component != null) 33 | { 34 | if (this._parent == null && component is Control control) 35 | { 36 | this._parent = control.Parent; 37 | this.parentName = base.ComponentName(this._parent); 38 | } 39 | this.properties = this.owner.StoreProperties(component, null, null); 40 | var selectionService = this.host.GetService(); 41 | container.Remove(component); 42 | component.Dispose(); 43 | selectionService.SetSelectedComponents(null); 44 | } 45 | } 46 | 47 | public override void Redo() 48 | { 49 | var selectionService = this.host.GetService(); 50 | selectionService.SetSelectedComponents(null); 51 | IComponent obj = this.host.CreateComponent(this._type, this.name); 52 | if (obj is Control control) 53 | { 54 | var container = this.host.GetService(); 55 | var parentControl = !this.parentName.IsNullOrEmpty() ? (container.Components[this.parentName] as Control) : null; 56 | if (parentControl != null && this._parent != parentControl) 57 | { 58 | this._parent = parentControl; 59 | } 60 | control.Parent = this._parent; 61 | control.BringToFront(); 62 | } 63 | base.SetProperties(this.properties); 64 | } 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/DesignerActions/ChangeAction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.ComponentModel.Design; 3 | 4 | namespace Smart.FormDesigner.Internal 5 | { 6 | internal class ChangeAction : DesignerAction 7 | { 8 | private Hashtable _oldValue; 9 | private Hashtable _newValue; 10 | 11 | public ChangeAction(IDesignerHost host, object control, Hashtable oldValues, Hashtable newValues, MegaAction owner) 12 | : base(host, control, owner) 13 | { 14 | this._oldValue = new Hashtable(); 15 | this._newValue = new Hashtable(); 16 | 17 | foreach (DictionaryEntry item in oldValues) 18 | { 19 | object newValue = newValues[item.Key]; 20 | if (newValue != null) 21 | { 22 | if (!newValue.Equals(item.Value)) 23 | { 24 | this._oldValue.Add(item.Key, item.Value); 25 | this._newValue.Add(item.Key, newValue); 26 | } 27 | newValues.Remove(item.Key); 28 | } 29 | else 30 | { 31 | this._oldValue.Add(item.Key, item.Value); 32 | } 33 | } 34 | 35 | foreach (DictionaryEntry item in newValues) 36 | { 37 | this._newValue.Add(item.Key, item.Value); 38 | } 39 | 40 | } 41 | 42 | public override void Undo() 43 | { 44 | var selectionService = this.host.GetService(); 45 | selectionService.SetSelectedComponents(null); 46 | base.SetProperties(this._oldValue); 47 | } 48 | 49 | public override void Redo() 50 | { 51 | var selectionService = this.host.GetService(); 52 | selectionService.SetSelectedComponents(null); 53 | base.SetProperties(this._newValue); 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/DesignerActions/DesignerAction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.ComponentModel; 3 | using System.ComponentModel.Design; 4 | 5 | namespace Smart.FormDesigner.Internal 6 | { 7 | internal abstract class DesignerAction 8 | { 9 | protected string name; 10 | protected IDesignerHost host; 11 | protected MegaAction owner; 12 | 13 | public DesignerAction(IDesignerHost host, object control, MegaAction owner) 14 | { 15 | this.host = host; 16 | this.name = this.ComponentName(control as Component); 17 | this.owner = owner; 18 | } 19 | 20 | public abstract void Undo(); 21 | 22 | public abstract void Redo(); 23 | 24 | public virtual void Dispose() 25 | { 26 | this.host = null; 27 | } 28 | 29 | protected string ComponentName(Component control) 30 | { 31 | return control?.Site?.Name ?? string.Empty; 32 | } 33 | 34 | protected void SetProperties(Hashtable props) 35 | { 36 | var container = this.host.GetService(); 37 | if (container.Components[this.name] is IComponent component) 38 | { 39 | this.owner.LoadProperties(component, props, (DesignerHost)this.host); 40 | } 41 | } 42 | 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/DesignerActions/RemoveAction.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.Design; 2 | 3 | namespace Smart.FormDesigner.Internal 4 | { 5 | internal class RemoveAction : AddAction 6 | { 7 | public RemoveAction(IDesignerHost host, object item, MegaAction owner) : base(host, item, owner) 8 | { 9 | this.properties = owner.StoreProperties(item, null, null); 10 | } 11 | 12 | public override void Undo() 13 | { 14 | base.Redo(); 15 | } 16 | 17 | public override void Redo() 18 | { 19 | base.Undo(); 20 | } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/DesignerSite.cs: -------------------------------------------------------------------------------- 1 | using Smart.FormDesigner.Services; 2 | using System; 3 | using System.ComponentModel; 4 | using System.ComponentModel.Design; 5 | 6 | namespace Smart.FormDesigner.Internal 7 | { 8 | internal class DesignerSite : ISite, IServiceContainer 9 | { 10 | private DesignerHost _designerHost; 11 | private NestedContainer _nestedContainer; 12 | private ServiceContainer _serviceContainer; 13 | private DictionaryService _dictionaryService; 14 | 15 | public bool DesignMode { get; set; } 16 | 17 | public string Name { get; set; } 18 | 19 | public IComponent Component { get; private set; } 20 | 21 | public IContainer Container 22 | { 23 | get 24 | { 25 | return this._designerHost.Container; 26 | } 27 | } 28 | 29 | public IDesigner Designer { get; set; } 30 | 31 | public DesignerSite(DesignerHost designer, IComponent component) 32 | { 33 | this._designerHost = designer; 34 | this._serviceContainer = new ServiceContainer(designer); 35 | this.Component = component; 36 | this.DesignMode = true; 37 | } 38 | 39 | #region IServiceProvider 接口成员 40 | 41 | public object GetService(Type serviceType) 42 | { 43 | if (serviceType == typeof(IDictionaryService)) 44 | { 45 | if (this._dictionaryService == null) 46 | { 47 | this._dictionaryService = new DictionaryService(); 48 | } 49 | return this._dictionaryService; 50 | } 51 | else if (serviceType == typeof(INestedContainer)) 52 | { 53 | if (this._nestedContainer == null) 54 | { 55 | this._nestedContainer = new NestedContainer(this.Component, this._designerHost); 56 | } 57 | return this._nestedContainer; 58 | } 59 | else 60 | { 61 | object service = this._serviceContainer.GetService(serviceType); 62 | if (service != null) 63 | { 64 | return service; 65 | } 66 | else 67 | { 68 | return this._designerHost.GetService(serviceType); 69 | } 70 | } 71 | } 72 | 73 | #endregion 74 | 75 | #region IServiceContainer 接口成员 76 | 77 | public void AddService(Type serviceType, ServiceCreatorCallback callback) 78 | { 79 | this.AddService(serviceType, callback, false); 80 | } 81 | 82 | public void AddService(Type serviceType, object serviceInstance) 83 | { 84 | this.AddService(serviceType, serviceInstance, false); 85 | } 86 | 87 | public void AddService(Type serviceType, ServiceCreatorCallback callback, bool promote) 88 | { 89 | this._serviceContainer.AddService(serviceType, callback, promote); 90 | } 91 | 92 | public void AddService(Type serviceType, object serviceInstance, bool promote) 93 | { 94 | this._serviceContainer.AddService(serviceType, serviceInstance, promote); 95 | } 96 | 97 | public void RemoveService(Type serviceType) 98 | { 99 | this.RemoveService(serviceType, false); 100 | } 101 | 102 | public void RemoveService(Type serviceType, bool promote) 103 | { 104 | this._serviceContainer.RemoveService(serviceType, promote); 105 | } 106 | 107 | #endregion 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/ExtenderProvidedProperty.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows.Forms; 3 | 4 | namespace Smart.FormDesigner.Internal 5 | { 6 | internal class ExtenderProvidedProperty 7 | { 8 | public ExtenderProvidedProperty(string name, ExtenderProvidedPropertyAttribute attribute, Control source, Control target) 9 | { 10 | this.ProperyName = name; 11 | this.Attribute = attribute; 12 | this.Source = source; 13 | this.Target = target; 14 | } 15 | 16 | public string ProperyName { get; } 17 | public ExtenderProvidedPropertyAttribute Attribute { get; } 18 | public Control Source { get; } 19 | public Control Target { get; } 20 | 21 | public void Invoke() 22 | { 23 | object provider = Attribute.Provider; 24 | var method = provider.GetType().GetMethod($"Set{ProperyName}"); 25 | if (method != null && this.Target != this.Source) 26 | { 27 | var array = new object[2]; 28 | array[0] = this.Source; 29 | method.Invoke(provider, array); 30 | } 31 | } 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/NestedContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.ComponentModel.Design; 5 | using System.Linq; 6 | 7 | namespace Smart.FormDesigner.Internal 8 | { 9 | /// 10 | /// 使容器可以拥有一个所属组件。 11 | /// 12 | internal class NestedContainer : Disposable, INestedContainer, IContainer, IDisposable 13 | { 14 | private IContainer container; 15 | public IComponent Owner { get; private set; } 16 | 17 | private Dictionary components; 18 | public ComponentCollection Components 19 | { 20 | get 21 | { 22 | var array = this.components.Keys.ToArray(); 23 | return new ComponentCollection(array); 24 | } 25 | } 26 | 27 | public NestedContainer(IComponent owner, IDesignerHost host) 28 | { 29 | this.Owner = owner; 30 | this.container = host.GetService(); 31 | this.components = new Dictionary(); 32 | } 33 | 34 | public void Add(IComponent component, string name) 35 | { 36 | this.components.Add(component, name); 37 | this.container.Add(component, name); 38 | } 39 | 40 | public void Add(IComponent component) 41 | { 42 | this.Add(component, null); 43 | } 44 | 45 | public void Remove(IComponent component) 46 | { 47 | this.components.Remove(component); 48 | this.container.Remove(component); 49 | } 50 | 51 | protected override void Dispose(bool disposing) 52 | { 53 | if (disposing) 54 | { 55 | this.container.Dispose(); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Internal/RootDesigner.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.Design; 2 | using System.Windows.Forms; 3 | using System.Windows.Forms.Design; 4 | using Smart.FormDesigner.Services; 5 | 6 | namespace Smart.FormDesigner.Internal 7 | { 8 | internal class RootDesigner : DocumentDesigner 9 | { 10 | protected override void OnCreateHandle() 11 | { 12 | base.OnCreateHandle(); 13 | var eventFilter = (EventService)this.GetService(typeof(EventService)); 14 | eventFilter.KeyDown += EventFilter_KeyDown; 15 | eventFilter.KeyDown += this.EventFilter_KeyDown; 16 | } 17 | protected override void Dispose(bool disposing) 18 | { 19 | var eventFilter = (EventService)this.GetService(typeof(EventService)); 20 | if (eventFilter != null) 21 | { 22 | eventFilter.KeyDown -= this.EventFilter_KeyDown; 23 | } 24 | base.Dispose(disposing); 25 | } 26 | 27 | private void EventFilter_KeyDown(object sender, KeyEventArgs e) 28 | { 29 | var designerHost = (IDesignerHost)this.GetService(typeof(IDesignerHost)); 30 | if (e.KeyValue == 9) //Tab 31 | { 32 | designerHost.SelectNextControl((e.Modifiers & Keys.Shift) == Keys.None); 33 | } 34 | else 35 | { 36 | bool ctrlFlag = false; 37 | if (this.GetService(typeof(Designer)) is Designer designer && !designer.SnapToGrid) 38 | { 39 | ctrlFlag = true; 40 | } 41 | if ((e.Modifiers & Keys.Control) != Keys.None) 42 | { 43 | ctrlFlag = !ctrlFlag; 44 | } 45 | int x = 0, y = 0; 46 | switch (e.KeyValue) 47 | { 48 | case 37: // 左 49 | case 39: // 右 50 | x = ctrlFlag ? 1 : GridSize.Width; 51 | if (e.KeyValue == 37) x = -x; 52 | break; 53 | case 38: // 上 54 | case 40: // 下 55 | y = ctrlFlag ? 1 : GridSize.Height; 56 | if (e.KeyValue == 38) y = -y; 57 | break; 58 | default: 59 | return; 60 | } 61 | if ((e.Modifiers & Keys.Shift) != Keys.None) 62 | { 63 | designerHost.Layout("Resize controls", control => 64 | { 65 | if (x != 0) control.Width += x; 66 | if (y != 0) control.Height += y; 67 | }); 68 | } 69 | else 70 | { 71 | designerHost.Layout("Move controls", control => 72 | { 73 | if (x != 0) control.Left += x; 74 | if (y != 0) control.Top += y; 75 | }); 76 | } 77 | } 78 | } 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/ResizeType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Smart.FormDesigner 4 | { 5 | /// 6 | /// 大小调整方式 7 | /// 8 | [Flags] 9 | public enum ResizeType 10 | { 11 | /// 12 | /// 使用相同宽度 13 | /// 14 | SameWidth = 1, 15 | 16 | /// 17 | /// 使用相同高度 18 | /// 19 | SameHeight = 2 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/BinarySerializationAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Smart.FormDesigner.Serialization 4 | { 5 | //[AttributeUsage(AttributeTargets.Class)] 6 | public class BinarySerializationAttribute : Attribute 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/IDesignerLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.ComponentModel.Design; 5 | using System.Windows.Forms; 6 | 7 | namespace Smart.FormDesigner.Serialization 8 | { 9 | public interface IDesignerLoader 10 | { 11 | event ComponentEventHandler ComponentLoaded; 12 | 13 | LoadModes LoadMode { get; set; } 14 | 15 | IDesignerHost DesignerHost { get; set; } 16 | void Load(Control parent, IReader reader, Dictionary components, bool ignoreParent); 17 | void Store(IComponent[] parents, IWriter writer); 18 | void SetEventSource(object eventSource); 19 | void BindEvents(object eventSource); 20 | void UnbindEvents(object eventSource); 21 | void RefreshEventData(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Internal/ComponentProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.ComponentModel; 4 | using System.Reflection; 5 | 6 | namespace Smart.FormDesigner.Serialization 7 | { 8 | internal class ComponentProperty 9 | { 10 | protected PropertyDescriptor property; 11 | protected object component; 12 | 13 | public ComponentProperty(object component, PropertyDescriptor property) 14 | { 15 | this.component = component; 16 | this.property = property; 17 | } 18 | 19 | public virtual void SetProperty(object value) 20 | { 21 | if (property.PropertyType.IsArray) 22 | { 23 | var arrayList = new ArrayList(); 24 | if (this.property.GetValue(this.component) is Array array) 25 | { 26 | arrayList.AddRange(array); 27 | } 28 | arrayList.Add(value); 29 | var instance = (Array)Activator.CreateInstance(this.property.PropertyType, new object[1] { arrayList.Count }); 30 | arrayList.CopyTo(instance); 31 | try 32 | { 33 | this.property.SetValue(this.component, instance); 34 | } 35 | catch 36 | { 37 | // TODO: SetProperty 错误处理 38 | } 39 | } 40 | else if (typeof(IList).IsAssignableFrom(property.PropertyType)) 41 | { 42 | object listValue = this.property.GetValue(this.component); 43 | if (listValue == null || this.TryAddRange(listValue, value)) 44 | { 45 | return; 46 | } 47 | if (listValue is IList list) 48 | { 49 | if (list.IsFixedSize) return; 50 | 51 | var property = listValue.GetType().GetProperty("List", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty); 52 | if (property != null) 53 | { 54 | list = (IList)property.GetValue(listValue, new object[0]); 55 | } 56 | try 57 | { 58 | list.Add(value); 59 | } 60 | catch 61 | { 62 | } 63 | } 64 | } 65 | else if (this.property.GetValue(this.component) == value) 66 | { 67 | return; 68 | } 69 | else 70 | { 71 | this.property.SetValue(this.component, value); 72 | } 73 | } 74 | 75 | public virtual object GetProperty() 76 | { 77 | if (property.PropertyType.IsArray) 78 | { 79 | return null; 80 | } 81 | else if (typeof(IList).IsAssignableFrom(property.PropertyType)) 82 | { 83 | return null; 84 | } 85 | else 86 | { 87 | return this.property.GetValue(this.component); 88 | } 89 | 90 | } 91 | 92 | private bool TryAddRange(object list, object item) 93 | { 94 | try 95 | { 96 | foreach (var method in list.GetType().GetMethods()) 97 | { 98 | if (method.Name == "AddRange") 99 | { 100 | var parameters1 = method.GetParameters(); 101 | if (parameters1.Length == 1 && parameters1[0].ParameterType.IsArray) 102 | { 103 | var instance = (Array)Activator.CreateInstance(parameters1[0].ParameterType, new object[1] { 1 }); 104 | instance.SetValue(item, 0); 105 | object[] parameters2 = new object[1] { instance }; 106 | method.Invoke(list, parameters2); 107 | return true; 108 | } 109 | } 110 | } 111 | } 112 | catch (Exception) 113 | { 114 | } 115 | 116 | return false; 117 | } 118 | 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Internal/Extender.cs: -------------------------------------------------------------------------------- 1 | namespace Smart.FormDesigner.Serialization 2 | { 3 | internal struct Extender 4 | { 5 | internal object Control { get; set; } 6 | internal object Value { get; set; } 7 | internal string Property { get; set; } 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Internal/InstanceDescriptorLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Smart.FormDesigner.Serialization 4 | { 5 | internal class InstanceDescriptorLoader 6 | { 7 | public InstanceDescriptorLoader(MemberInfo memberInfo, object[] args) 8 | { 9 | this.MemberInfo = memberInfo; 10 | this.Arguments = args; 11 | } 12 | public MemberInfo MemberInfo { get; set; } 13 | 14 | public object[] Arguments { get; set; } 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Internal/ReferencedCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | 3 | namespace Smart.FormDesigner.Serialization 4 | { 5 | internal class ReferencedCollection : Collection 6 | { 7 | internal ReferencedCollection() 8 | { 9 | } 10 | 11 | public void Add(string key, ComponentProperty property) 12 | { 13 | foreach (ReferencedItem referencedItem in this) 14 | { 15 | if (referencedItem.Key == key) 16 | { 17 | referencedItem.Properties.Add(property); 18 | return; 19 | } 20 | } 21 | this.Add(new ReferencedItem() 22 | { 23 | Key = key, 24 | Properties = { property } 25 | }); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Internal/ReferencedItem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Smart.FormDesigner.Serialization 4 | { 5 | internal class ReferencedItem 6 | { 7 | internal string Key { get; set; } 8 | internal IList Properties { get; private set; } = new List(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/LoadModes.cs: -------------------------------------------------------------------------------- 1 | namespace Smart.FormDesigner.Serialization 2 | { 3 | /// 4 | /// 表单加载方式 5 | /// 6 | public enum LoadModes 7 | { 8 | /// 9 | /// 默认的 10 | /// 11 | Default, 12 | /// 13 | /// 允许重复的 14 | /// 15 | Duplicate, 16 | /// 17 | /// 删除表单 18 | /// 19 | EraseForm, 20 | /// 21 | /// 修改现有的 22 | /// 23 | ModifyExisting, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Reader/IReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Smart.FormDesigner.Serialization 5 | { 6 | public interface IReader : IDisposable 7 | { 8 | string Name { get; } 9 | string Value { get; } 10 | Dictionary Attributes { get; } 11 | ReaderState State { get; } 12 | 13 | bool Read(); 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Reader/ReaderBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace Smart.FormDesigner.Serialization 6 | { 7 | public abstract class ReaderBase : IReader where T : IDisposable 8 | { 9 | protected T reader; 10 | 11 | #region IReader 接口成员 12 | 13 | public string Name { get; protected set; } = string.Empty; 14 | public string Value { get; protected set; } = string.Empty; 15 | public Dictionary Attributes { get; protected set; } = new Dictionary(); 16 | public ReaderState State { get; protected set; } = ReaderState.Initial; 17 | 18 | public abstract bool Read(); 19 | 20 | #endregion 21 | 22 | #region IDisposable 接口成员 23 | 24 | public virtual void Dispose() 25 | { 26 | reader?.Dispose(); 27 | } 28 | 29 | #endregion 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Reader/ReaderState.cs: -------------------------------------------------------------------------------- 1 | namespace Smart.FormDesigner.Serialization 2 | { 3 | public enum ReaderState 4 | { 5 | Initial, 6 | /// 7 | /// 开始读取节点 8 | /// 9 | StartElement, 10 | /// 11 | /// 开始读取节点值 12 | /// 13 | Value, 14 | /// 15 | /// 读取节点完成 16 | /// 17 | EndElement, 18 | /// 19 | /// 已成功到达末尾。 20 | /// 21 | EOF, 22 | /// 23 | /// 将出现错误,以防止读取的操作继续进行。 24 | /// 25 | Error 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Reader/XmlFormReader.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Xml; 3 | 4 | namespace Smart.FormDesigner.Serialization 5 | { 6 | public class XmlFormReader : ReaderBase 7 | { 8 | private bool isEmptyValue = false; 9 | 10 | #region 构造函数 11 | 12 | public XmlFormReader(string fileName) 13 | { 14 | this.reader = new XmlTextReader(fileName); 15 | } 16 | public XmlFormReader(XmlReader stream) 17 | { 18 | this.reader = stream; 19 | } 20 | public XmlFormReader(Stream stream) 21 | { 22 | this.reader = new XmlTextReader(stream); 23 | } 24 | 25 | #endregion 26 | 27 | public override bool Read() 28 | { 29 | if (this.State == ReaderState.Error || this.State == ReaderState.EOF || this.reader.ReadState != ReadState.Initial && this.reader.ReadState != ReadState.Interactive) 30 | { 31 | return false; 32 | } 33 | if (this.State == ReaderState.Initial && !this.ReadUntil(XmlNodeType.Element)) 34 | { 35 | this.State = ReaderState.Error; 36 | return false; 37 | } 38 | 39 | if (this.isEmptyValue) 40 | { 41 | this.isEmptyValue = false; 42 | this.ReadNext(); 43 | } 44 | 45 | if (this.reader.NodeType == XmlNodeType.Element) 46 | { 47 | this.State = ReaderState.StartElement; 48 | this.Name = this.reader.Name; 49 | this.ReadAttributes(); 50 | 51 | this.isEmptyValue = this.reader.IsEmptyElement; 52 | if (this.isEmptyValue) 53 | { 54 | this.Value = ""; 55 | this.State = ReaderState.Value; 56 | return true; 57 | } 58 | } 59 | else if (this.reader.NodeType == XmlNodeType.EndElement) 60 | { 61 | this.State = ReaderState.EndElement; 62 | this.Name = ""; 63 | } 64 | else 65 | { 66 | this.State = ReaderState.Value; 67 | } 68 | 69 | if (!this.ReadNext()) 70 | { 71 | this.State = this.reader.ReadState == ReadState.EndOfFile ? ReaderState.EOF : ReaderState.Error; 72 | return false; 73 | } 74 | 75 | if (this.reader.NodeType == XmlNodeType.Text) 76 | { 77 | this.Value = this.reader.Value; 78 | if (!this.ReadNext() || this.reader.NodeType != XmlNodeType.EndElement) 79 | { 80 | this.State = ReaderState.Error; 81 | return false; 82 | } 83 | this.State = ReaderState.Value; 84 | this.ReadNext(); 85 | } 86 | else if (this.reader.NodeType == XmlNodeType.EndElement && this.reader.Name == this.Name) 87 | { 88 | this.Value = ""; 89 | this.State = ReaderState.Value; 90 | this.ReadNext(); 91 | } 92 | return true; 93 | } 94 | 95 | private void ReadAttributes() 96 | { 97 | this.Attributes.Clear(); 98 | while (this.reader.MoveToNextAttribute()) 99 | { 100 | this.Attributes[this.reader.Name] = this.reader.Value; 101 | } 102 | } 103 | private bool ReadUntil(XmlNodeType nodeType) 104 | { 105 | while (this.ReadNext()) 106 | { 107 | if (this.reader.NodeType == nodeType) 108 | return true; 109 | } 110 | return false; 111 | } 112 | private bool ReadNext() 113 | { 114 | while (this.reader.Read()) 115 | { 116 | switch (this.reader.NodeType) 117 | { 118 | case XmlNodeType.Element: 119 | case XmlNodeType.Text: 120 | case XmlNodeType.EndElement: 121 | return true; 122 | default: 123 | continue; 124 | } 125 | } 126 | return false; 127 | } 128 | 129 | public override void Dispose() 130 | { 131 | this.reader.Close(); 132 | } 133 | 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/StoreEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.ComponentModel.Design; 3 | 4 | namespace Smart.FormDesigner.Serialization 5 | { 6 | public class StoreEventArgs : ComponentEventArgs 7 | { 8 | public StoreEventArgs(IComponent component) : base(component) 9 | { 10 | } 11 | 12 | public bool Cancel { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Writer/IWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | namespace Smart.FormDesigner.Serialization 5 | { 6 | public interface IWriter : IDisposable 7 | { 8 | void WriteStartElement(string name, Hashtable attributes); 9 | void WriteValue(string name, string value, Hashtable attributes); 10 | void WriteEndElement(string name); 11 | 12 | void Flush(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Serialization/Writer/XmlFormWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.IO; 4 | using System.Text; 5 | using System.Xml; 6 | 7 | namespace Smart.FormDesigner.Serialization 8 | { 9 | public class XmlFormWriter : IWriter, IDisposable 10 | { 11 | #region 私有字段 12 | 13 | private XmlWriter writer; 14 | private XmlWriter curWriter; 15 | 16 | #endregion 17 | 18 | #region 构造函数 19 | 20 | public XmlFormWriter(string fileName) 21 | { 22 | this.writer = new XmlTextWriter(fileName, Encoding.UTF8); 23 | this.curWriter = this.writer; 24 | } 25 | public XmlFormWriter(XmlWriter stream) 26 | { 27 | this.writer = stream; 28 | this.curWriter = this.writer; 29 | } 30 | public XmlFormWriter(Stream stream) 31 | { 32 | this.writer = new XmlTextWriter(stream, Encoding.UTF8); 33 | this.curWriter = this.writer; 34 | } 35 | 36 | #endregion 37 | 38 | #region IWriter 接口成员 39 | 40 | public virtual void WriteStartElement(string name, Hashtable attributes) 41 | { 42 | this.curWriter.WriteStartElement(name); 43 | if (attributes != null) 44 | { 45 | foreach (DictionaryEntry dictionaryEntry in attributes) 46 | { 47 | if (dictionaryEntry.Value != null) 48 | { 49 | this.curWriter.WriteAttributeString(dictionaryEntry.Key.ToString(), dictionaryEntry.Value.ToString()); 50 | } 51 | } 52 | } 53 | } 54 | public virtual void WriteEndElement(string name) 55 | { 56 | this.curWriter.WriteEndElement(); 57 | } 58 | public virtual void WriteValue(string name, string value, Hashtable attributes) 59 | { 60 | this.WriteStartElement(name, attributes); 61 | this.curWriter.WriteString(value); 62 | this.curWriter.WriteEndElement(); 63 | } 64 | public void Flush() 65 | { 66 | this.writer.Flush(); 67 | } 68 | 69 | #endregion 70 | 71 | #region IDisposable 接口成员 72 | 73 | public void Dispose() 74 | { 75 | this.writer.Close(); 76 | } 77 | 78 | #endregion 79 | 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/ContainerService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Linq; 4 | 5 | namespace Smart.FormDesigner.Services 6 | { 7 | public interface IContainerService 8 | { 9 | IDictionary Components { get; } 10 | void Add(IComponent component, string name); 11 | IComponent Get(string name); 12 | void Remove(string name); 13 | void Clear(); 14 | 15 | } 16 | public class ContainerService : IContainerService 17 | { 18 | private Dictionary _components = new Dictionary(); 19 | public IDictionary Components { get { return this._components; } } 20 | 21 | public IComponent Get(string name) 22 | { 23 | this._components.TryGetValue(name, out IComponent component); 24 | return component; 25 | } 26 | 27 | public void Add(IComponent component, string name) 28 | { 29 | if (this._components.FirstOrDefault(c => c.Value == component).Value != null) return; 30 | 31 | this._components[name] = component; 32 | } 33 | 34 | public void Remove(string name) 35 | { 36 | if (!this._components.ContainsKey(name)) return; 37 | 38 | this._components.Remove(name); 39 | } 40 | 41 | public void Clear() 42 | { 43 | this._components.Clear(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/DefaultDesignerOptionService.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.Design; 2 | using System.Drawing; 3 | using System.Windows.Forms.Design; 4 | 5 | namespace Smart.FormDesigner.Services 6 | { 7 | /// 8 | public class DefaultDesignerOptionService : DesignerOptionService 9 | { 10 | protected override void PopulateOptionCollection(DesignerOptionCollection options) 11 | { 12 | if (options.Parent == null) 13 | { 14 | base.CreateOptionCollection(options, "DesignerOptions", new DesignerOptions() 15 | { 16 | GridSize = new Size(8, 8), 17 | ShowGrid = false, 18 | UseSmartTags = true, 19 | UseSnapLines = true, 20 | ObjectBoundSmartTagAutoShow = true, 21 | EnableInSituEditing = true, 22 | SnapToGrid = true, 23 | UseOptimizedCodeGeneration = false, 24 | }); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/DefaultMenuCommandService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.ComponentModel; 4 | using System.ComponentModel.Design; 5 | using System.Drawing; 6 | using System.Windows.Forms; 7 | 8 | namespace Smart.FormDesigner.Services 9 | { 10 | public class DefaultMenuCommandService : AbstractService, IMenuCommandService 11 | { 12 | private IDesignerHost host; 13 | private IDictionary commands; 14 | private IDictionary globalVerbs; 15 | private IDictionary menuItemVerb; 16 | private ContextMenuStrip menu; 17 | 18 | internal event EventHandler AddingVerb; 19 | public DesignerVerbCollection Verbs 20 | { 21 | get 22 | { 23 | var designerVerbCollection = new DesignerVerbCollection(); 24 | var selectionService = this.host.GetService(); 25 | var selectedComponents = selectionService.GetSelectedComponents(); 26 | foreach (IComponent component in selectedComponents) 27 | { 28 | var designer = this.host.GetDesigner(component); 29 | if (designer?.Verbs != null && AddingVerb != null) 30 | { 31 | foreach (DesignerVerb verb in designer.Verbs) 32 | { 33 | var args = new AddingVerbEventArgs(component, verb); 34 | AddingVerb(this, args); 35 | if (!args.Cancel) 36 | { 37 | designerVerbCollection.Add(verb); 38 | } 39 | } 40 | } 41 | } 42 | foreach (DesignerVerb value in this.globalVerbs.Values) 43 | { 44 | designerVerbCollection.Add(value); 45 | } 46 | return designerVerbCollection; 47 | } 48 | } 49 | 50 | public DefaultMenuCommandService(IDesignerHost host) 51 | { 52 | this.host = host; 53 | this.commands = new Hashtable(); 54 | this.globalVerbs = new Hashtable(); 55 | this.menuItemVerb = new Hashtable(); 56 | this.menu = new ContextMenuStrip(); 57 | } 58 | 59 | public void AddCommand(MenuCommand command) 60 | { 61 | if (command == null) 62 | { 63 | throw new NullReferenceException("command"); 64 | } 65 | if (this.FindCommand(command.CommandID) != null) 66 | { 67 | throw new InvalidOperationException("添加的命令已经存在"); 68 | } 69 | 70 | this.commands.Add(command.CommandID, command); 71 | } 72 | 73 | public void RemoveCommand(MenuCommand command) 74 | { 75 | if (command != null) 76 | { 77 | this.commands.Remove(command.CommandID); 78 | } 79 | } 80 | 81 | public MenuCommand FindCommand(CommandID commandID) 82 | { 83 | return (MenuCommand)this.commands[commandID]; 84 | } 85 | 86 | public bool GlobalInvoke(CommandID commandID) 87 | { 88 | if (this.globalVerbs[commandID] is DesignerVerb designerVerb) 89 | { 90 | designerVerb.Invoke(); 91 | return true; 92 | } 93 | else 94 | { 95 | if (this.FindCommand(commandID) is MenuCommand menuCommand) 96 | { 97 | menuCommand.Invoke(); 98 | return true; 99 | } 100 | } 101 | return false; 102 | } 103 | 104 | public void AddVerb(DesignerVerb verb) 105 | { 106 | if (verb == null) 107 | { 108 | throw new NullReferenceException("verb"); 109 | } 110 | this.globalVerbs.Add(verb.CommandID, verb); 111 | } 112 | 113 | public void RemoveVerb(DesignerVerb verb) 114 | { 115 | if (verb == null) 116 | { 117 | throw new NullReferenceException("verb"); 118 | } 119 | this.globalVerbs.Remove(verb.CommandID); 120 | } 121 | 122 | public void ShowContextMenu(CommandID menuID, int x, int y) 123 | { 124 | var verbs = this.Verbs; 125 | int num = verbs.Count - this.globalVerbs.Values.Count; 126 | int num2 = 0; 127 | this.menu.Items.Clear(); 128 | this.menuItemVerb.Clear(); 129 | foreach (DesignerVerb designerVerb in verbs) 130 | { 131 | if (designerVerb.Visible) 132 | { 133 | if (num > 0 && num2 == num) 134 | { 135 | this.menu.Items.Add(new ToolStripMenuItem("-")); 136 | } 137 | var menuItem = new ToolStripMenuItem(designerVerb.Text); 138 | menuItem.Click += new EventHandler(this.MenuItemClickHandler); 139 | this.menuItemVerb.Add(menuItem, designerVerb); 140 | menuItem.Enabled = designerVerb.Enabled; 141 | menuItem.Checked = designerVerb.Checked; 142 | this.menu.Items.Add(menuItem); 143 | num2++; 144 | } 145 | } 146 | var selectionService = this.host.GetService(); 147 | if (!(selectionService.PrimarySelection is Control control)) 148 | { 149 | control = (Control)this.host.RootComponent; 150 | } 151 | var point = control.PointToScreen(new Point(0, 0)); 152 | this.menu.Show(control, new Point(x - point.X, y - point.Y)); 153 | } 154 | 155 | private void MenuItemClickHandler(object sender, EventArgs e) 156 | { 157 | if (sender is ToolStripMenuItem menuItem) 158 | { 159 | if (this.menuItemVerb[menuItem] is DesignerVerb designerVerb) 160 | { 161 | designerVerb.Invoke(); 162 | } 163 | } 164 | } 165 | 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/DictionaryService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.ComponentModel.Design; 3 | 4 | namespace Smart.FormDesigner.Services 5 | { 6 | public class DictionaryService : AbstractService, IDictionaryService 7 | { 8 | private IDictionary dictionary; 9 | 10 | public DictionaryService() 11 | { 12 | this.dictionary = new Hashtable(); 13 | } 14 | 15 | public object GetValue(object key) 16 | { 17 | return this.dictionary[key]; 18 | } 19 | 20 | public void SetValue(object key, object value) 21 | { 22 | this.dictionary[key] = value; 23 | } 24 | 25 | public object GetKey(object value) 26 | { 27 | foreach (DictionaryEntry dictionaryEntry in this.dictionary) 28 | { 29 | if (dictionaryEntry.Value == value) 30 | { 31 | return dictionaryEntry.Key; 32 | } 33 | } 34 | return null; 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/EventService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Smart.FormDesigner.Services 5 | { 6 | public class EventService : IMessageFilter 7 | { 8 | const int WM_KEYDOWN = 0x100; //256 9 | const int WM_KEYUP = 0x101; //257 10 | 11 | const int WM_LBUTTONDOWN = 0x201; //513 12 | const int WM_LBUTTONUP = 0x202; //514 13 | const int WM_LBUTTONDBLCLK = 0x203; //515 14 | 15 | const int WM_RBUTTONDOWN = 0x204; //516 16 | const int WM_RBUTTONUP = 0x205; //517 17 | const int WM_RBUTTONDBLCLK = 0x206; //518 18 | 19 | const int WM_MBUTTONDOWN = 0x207; //519 20 | const int WM_MBUTTONUP = 0x208; //520 21 | 22 | private DesignerHost _host; 23 | 24 | public event EventHandler DoubleClick; 25 | public event KeyEventHandler KeyDown; 26 | public event KeyEventHandler KeyUp; 27 | public event MouseEventHandler MouseUp; 28 | public event MouseEventHandler MouseDown; 29 | 30 | public EventService(DesignerHost host) 31 | { 32 | this._host = host; 33 | } 34 | 35 | public bool PreFilterMessage(ref Message m) 36 | { 37 | bool result; 38 | if (m.Msg != WM_KEYDOWN && m.Msg == WM_KEYUP && m.Msg != WM_LBUTTONDBLCLK) 39 | { 40 | result = false; 41 | } 42 | else if (this._host.DesignedForm == null) 43 | { 44 | result = false; 45 | } 46 | else if (!(this._host.DesignContainer ?? this._host.DesignedForm).ContainsFocus) 47 | { 48 | result = false; 49 | } 50 | else 51 | { 52 | if (this.MouseDown != null && (m.Msg == WM_LBUTTONDOWN || m.Msg == WM_RBUTTONDOWN || m.Msg == WM_MBUTTONDOWN)) 53 | { 54 | var position = Cursor.Position; 55 | var button = m.Msg == WM_LBUTTONDOWN ? MouseButtons.Left 56 | : m.Msg == WM_RBUTTONDOWN ? MouseButtons.Right 57 | : MouseButtons.Middle; 58 | this.MouseDown(this, new MouseEventArgs(button, 1, position.X, position.Y, 1)); 59 | } 60 | else if (this.MouseUp != null && (m.Msg == WM_LBUTTONUP || m.Msg == WM_RBUTTONUP || m.Msg == WM_MBUTTONUP)) 61 | { 62 | var position = Cursor.Position; 63 | var button = m.Msg == WM_LBUTTONUP ? MouseButtons.Left 64 | : m.Msg == WM_RBUTTONUP ? MouseButtons.Right 65 | : MouseButtons.Middle; 66 | this.MouseUp(this, new MouseEventArgs(button, 1, position.X, position.Y, 1)); 67 | } 68 | else if (m.Msg == WM_LBUTTONDBLCLK && this.DoubleClick != null) 69 | { 70 | this.DoubleClick(this, new EventArgs()); 71 | } 72 | else if (m.Msg == WM_KEYDOWN && this.KeyDown != null) 73 | { 74 | this.KeyDown(this, new KeyEventArgs((Keys)((int)m.WParam | (int)Control.ModifierKeys))); 75 | } 76 | else if (m.Msg == WM_KEYUP && this.KeyUp != null) 77 | { 78 | this.KeyUp(this, new KeyEventArgs((Keys)((int)m.WParam | (int)Control.ModifierKeys))); 79 | } 80 | 81 | return false; 82 | } 83 | 84 | return result; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/NameCreationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.ComponentModel.Design.Serialization; 4 | 5 | namespace Smart.FormDesigner.Services 6 | { 7 | /// 8 | /// 提供可以生成对象的唯一名称的服务。 9 | /// 10 | public class NameCreationService : AbstractService, INameCreationService 11 | { 12 | #region INameCreationService 接口成员 13 | 14 | public string CreateName(IContainer container, Type dataType) 15 | { 16 | int i = 0; 17 | string typeName = dataType.Name; 18 | string name; 19 | do 20 | { 21 | i++; 22 | name = typeName + i.ToString(); 23 | if (container?.Components[name] == null) 24 | { 25 | break; 26 | } 27 | } while (true); 28 | 29 | return name; 30 | } 31 | 32 | public bool IsValidName(string name) 33 | { 34 | // 名称为空 35 | if (name == null || name.Length == 0) 36 | { 37 | return false; 38 | } 39 | // 不是字母开头 40 | if (!char.IsLetter(name, 0)) 41 | { 42 | return false; 43 | } 44 | // 含有不允许的字母 45 | for (int i = 0; i < name.Length; i++) 46 | { 47 | var c = name[i]; 48 | if (!char.IsLetterOrDigit(name, i) && c != '_' && c != ' ' && c != '-' && c != '.') 49 | { 50 | return false; 51 | } 52 | } 53 | return true; 54 | } 55 | 56 | public void ValidateName(string name) 57 | { 58 | if (!IsValidName(name)) 59 | { 60 | throw new ArgumentException($"无效的名称: {name}"); 61 | } 62 | } 63 | 64 | #endregion 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/SelectionService.cs: -------------------------------------------------------------------------------- 1 | using Smart.FormDesigner.Internal; 2 | using System; 3 | using System.Collections; 4 | using System.ComponentModel; 5 | using System.ComponentModel.Design; 6 | using System.Windows.Forms; 7 | 8 | namespace Smart.FormDesigner.Services 9 | { 10 | public class SelectionService : AbstractService, ISelectionService 11 | { 12 | private IDesignerHost host = null; 13 | private IComponent removedComponent = null; 14 | private ArrayList selectedComponents = null; 15 | 16 | public event EventHandler SelectionChanging; 17 | public event EventHandler SelectionChanged; 18 | 19 | public object PrimarySelection 20 | { 21 | get 22 | { 23 | if (this.selectedComponents.Count > 0) 24 | { 25 | return this.selectedComponents[0]; 26 | } 27 | return null; 28 | } 29 | } 30 | 31 | public int SelectionCount 32 | { 33 | get 34 | { 35 | return this.selectedComponents.Count; 36 | } 37 | } 38 | 39 | public SelectionService(IDesignerHost host) 40 | { 41 | this.host = host; 42 | this.selectedComponents = new ArrayList(); 43 | if (host.GetService(typeof(IComponentChangeService)) is IComponentChangeService componentChangeService) 44 | { 45 | componentChangeService.ComponentRemoving += new ComponentEventHandler(this.OnComponentRemoving); 46 | } 47 | } 48 | 49 | public ICollection GetSelectedComponents() 50 | { 51 | return this.selectedComponents.ToArray(); 52 | } 53 | 54 | public bool GetComponentSelected(object component) 55 | { 56 | return this.selectedComponents.Contains(component); 57 | } 58 | 59 | public void SetSelectedComponents(ICollection components, SelectionTypes selectionType) 60 | { 61 | bool ctrlFlag = false; 62 | bool shiftFlag = false; 63 | if (this.removedComponent != null && components != null && components.Count == 1) 64 | { 65 | var enumerator = components.GetEnumerator(); 66 | enumerator.MoveNext(); 67 | if (enumerator.Current == this.removedComponent) 68 | { 69 | return; 70 | } 71 | } 72 | if (components == null) 73 | { 74 | object[] array = new object[1]; 75 | components = array; 76 | } 77 | var designerHost = this.host as DesignerHost; 78 | var arrayList = new ArrayList(this.selectedComponents); 79 | if ((selectionType & SelectionTypes.Primary) == SelectionTypes.Primary) 80 | { 81 | ctrlFlag = ((Control.ModifierKeys & Keys.Control) == Keys.Control); 82 | shiftFlag = ((Control.ModifierKeys & Keys.Shift) == Keys.Shift); 83 | } 84 | if (selectionType == SelectionTypes.Replace) 85 | { 86 | this.selectedComponents.Clear(); 87 | foreach (object current in components) 88 | { 89 | if (current != this.removedComponent) 90 | { 91 | if (current != null && !this.selectedComponents.Contains(current) && (designerHost == null || designerHost.DesignContainer != null || current != this.host.RootComponent)) 92 | { 93 | this.selectedComponents.Add(current); 94 | } 95 | } 96 | } 97 | } 98 | else 99 | { 100 | if (!ctrlFlag && !shiftFlag && components.Count == 1) 101 | { 102 | foreach (object current in components) 103 | { 104 | if (!this.selectedComponents.Contains(current)) 105 | { 106 | this.selectedComponents.Clear(); 107 | } 108 | } 109 | } 110 | foreach (object current in components) 111 | { 112 | if (current != this.removedComponent) 113 | { 114 | if (current != null && (designerHost == null || designerHost.DesignContainer != null || current != this.host.RootComponent)) 115 | { 116 | if (ctrlFlag || shiftFlag) 117 | { 118 | if (this.selectedComponents.Contains(current)) 119 | { 120 | this.selectedComponents.Remove(current); 121 | } 122 | else 123 | { 124 | this.selectedComponents.Insert(0, current); 125 | } 126 | } 127 | else if (!this.selectedComponents.Contains(current)) 128 | { 129 | this.selectedComponents.Add(current); 130 | } 131 | else 132 | { 133 | this.selectedComponents.Remove(current); 134 | this.selectedComponents.Insert(0, current); 135 | } 136 | } 137 | } 138 | } 139 | } 140 | bool noChangeFlag = true; 141 | if (arrayList.Count != this.selectedComponents.Count) 142 | { 143 | noChangeFlag = false; 144 | } 145 | else 146 | { 147 | for (int i = 0; i < arrayList.Count; i++) 148 | { 149 | object obj = arrayList[i]; 150 | object selectedObj = this.selectedComponents[i]; 151 | if (!obj.Equals(selectedObj)) 152 | { 153 | noChangeFlag = false; 154 | break; 155 | } 156 | } 157 | } 158 | if (!noChangeFlag) 159 | { 160 | try 161 | { 162 | this.SelectionChanging?.Invoke(this, EventArgs.Empty); 163 | this.SelectionChanged?.Invoke(this, EventArgs.Empty); 164 | } 165 | catch (Exception) 166 | { 167 | } 168 | } 169 | } 170 | 171 | public void SetSelectedComponents(ICollection components) 172 | { 173 | this.SetSelectedComponents(components, SelectionTypes.Replace); 174 | } 175 | 176 | protected void OnComponentRemoving(object sender, ComponentEventArgs e) 177 | { 178 | this.removedComponent = e.Component; 179 | } 180 | 181 | public void OnComponentRemoved(object sender, ComponentEventArgs e) 182 | { 183 | this.removedComponent = null; 184 | if (this.selectedComponents.Contains(e.Component)) 185 | { 186 | this.SelectionChanging?.Invoke(this, e); 187 | this.selectedComponents.Remove(e.Component); 188 | this.SelectionChanged?.Invoke(this, e); 189 | } 190 | } 191 | 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/TypeDescriptorFilterService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.ComponentModel; 4 | using System.ComponentModel.Design; 5 | 6 | namespace Smart.FormDesigner.Services 7 | { 8 | public class TypeDescriptorFilterService : ITypeDescriptorFilterService 9 | { 10 | private IDesignerHost _host; 11 | 12 | internal event EventHandler FilterAttribute; 13 | internal event EventHandler FilterEvnt; 14 | internal event EventHandler FilterProperty; 15 | 16 | public TypeDescriptorFilterService(IDesignerHost host) 17 | { 18 | this._host = host; 19 | } 20 | 21 | public bool FilterAttributes(IComponent component, IDictionary attributes) 22 | { 23 | bool flag = false; 24 | var designer = this._host.GetDesigner(component); 25 | if (designer is IDesignerFilter designerFilter) 26 | { 27 | designerFilter.PreFilterAttributes(attributes); 28 | designerFilter.PostFilterAttributes(attributes); 29 | flag = true; 30 | } 31 | if (this.FilterAttribute != null && !(component is DesignSurface)) 32 | { 33 | var filterEventArgs = new FilterEventArgs() 34 | { 35 | Data = attributes, 36 | Caching = true 37 | }; 38 | this.FilterAttribute(component, filterEventArgs); 39 | return filterEventArgs.Caching; 40 | } 41 | return flag; 42 | } 43 | 44 | public bool FilterEvents(IComponent component, IDictionary events) 45 | { 46 | bool flag = false; 47 | var designer = this._host.GetDesigner(component); 48 | if (designer is IDesignerFilter designerFilter) 49 | { 50 | designerFilter.PreFilterEvents(events); 51 | designerFilter.PostFilterEvents(events); 52 | flag = true; 53 | } 54 | if (this.FilterEvnt != null && !(component is DesignSurface)) 55 | { 56 | var filterEventArgs = new FilterEventArgs() 57 | { 58 | Data = events, 59 | Caching = true 60 | }; 61 | this.FilterEvnt(component, filterEventArgs); 62 | return filterEventArgs.Caching; 63 | } 64 | return flag; 65 | } 66 | 67 | public bool FilterProperties(IComponent component, IDictionary properties) 68 | { 69 | bool flag = false; 70 | var designer = this._host.GetDesigner(component); 71 | if (designer is IDesignerFilter designerFilter) 72 | { 73 | designerFilter.PreFilterProperties(properties); 74 | designerFilter.PostFilterProperties(properties); 75 | flag = true; 76 | } 77 | if (this.FilterProperty != null && !(component is DesignSurface)) 78 | { 79 | var filterEventArgs = new FilterEventArgs() 80 | { 81 | Data = properties, 82 | Caching = true 83 | }; 84 | this.FilterProperty(component, filterEventArgs); 85 | return filterEventArgs.Caching; 86 | } 87 | return flag; 88 | } 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/TypeDiscoveryService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.Design; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Windows.Forms; 10 | using System.Xml; 11 | 12 | namespace Smart.FormDesigner.Services 13 | { 14 | /// 15 | /// 提供程序集或类型检索服务 16 | /// 17 | public class TypeDiscoveryService : AbstractService, ITypeDiscoveryService 18 | { 19 | private List assemblies; 20 | 21 | public TypeDiscoveryService() 22 | { 23 | this.assemblies = new List(); 24 | this.assemblies.AddRange(new Assembly[] { 25 | typeof(Size).Assembly, 26 | typeof(Control).Assembly, 27 | typeof(DataSet).Assembly, 28 | typeof(XmlElement).Assembly 29 | }); 30 | } 31 | 32 | // 发现设计时可用的类型 33 | #region ITypeDiscoveryService 接口成员 34 | 35 | /// 36 | public ICollection GetTypes(Type baseType, bool excludeGlobalTypes) 37 | { 38 | var list = new List(); 39 | if (baseType == null) 40 | { 41 | baseType = typeof(object); 42 | } 43 | foreach (var assembly in this.assemblies) 44 | { 45 | if (!excludeGlobalTypes || !assembly.GlobalAssemblyCache) 46 | { 47 | list.AddRange(assembly.GetTypes().Where(t => t.IsSubclassOf(baseType))); 48 | } 49 | } 50 | return list; 51 | } 52 | 53 | #endregion 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Designer/Services/TypeResolutionService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.Design; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Windows.Forms; 10 | using System.Xml; 11 | 12 | namespace Smart.FormDesigner.Services 13 | { 14 | /// 15 | /// 提供程序集或类型检索服务 16 | /// 17 | public class TypeResolutionService : AbstractService, ITypeResolutionService, ITypeDiscoveryService 18 | { 19 | private List assemblies; 20 | 21 | public TypeResolutionService() 22 | { 23 | this.assemblies = new List(); 24 | this.assemblies.AddRange(new Assembly[] { 25 | typeof(Size).Assembly, 26 | typeof(Control).Assembly, 27 | typeof(DataSet).Assembly, 28 | typeof(XmlElement).Assembly 29 | }); 30 | } 31 | 32 | // 提供按名称检索程序集或类型 33 | #region ITypeResolutionService 接口成员 34 | 35 | public Assembly GetAssembly(AssemblyName name, bool throwOnError) 36 | { 37 | var assembly = this.assemblies 38 | .Find(a => a.GetName().FullName.CompareTo(name.FullName) == 0); 39 | 40 | if (assembly != null) 41 | { 42 | return assembly; 43 | } 44 | 45 | try 46 | { 47 | assembly = Assembly.Load(name); 48 | } 49 | catch (Exception ex) 50 | { 51 | if (throwOnError) 52 | { 53 | throw ex; 54 | } 55 | } 56 | 57 | if (assembly != null) 58 | { 59 | this.assemblies.Add(assembly); 60 | return assembly; 61 | } 62 | 63 | return null; 64 | } 65 | 66 | public Assembly GetAssembly(AssemblyName name) 67 | { 68 | return this.GetAssembly(name, false); 69 | } 70 | 71 | public string GetPathOfAssembly(AssemblyName name) 72 | { 73 | string result = this.assemblies 74 | .Find(a => a.GetName().FullName.CompareTo(name.FullName) == 0)?.Location; 75 | return result; 76 | } 77 | 78 | public Type GetType(string name, bool throwOnError, bool ignoreCase) 79 | { 80 | var type = Type.GetType(name, throwOnError, ignoreCase); 81 | if (type == null) 82 | { 83 | this.assemblies.Any(assembly => 84 | { 85 | type = assembly.GetType(name, false, ignoreCase); 86 | return type != null; 87 | }); 88 | } 89 | if (type == null && throwOnError) 90 | { 91 | throw new TypeLoadException($"未找到类型 {name}"); 92 | } 93 | return type; 94 | } 95 | 96 | public Type GetType(string name, bool throwOnError) 97 | { 98 | return this.GetType(name, throwOnError, false); 99 | } 100 | 101 | public Type GetType(string name) 102 | { 103 | return this.GetType(name, false, false); 104 | } 105 | 106 | public void ReferenceAssembly(AssemblyName name) 107 | { 108 | this.GetAssembly(name, false); 109 | } 110 | 111 | #endregion 112 | 113 | // 发现设计时可用的类型 114 | #region ITypeDiscoveryService 接口成员 115 | 116 | /// 117 | public ICollection GetTypes(Type baseType, bool excludeGlobalTypes) 118 | { 119 | var list = new List(); 120 | if (baseType == null) 121 | { 122 | baseType = typeof(object); 123 | } 124 | foreach (var assembly in this.assemblies) 125 | { 126 | if (!excludeGlobalTypes || !assembly.GlobalAssemblyCache) 127 | { 128 | list.AddRange(assembly.GetTypes().Where(t => t.IsSubclassOf(baseType))); 129 | } 130 | } 131 | return list; 132 | } 133 | 134 | #endregion 135 | 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Disposable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Smart.FormDesigner 4 | { 5 | public abstract class Disposable : IDisposable 6 | { 7 | private bool disposedValue; 8 | 9 | protected virtual void Dispose(bool disposing) 10 | { 11 | if (!disposedValue) 12 | { 13 | if (disposing) 14 | { 15 | // TODO: 释放托管状态(托管对象) 16 | } 17 | 18 | // TODO: 释放未托管的资源(未托管的对象)并重写终结器 19 | // TODO: 将大型字段设置为 null 20 | disposedValue = true; 21 | } 22 | } 23 | 24 | // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器 25 | // ~Disposable() 26 | // { 27 | // // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 28 | // Dispose(disposing: false); 29 | // } 30 | 31 | public void Dispose() 32 | { 33 | // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 34 | Dispose(disposing: true); 35 | GC.SuppressFinalize(this); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Extensions/ControlExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Reflection; 5 | using System.Windows.Forms; 6 | 7 | namespace Smart.FormDesigner 8 | { 9 | internal static class ControlExtensions 10 | { 11 | public static Control FindFirst(this Control control, string name) 12 | { 13 | if (control == null || string.IsNullOrEmpty(name)) 14 | { 15 | return null; 16 | } 17 | var controls = control.Controls.Find(name, true); 18 | if (controls.Length > 0) 19 | { 20 | return controls[0]; 21 | } 22 | return null; 23 | } 24 | 25 | public static bool HaveParentInList(this Control control, List parentsList) 26 | { 27 | if (control == null) 28 | { 29 | return false; 30 | } 31 | 32 | for (var parent = control.Parent; parent != null; parent = parent.Parent) 33 | { 34 | if (parentsList.Contains(parent)) 35 | { 36 | return true; 37 | } 38 | } 39 | return false; 40 | } 41 | 42 | public static bool IsVisiable(this Control control) 43 | { 44 | bool visible = (bool)typeof(Control).InvokeMember( 45 | "GetState", 46 | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, 47 | null, 48 | control, 49 | new object[] { 2 }); 50 | return visible; 51 | } 52 | 53 | public static Control[] ToArray(this Control.ControlCollection controls) 54 | { 55 | var arrray = new Control[controls.Count]; 56 | controls.CopyTo(arrray, 0); 57 | return arrray; 58 | } 59 | 60 | 61 | #region Tab 顺序 62 | 63 | public static Control First(this Control.ControlCollection controls) 64 | { 65 | if (controls.Count == 0) 66 | { 67 | return null; 68 | } 69 | int tabIndex = controls[0].TabIndex; 70 | int index = 0; 71 | for (int i = 1; i < controls.Count; i++) 72 | { 73 | if (controls[i].TabIndex < tabIndex) 74 | { 75 | index = i; 76 | tabIndex = controls[i].TabIndex; 77 | } 78 | } 79 | return controls[index]; 80 | } 81 | 82 | public static Control Last(this Control.ControlCollection controls) 83 | { 84 | if (controls.Count == 0) 85 | { 86 | return null; 87 | } 88 | 89 | int tabIndex = controls[0].TabIndex; 90 | int index = 0; 91 | for (int i = 1; i < controls.Count; i++) 92 | { 93 | if (controls[i].TabIndex >= tabIndex) 94 | { 95 | index = i; 96 | tabIndex = controls[i].TabIndex; 97 | } 98 | } 99 | return controls[index]; 100 | } 101 | 102 | public static Control Next(this Control.ControlCollection controls, Control current) 103 | { 104 | int currentIndex = controls.IndexOf(current); 105 | int index = -1; 106 | int currentTabIndex = current.TabIndex; 107 | int tabIndex = 0; 108 | bool flag = false; 109 | for (int i = 0; i < controls.Count; i++) 110 | { 111 | if (controls[i].TabIndex >= currentTabIndex) 112 | { 113 | if (controls[i].TabIndex != currentTabIndex || i > currentIndex) 114 | { 115 | if (controls[i].TabIndex == currentTabIndex) 116 | { 117 | index = i; 118 | break; 119 | } 120 | if (!flag) 121 | { 122 | flag = true; 123 | tabIndex = controls[i].TabIndex; 124 | index = i; 125 | } 126 | else if (controls[i].TabIndex < tabIndex) 127 | { 128 | tabIndex = controls[i].TabIndex; 129 | index = i; 130 | } 131 | } 132 | } 133 | } 134 | return (index < 0) ? null : controls[index]; 135 | } 136 | 137 | public static Control Previous(this Control.ControlCollection controls, Control current) 138 | { 139 | int currentIndex = controls.IndexOf(current); 140 | int index = -1; 141 | int currentTabIndex = current.TabIndex; 142 | int tabIndex = 0; 143 | bool flag = false; 144 | for (int i = 0; i < controls.Count; i++) 145 | { 146 | if (controls[i].TabIndex <= currentTabIndex) 147 | { 148 | if (controls[i].TabIndex != currentTabIndex || i < currentIndex) 149 | { 150 | if (controls[i].TabIndex == currentTabIndex) 151 | { 152 | index = i; 153 | break; 154 | } 155 | if (!flag) 156 | { 157 | flag = true; 158 | tabIndex = controls[i].TabIndex; 159 | index = i; 160 | } 161 | else if (controls[i].TabIndex > tabIndex) 162 | { 163 | tabIndex = controls[i].TabIndex; 164 | index = i; 165 | } 166 | } 167 | } 168 | } 169 | return (index < 0) ? null : controls[index]; 170 | } 171 | 172 | public static Control Next(this Control current) 173 | { 174 | return Next(current.Parent.Controls, current); 175 | } 176 | 177 | public static Control Previous(this Control current) 178 | { 179 | return Previous(current.Parent.Controls, current); 180 | } 181 | #endregion 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Extensions/IDesignerHostExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.Design; 3 | using System.Windows.Forms; 4 | 5 | namespace Smart.FormDesigner 6 | { 7 | public static class DesignerHostExtensions 8 | { 9 | public static void SelectNextControl(this IDesignerHost designerHost, bool next) 10 | { 11 | if (designerHost.RootComponent is Control rootControl) 12 | { 13 | if (designerHost.GetService(typeof(ISelectionService)) is ISelectionService selectionService) 14 | { 15 | var control = selectionService.PrimarySelection as Control; 16 | if (control == null) 17 | { 18 | if (next) 19 | { 20 | control = rootControl.Controls.First(); 21 | } 22 | else 23 | { 24 | control = rootControl; 25 | while (control.Controls.Count != 0) 26 | { 27 | control = control.Controls.Last(); 28 | if (control is ContainerControl) 29 | { 30 | break; 31 | } 32 | } 33 | } 34 | } 35 | else 36 | { 37 | bool flag = false; 38 | var parent = control.Parent; 39 | if (parent == null || (control == rootControl && control.Controls.Count == 0)) 40 | { 41 | return; 42 | } 43 | if (!next) 44 | { 45 | if (control == rootControl) 46 | { 47 | control = control.Controls.Last(); 48 | } 49 | else if (control.TabIndex == 0 && parent != rootControl) 50 | { 51 | control = parent; 52 | parent = parent.Parent; 53 | } 54 | else 55 | { 56 | control = control.Previous(); 57 | while (control != null && control.Controls.Count != 0 && !(control is ContainerControl) && !(control is DataGridView)) 58 | { 59 | control = control.Controls.Last(); 60 | } 61 | } 62 | } 63 | else if (control.Controls.Count != 0 && ((!(control is ContainerControl) && !(control is DataGridView)) || control == rootControl)) 64 | { 65 | control = control.Controls.First(); 66 | } 67 | else 68 | { 69 | while (control == parent.Controls.Last() && parent != rootControl) 70 | { 71 | control = parent; 72 | parent = parent.Parent; 73 | flag = true; 74 | } 75 | if (control.Controls.Count == 0 || control is ContainerControl || control is DataGridView || flag) 76 | { 77 | control = control.Next(); 78 | } 79 | } 80 | } 81 | if (control == null) 82 | { 83 | control = rootControl; 84 | } 85 | var components = new Control[] 86 | { 87 | control 88 | }; 89 | selectionService.SetSelectedComponents(components, SelectionTypes.Replace); 90 | } 91 | } 92 | } 93 | 94 | public static void Layout(this IDesignerHost designerHost, string transDesc, Action setAction) 95 | { 96 | if (designerHost.GetService(typeof(ISelectionService)) is ISelectionService selectionService) 97 | { 98 | var selectedComponents = selectionService.GetSelectedComponents(); 99 | if (selectedComponents.Count > 0) 100 | { 101 | var rootControl = (Control)designerHost.RootComponent; 102 | if (rootControl != null) 103 | { 104 | rootControl.SuspendLayout(); 105 | } 106 | using (var ts = designerHost.CreateTransaction(transDesc)) 107 | { 108 | var primaryControl = selectionService.PrimarySelection as Control; 109 | if (primaryControl != null) 110 | { 111 | var componentChangeService = designerHost.GetService(); 112 | foreach (object current in selectedComponents) 113 | { 114 | var control = current as Control; 115 | if (control != null && control.Parent == primaryControl.Parent) 116 | { 117 | componentChangeService.OnComponentChanging(control, null); 118 | setAction(control); 119 | componentChangeService.OnComponentChanged(control, null, null, null); 120 | } 121 | } 122 | } 123 | ts.Commit(); 124 | } 125 | if (rootControl != null) 126 | { 127 | rootControl.ResumeLayout(); 128 | } 129 | } 130 | } 131 | } 132 | 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Extensions/IServiceProviderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Smart.FormDesigner 4 | { 5 | public static class IServiceProviderExtensions 6 | { 7 | public static T GetService(this IServiceProvider serviceProvider) 8 | { 9 | return (T)serviceProvider.GetService(typeof(T)); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Extensions/ObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace Smart.FormDesigner 4 | { 5 | internal static class ObjectExtensions 6 | { 7 | public static void CopyPropertiesTo(this object src, object dest) 8 | { 9 | var srcProperties = TypeDescriptor.GetProperties(src); 10 | var destProperties = TypeDescriptor.GetProperties(dest); 11 | foreach (PropertyDescriptor srcPropertyDescriptor in srcProperties) 12 | { 13 | if (!srcPropertyDescriptor.IsReadOnly && srcPropertyDescriptor.IsBrowsable) 14 | { 15 | var destPropertyDescriptor = destProperties[srcPropertyDescriptor.Name]; 16 | if (destPropertyDescriptor != null) 17 | { 18 | object srcValue = srcPropertyDescriptor.GetValue(src); 19 | object destValue = destPropertyDescriptor.GetValue(dest); 20 | if ((destValue != null && !destValue.Equals(srcValue)) || srcValue != null) 21 | { 22 | destPropertyDescriptor.SetValue(dest, srcValue); 23 | } 24 | } 25 | } 26 | } 27 | } 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Extensions/PointExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace Smart.FormDesigner 5 | { 6 | internal static class PointExtensions 7 | { 8 | /// 9 | /// 计算两点间的距离 10 | /// 11 | /// 12 | /// 13 | /// 14 | public static int Distance(this Point p1, Point p2) 15 | { 16 | // 勾股定理计算 17 | int x = p1.X - p2.X; 18 | int y = p1.Y - p2.Y; 19 | return (int)Math.Sqrt(x * x + y * y); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Smart.FormDesigner 2 | { 3 | internal static class StringExtensions 4 | { 5 | public static bool IsNullOrEmpty(this string str) 6 | { 7 | return string.IsNullOrEmpty(str); 8 | } 9 | 10 | public static bool IsNullOrWhiteSpace(this string str) 11 | { 12 | return string.IsNullOrWhiteSpace(str); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Extensions/TypeConverterExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace Smart.FormDesigner 5 | { 6 | internal static class TypeConverterExtensions 7 | { 8 | public static bool CanConvert(this TypeConverter cnv, Type type) 9 | { 10 | return cnv.CanConvertFrom(type) && cnv.CanConvertTo(type); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Extensions/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Data; 4 | using System.Windows.Forms; 5 | 6 | namespace Smart.FormDesigner 7 | { 8 | internal static class TypeExtensions 9 | { 10 | private const string INFRAGISTICS = "Infragistics"; 11 | public static bool IsDataCollection(this Type type) 12 | { 13 | bool result; 14 | if (type.FullName.IndexOf(INFRAGISTICS) >= 0) 15 | { 16 | result = typeof(ICollection).IsAssignableFrom(type); 17 | } 18 | else 19 | { 20 | result = (typeof(InternalDataCollectionBase).IsAssignableFrom(type) || typeof(BaseCollection).IsAssignableFrom(type)); 21 | } 22 | return result; 23 | } 24 | 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Smart.FormDesigner.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Smart.FormDesigner.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性,对 51 | /// 使用此强类型资源类的所有资源查找执行重写。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 65 | /// 66 | internal static System.Drawing.Bitmap arrow_cursor_16px { 67 | get { 68 | object obj = ResourceManager.GetObject("arrow_cursor_16px", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 75 | /// 76 | internal static System.Drawing.Bitmap launch_16x { 77 | get { 78 | object obj = ResourceManager.GetObject("launch_16x", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。 85 | /// 86 | internal static System.Drawing.Bitmap normal_16x { 87 | get { 88 | object obj = ResourceManager.GetObject("normal_16x", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\arrow_cursor_16px.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\launch_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\normal_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Resources/arrow_cursor_16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/src/Smart.FormDesigner/Resources/arrow_cursor_16px.png -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Resources/launch_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/src/Smart.FormDesigner/Resources/launch_16x.png -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Resources/normal_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmallAnts/FormDesigner/5071324d01444b644a52c4c50203a103057935c7/src/Smart.FormDesigner/Resources/normal_16x.png -------------------------------------------------------------------------------- /src/Smart.FormDesigner/Smart.FormDesigner.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net40 5 | true 6 | false 7 | 1.4.* 8 | 1.4.3.0 9 | False 10 | 11 | Smart.FormDesigner 12 | $(FileVersion) 13 | SmallAnts 14 | Smart.FormDesigner 15 | LJF 16 | Copyright © SmallAnts 2018 17 | true 18 | MIT 19 | 20 | https://github.com/SmallAnts/FormDesigner 21 | https://github.com/SmallAnts/FormDesigner 22 | smart; form designer; custom form designer; winform; 自定义表单设计器 23 | FormDesigner 是一个基于.NET C# 开发的 Winform 自定义表单设计组件。支持Xml保存和加载表单,支持控件的拖放和属性设置,支持复制、粘贴、对齐、撤销、重做等设计时操作。 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | ..\..\nuget\ 33 | true 34 | 35 | 36 | 37 | 38 | UserControl 39 | 40 | 41 | UserControl 42 | 43 | 44 | True 45 | True 46 | Resources.resx 47 | 48 | 49 | 50 | 51 | 52 | Smart.FormDesigner 53 | 54 | 55 | DesignerWindow.cs 56 | 57 | 58 | ResXFileCodeGenerator 59 | Resources.Designer.cs 60 | 61 | 62 | 63 | 64 | --------------------------------------------------------------------------------