├── .editorconfig
├── .gitattributes
├── .gitignore
├── DbToys.sln
├── LICENSE.md
├── PRIVACY.md
├── README.md
├── SampleTemplates
├── Acartons Admin
│ ├── edit-component.tpl
│ ├── edit-html.tpl
│ ├── list-component.tpl
│ ├── list-html.tpl
│ ├── service.tpl
│ └── type.tpl
├── Acartons Api
│ ├── controller.tpl
│ ├── dto.tpl
│ ├── model.tpl
│ ├── repository.tpl
│ └── service.tpl
└── Netcool Api
│ ├── controller.tpl
│ ├── dto.tpl
│ └── service.tpl
├── images
├── screen1.png
├── screen2.png
├── screen3.png
└── screen5.png
└── src
├── .vsconfig
├── Build.props
├── DbToys.Core
├── Constants.cs
├── Database
│ ├── DataBaseType.cs
│ ├── Inflector.cs
│ ├── MySqlSchemaReader.cs
│ ├── PostgreSqlSchemaReader.cs
│ ├── SchemaReader.cs
│ ├── SqlServerSchemaReader.cs
│ └── Table.cs
├── DbToys.Core.csproj
├── Excel
│ ├── ExcelService.cs
│ ├── ExcelStyleOptions.cs
│ └── IExcelService.cs
├── ICodeGenerator.cs
├── Log
│ └── Logger.cs
├── NameValue.cs
├── Scriban
│ └── CustomScribanStringFunctions.cs
└── WorkshopContext.cs
└── DbToys.WinUI
├── Activation
├── ActivationHandler.cs
├── DefaultActivationHandler.cs
└── IActivationHandler.cs
├── App.xaml
├── App.xaml.cs
├── Assets
├── Icons
│ ├── add_file.png
│ ├── add_folder.png
│ ├── broken_link.png
│ ├── chain_start.png
│ ├── code_file.png
│ ├── connected.png
│ ├── database.png
│ ├── database_server.png
│ ├── document.png
│ ├── flash_on.png
│ ├── github.png
│ ├── microsoft_excel.png
│ ├── microsoft_sql_server.png
│ ├── mysql.png
│ ├── opened_folder.png
│ ├── paint_palette.png
│ ├── postgresql.png
│ ├── refresh.png
│ ├── remove.png
│ ├── rename.png
│ ├── sms.png
│ ├── source_code.png
│ └── table.png
├── LockScreenLogo.scale-200.png
├── Monaco
│ ├── monaco.html
│ └── vs
│ │ ├── base
│ │ ├── browser
│ │ │ └── ui
│ │ │ │ └── codicons
│ │ │ │ └── codicon
│ │ │ │ └── codicon.ttf
│ │ ├── common
│ │ │ └── worker
│ │ │ │ └── simpleWorker.nls.js
│ │ └── worker
│ │ │ └── workerMain.js
│ │ ├── basic-languages
│ │ └── csharp
│ │ │ └── csharp.js
│ │ ├── editor
│ │ ├── editor.main.css
│ │ ├── editor.main.js
│ │ └── editor.main.nls.js
│ │ └── loader.js
├── SplashScreen.scale-400.png
├── Square150x150Logo.scale-200.png
├── Square150x150Logo.scale-400.png
├── Square310x310Logo.scale-200.png
├── Square310x310Logo.scale-400.png
├── Square44x44Logo.scale-150.png
├── Square44x44Logo.scale-200.png
├── Square44x44Logo.scale-400.png
├── Square44x44Logo.targetsize-20_altform-unplated.png
├── Square44x44Logo.targetsize-24_altform-unplated.png
├── Square44x44Logo.targetsize-256_altform-lightunplated.png
├── Square44x44Logo.targetsize-256_altform-unplated.png
├── Square44x44Logo.targetsize-32_altform-unplated.png
├── Square44x44Logo.targetsize-48_altform-lightunplated.png
├── Square44x44Logo.targetsize-48_altform-unplated.png
├── StoreLogo.scale-200.png
├── StoreLogo.scale-400.png
├── Wide310x150Logo.scale-200.png
├── WindowIcon.ico
└── global.tpl
├── Behaviors
├── NavigationViewHeaderBehavior.cs
└── NavigationViewHeaderMode.cs
├── CodeEditor
├── CompletionItem.cs
└── CompletionItemKind.cs
├── DbToys.WinUI.csproj
├── Helpers
├── DependencyObjectHelper.cs
├── DialogFactory.cs
├── DialogHelper.cs
├── EnumToBooleanConverter.cs
├── FileSystemHelper.cs
├── FrameExtensions.cs
├── Json.cs
├── NavigationHelper.cs
├── ResourceExtensions.cs
├── RuntimeHelper.cs
├── SettingsStorageExtensions.cs
├── StorageItemIconHelper.cs
├── TitleBarHelper.cs
├── UIElementExtensions.cs
└── Win32Helper.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Package.StoreAssociation.xml
├── Package.appinstaller
├── Package.appxmanifest
├── Properties
└── launchsettings.json
├── README.md
├── Services
├── ActivationService.cs
├── CodeTemplateStorageService.cs
├── FileSystem
│ ├── BaseStorageFile.cs
│ ├── BaseStorageFolder.cs
│ ├── IBaseStorageFile.cs
│ └── IBaseStorageFolder.cs
├── IActivationService.cs
├── IDatabaseAccountHistory.cs
├── INavigationService.cs
├── INavigationViewService.cs
├── INotificationService.cs
├── IPageService.cs
├── IThemeSelectorService.cs
├── LoadingService.cs
├── NavigationService.cs
├── NavigationViewService.cs
├── PageService.cs
├── Settings
│ ├── FileService.cs
│ ├── GeneralSettingsService.cs
│ ├── IFileService.cs
│ ├── ISettingsService.cs
│ ├── SettingsServiceBase.cs
│ └── UiSettingsService.cs
└── ThemeSelectorService.cs
├── Strings
└── en-us
│ └── Resources.resw
├── Styles
├── Colors.xaml
├── FontSizes.xaml
├── GridSplitterStyle.xaml
├── NotificationStyle.xaml
├── TextBlock.xaml
└── Thickness.xaml
├── TemplateStudio.xml
├── Usings.cs
├── ViewModels
├── CodeTemplate
│ ├── ActionArgs.cs
│ ├── ProjectFolderItem.cs
│ ├── TemplateFileItem.cs
│ └── TemplateViewModel.cs
├── CodeTemplateExplorerViewModel.cs
├── Database
│ ├── ConnectionItem.cs
│ ├── DatabaseItem.cs
│ └── TableItem.cs
├── DatabaseViewModel.cs
├── Dialogs
│ ├── DynamicDialogViewModel.cs
│ ├── GenerateCodeViewModel.cs
│ ├── IDialog.cs
│ ├── MysqlConnectViewModel.cs
│ ├── PostgreSqlConnectViewModel.cs
│ ├── SqlServerConnectViewModel.cs
│ └── TemplateFilenameViewModel.cs
├── INavigationAware.cs
├── LogViewModel.cs
├── MainViewModel.cs
├── SettingsViewModel.cs
├── ShellViewModel.cs
├── TableDetailViewModel.cs
└── TreeItem.cs
├── Views
├── CodeTemplate
│ ├── TemplatePage.xaml
│ └── TemplatePage.xaml.cs
├── CodeTemplateExplorerPage.xaml
├── CodeTemplateExplorerPage.xaml.cs
├── DatabasePage.xaml
├── DatabasePage.xaml.cs
├── Dialogs
│ ├── DynamicDialog.xaml
│ ├── DynamicDialog.xaml.cs
│ ├── GenerateCodeDialog.xaml
│ ├── GenerateCodeDialog.xaml.cs
│ ├── MysqlConnectDialog.xaml
│ ├── MysqlConnectDialog.xaml.cs
│ ├── PostgreSqlConnectDialog.xaml
│ ├── PostgreSqlConnectDialog.xaml.cs
│ ├── SqlServerConnectDialog.xaml
│ ├── SqlServerConnectDialog.xaml.cs
│ ├── TemplateFilenameDialog.xaml
│ └── TemplateFilenameDialog.xaml.cs
├── LogPage.xaml
├── LogPage.xaml.cs
├── MainPage.xaml
├── MainPage.xaml.cs
├── SettingsPage.xaml
├── SettingsPage.xaml.cs
├── ShellPage.xaml
├── ShellPage.xaml.cs
├── TableDetailPage.xaml
└── TableDetailPage.xaml.cs
├── app.manifest
└── appsettings.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 |
3 | # IDE0058: Expression value is never used
4 | dotnet_diagnostic.IDE0058.severity = silent
5 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ---> C Sharp
2 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
3 | [Bb]in/
4 | [Oo]bj/
5 |
6 | # mstest test results
7 | TestResults
8 |
9 | ## Ignore Visual Studio temporary files, build results, and
10 | ## files generated by popular Visual Studio add-ons.
11 |
12 | # User-specific files
13 | *.suo
14 | *.user
15 | *.sln.docstates
16 |
17 | # Build results
18 | [Dd]ebug/
19 | [Rr]elease/
20 | x64/
21 | *_i.c
22 | *_p.c
23 | *.ilk
24 | *.meta
25 | *.obj
26 | *.pch
27 | *.pdb
28 | *.pgc
29 | *.pgd
30 | *.rsp
31 | *.sbr
32 | *.tlb
33 | *.tli
34 | *.tlh
35 | *.tmp
36 | *.log
37 | *.vspscc
38 | *.vssscc
39 | .builds
40 |
41 | # Visual C++ cache files
42 | ipch/
43 | *.aps
44 | *.ncb
45 | *.opensdf
46 | *.sdf
47 |
48 | # Visual Studio profiler
49 | *.psess
50 | *.vsp
51 | *.vspx
52 |
53 | # Guidance Automation Toolkit
54 | *.gpState
55 |
56 | # ReSharper is a .NET coding add-in
57 | _ReSharper*
58 |
59 | # NCrunch
60 | *.ncrunch*
61 | .*crunch*.local.xml
62 |
63 | # Installshield output folder
64 | [Ee]xpress
65 |
66 | # DocProject is a documentation generator add-in
67 | DocProject/buildhelp/
68 | DocProject/Help/*.HxT
69 | DocProject/Help/*.HxC
70 | DocProject/Help/*.hhc
71 | DocProject/Help/*.hhk
72 | DocProject/Help/*.hhp
73 | DocProject/Help/Html2
74 | DocProject/Help/html
75 |
76 | # Click-Once directory
77 | publish
78 |
79 | # Publish Web Output
80 | *.Publish.xml
81 |
82 | # NuGet Packages Directory
83 | packages
84 |
85 | # Windows Azure Build Output
86 | csx
87 | *.build.csdef
88 |
89 | # Windows Store app package directory
90 | AppPackages/
91 |
92 | # Others
93 | [Bb]in
94 | [Oo]bj
95 | sql
96 | [Tt]est[Rr]esult*
97 | *.Cache
98 | ClientBin
99 | [Ss]tyle[Cc]op.*
100 | ~$*
101 | *.dbmdl
102 | Generated_Code #added for RIA/Silverlight projects
103 |
104 | # Backup & report files from converting an old project file to a newer
105 | # Visual Studio version. Backup files are not needed, because we have git ;-)
106 | _UpgradeReport_Files/
107 | Backup*/
108 | UpgradeLog*.XML
109 |
110 | # ReSharper is a .NET coding add-in
111 | _ReSharper*/
112 | *.[Rr]e[Ss]harper
113 | *.DotSettings.user
114 |
115 | # JustCode is a .NET coding add-in
116 | .JustCode
117 |
118 | # TeamCity is a build add-in
119 | _TeamCity*
120 |
121 | # DotCover is a Code Coverage Tool
122 | *.dotCover
123 |
124 | # MightyMoose
125 | *.mm.*
126 | AutoTest.Net/
127 |
128 | # Web workbench (sass)
129 | .sass-cache/
130 |
131 | # Installshield output folder
132 | [Ee]xpress/
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | # TODO: Comment the next line if you want to checkin your web deploy settings
141 | # but database connection strings (with potential passwords) will be unencrypted
142 | *.pubxml
143 | *.publishproj
144 |
145 | # NuGet Packages
146 | *.nupkg
147 | # The packages folder can be ignored because of Package Restore
148 | **/packages/*
149 | # except build/, which is used as an MSBuild target.
150 | !**/packages/build/
151 | # Uncomment if necessary however generally it will be regenerated when needed
152 | #!**/packages/repositories.config
153 |
154 | # Visual Studio cache files
155 | # files ending in .cache can be ignored
156 | *.[Cc]ache
157 | # but keep track of directories ending in .cache
158 | !*.[Cc]ache/
159 |
160 | # Others
161 | ClientBin/
162 | *.dbproj.schemaview
163 | *.pfx
164 | *.publishsettings
165 | node_modules/
166 | orleans.codegen.cs
167 |
168 | # RIA/Silverlight projects
169 | Generated_Code/
170 |
171 | # SQL Server files
172 | *.mdf
173 | *.ldf
174 |
175 | # Business Intelligence projects
176 | *.rdl.data
177 | *.bim.layout
178 | *.bim_*.settings
179 |
180 | # Microsoft Fakes
181 | FakesAssemblies/
182 |
183 | # Node.js Tools for Visual Studio
184 | .ntvs_analysis.dat
185 |
186 | # Visual Studio 6 build log
187 | *.plg
188 |
189 | # Visual Studio 6 workspace options file
190 | *.opt
191 |
192 | # Visual Studio LightSwitch build output
193 | **/*.HTMLClient/GeneratedArtifacts
194 | **/*.DesktopClient/GeneratedArtifacts
195 | **/*.DesktopClient/ModelManifest.xml
196 | **/*.Server/GeneratedArtifacts
197 | **/*.Server/ModelManifest.xml
198 | _Pvt_Extensions
199 |
200 | !/CameraSDK/*
201 | !/CameraSDK2/*
202 | .idea/
203 | .vs/
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 邱尘
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 |
--------------------------------------------------------------------------------
/PRIVACY.md:
--------------------------------------------------------------------------------
1 | ### Privacy Policy
2 |
3 | Last updated: 2023-02-01
4 |
5 | This Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your information when You use the Service and tells You about Your privacy rights and how the law protects You.
6 | We use Your anonynous Non-Personal data and health and performance data of the Service to provide and improve the Service itself. By using the Service, You agree to the collection and use of information in accordance with this Privacy Policy.
7 |
8 | ### Interpretation and Definitions
9 |
10 | #### Interpretation
11 |
12 | The words of which the initial letter is capitalized have meanings defined under the following conditions.
13 | The following definitions shall have the same meaning regardless of whether they appear in singular or in plural.
14 |
15 | #### Definitions
16 |
17 | For the purposes of this Privacy Policy:
18 |
19 | + **You** means the individual accessing or using the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.
20 | + **Developer** (referred to as either "the Developer", "We", "Us" or "Our" in this Agreement) refers to DbToys's owner.
21 | + **Website** refers to DbToys's website, accessible from [github.com/neilq/DbToys](https://github.com/NeilQ/DbToys)
22 | + **Service** refers to the DbToys software.
23 | + **Service Provider** means any natural or legal person who processes the data on behalf of the Developer. It refers to third-party developer(s) or individuals contributor to facilitate the Service, to provide the Service on behalf of the Developer, to perform services related to the Service or to assist the Developer in analyzing how the Service is used.
24 | + **Personal Data** is any information that relates to an identified or identifiable individual.
25 | + **Non-Personal Data** is any information that does not relates to an identified or identifiable individual.
26 | + **Device** means any device that can access the Service such as a computer, a cellphone or a digital tablet.
27 | + **Usage Data** refers to data collected automatically, either generated by the use of the Service or from the Service infrastructure itself (for example, the duration that the Service takes to start).
28 |
29 | ### Collecting and Using Your Personal Data
30 |
31 | #### Types of Data Collected
32 |
33 | ##### Personal Data
34 |
35 | While using Our Service, We will never retain or ask You to provide Us any personally identifiable information.
36 |
37 | ##### Usage Data
38 |
39 | Usage Data is collected automatically when using the Service.
40 | Usage Data may include non-identifiable information such as error messages, performance metric, ordered list of features used during the use of the Service.
41 | Usage Data are not sent to the Developer and Service Provider.
42 | Usage Data are displayed in the "Logs" section in the Settings page of the Service.
43 |
44 | ### Links to Other Websites
45 |
46 | Our Service may contain links to other websites that are not operated by Us. If You click on a third party link, You will be directed to that third party's site. We strongly advise You to review the Privacy Policy of every site You visit.
47 |
48 | We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.
49 |
50 | ### Third-Party Services
51 |
52 | Our Service allow You to use a Third-Party service. We strongly advise You to review the Privacy Policy of every service You use.
53 |
54 | We have no control over and assume no responsibility for the content, privacy policies or practices of any third party services.
55 |
56 | ### Changes to this Privacy Policy
57 |
58 | We may update our Privacy Policy from time to time. We will notify You of any changes by posting the new Privacy Policy on this page.
59 | You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.
60 |
61 | ### Contact Us
62 |
63 | If you have any questions about this Privacy Policy, You can contact us:
64 |
65 | + By visiting this page on Github: [github.com/neilq/DbToys](https://github.com/NeilQ/DbToys)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
DbToys
4 |
5 |
6 | ## Introduction
7 |
8 | DbToys offers a set of utilities around database like view table design, exporting data dictionary, code generator.
9 |
10 | Supported databases:
11 | - Sql Server
12 | - Mysql
13 | - Postgresql
14 |
15 | ## Features
16 | ### OneClick To View Table
17 | Sometimes we just want to view the column definition and see the sample data by one click.
18 |
19 | - View table design
20 | - View Sample result data of table
21 | - Export data dictionary to excel
22 | - Code generation
23 |
24 | ### Export Database Documents
25 | - Export data dicionary to Excel
26 | - more to continue...
27 |
28 | ### Code Generation
29 | - Global templates
30 | - Customize your own code templates
31 | - Generate code files according the selected data table and the code templates
32 |
33 | ## Screenshots
34 |
35 | 
36 |
37 | 
38 |
39 | ## How to install
40 |
41 | ### Prerequisite
42 | - You need Windows 10 build 17763+ or later.
43 | - [Microsoft Edge WebView2 Runtime](https://go.microsoft.com/fwlink/p/?LinkId=2124703) should be installed.
44 |
45 | ### Via Microsoft Store
46 | [DbToys](https://apps.microsoft.com/store/detail/dbtoys/9NKCGCMR2W99)
47 |
48 | ### Via Release
49 | Go to [GitHub releases page](https://github.com/NeilQ/DbToys/releases), click on Assets at the bottom to show the files available in the release.
50 | **(No autoupdate)**
51 |
52 | ## Known issues
53 | - [Flash when using Multiple WebViews in Tab Controls](https://github.com/MicrosoftEdge/WebView2Feedback/issues/1412)
54 | - [Working with CoreWebView2 in MAUI Blazor (hybrid) in combination with Identity results in compile errors](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/3583)
55 | - [TreeView with DataTemplateSelector not reliably using selected DataTemplate](https://github.com/microsoft/microsoft-ui-xaml/issues/2121)
56 |
57 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Admin/edit-component.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_kebab_case | string.to_singular) + "-edit.component.ts" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | import {
5 | Component, Output, EventEmitter, ViewChild, Input, ViewEncapsulation, OnInit
6 | } from '@angular/core';
7 | import { NgForm } from '@angular/forms';
8 | import { NzModalRef } from "ng-zorro-antd/modal";
9 | import { NotificationsService, {{classname}}Service } from '@services';
10 | import { {{classname}}, ViewAction, ModalComponentBase } from '@models';
11 |
12 | @Component({
13 | selector: '{{classname | string.to_kebab_case}}-edit',
14 | templateUrl: '{{classname | string.to_kebab_case}}-edit.html',
15 | encapsulation: ViewEncapsulation.None
16 | })
17 | export class {{classname}}EditComponent extends ModalComponentBase implements OnInit {
18 |
19 | action: ViewAction;
20 | ViewAction = ViewAction;
21 |
22 | @Output() onSuccess: EventEmitter = new EventEmitter();
23 | @Input() companyId: number;
24 | @ViewChild('editForm') editForm: NgForm;
25 |
26 | submitted: boolean = false;
27 |
28 | entity: {{classname}} = new {{classname}}();
29 | currentId: number;
30 |
31 | constructor(
32 | private modal: NzModalRef,
33 | private apiService: {{classname}}Service,
34 | protected notifyService: NotificationsService) {
35 | super();
36 | }
37 |
38 | changeViewAction(selectedData: any, action: ViewAction) {
39 | this.submitted = false;
40 | this.action = action;
41 |
42 | switch (this.action) {
43 | default:
44 | case ViewAction.Add:
45 | this.entity.companyId = this.companyId;
46 | break;
47 | case ViewAction.Update:
48 | this.currentId = selectedData.id;
49 |
50 | this.apiService.get(this.currentId)
51 | .then(data => {
52 | this.entity = data;
53 | })
54 | .catch(err => {
55 | this.notifyService.error('Error', err);
56 | });
57 | break;
58 | }
59 | }
60 |
61 | save() {
62 | if (!this.editForm.valid) {
63 | return;
64 | }
65 | this.submitted = true;
66 |
67 | switch (this.action) {
68 | default:
69 | case ViewAction.Add:
70 | this.apiService.add(this.entity)
71 | .then(() => {
72 | this.onSuccess.emit(null);
73 | this.modal.destroy(true);
74 | })
75 | .catch((err) => {
76 | this.notifyService.error('Error', err);
77 | this.submitted = false;
78 | });
79 | break;
80 | case ViewAction.Update:
81 | this.apiService.update(this.entity.id, this.entity)
82 | .then(() => {
83 | this.onSuccess.emit(null);
84 | this.modal.destroy(true);
85 | })
86 | .catch((err) => {
87 | this.notifyService.error('Error', err);
88 | this.submitted = false;
89 | });
90 | break;
91 | }
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Admin/edit-html.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_kebab_case | string.to_singular) + "-edit.html" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~
5 | ignoredCols=["id","add_user","add_time","update_time","update_user","marked_for_delete","delete_time","delete_user"]
6 | ~}}
7 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Admin/list-component.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_kebab_case | string.to_singular) + ".component.ts" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | import { Component, ViewEncapsulation } from '@angular/core';
5 | import { CrudTableComponentBase, {{classname}}, IdNamePair } from '@models';
6 | import { AuthService, {{classname}}Service, NotificationsService } from '@services';
7 | import { NzModalService } from "ng-zorro-antd/modal";
8 | import { {{classname}}EditComponent } from "./edit/{{classname | string.to_kebab_case}}-edit.component";
9 |
10 | @Component({
11 | selector: '{{classname | string.to_kebab_case}}',
12 | templateUrl: '{{classname | string.to_kebab_case}}.component.html',
13 | encapsulation: ViewEncapsulation.None
14 | })
15 | export class {{classname}}Component extends CrudTableComponentBase<{{classname}}> {
16 |
17 | query = {
18 | companyId: null,
19 | };
20 |
21 | constructor(
22 | protected apiService: {{classname}}Service,
23 | protected notifyService: NotificationsService,
24 | protected modalService: NzModalService,
25 | protected authService: AuthService) {
26 | super(authService, notifyService, apiService, modalService);
27 | }
28 |
29 | ngOnInit(): void {
30 | super.ngOnInit();
31 | this.editTitle = "";
32 | //this.editModalWidth = 600;
33 | //this.deleteMessage = "";
34 | this.editComponent = {{classname}}EditComponent;
35 | this.editComponentParams = {companyId: this.companyId};
36 | }
37 |
38 | onCompanyChanged(company: IdNamePair) {
39 | super.onCompanyChanged(company);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Admin/list-html.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_kebab_case | string.to_singular) + ".component.html" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~
5 | # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction
6 | # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates
7 | # Press 'F1' to show editor commands
8 | ~}}
9 | {{~
10 | ignoredCols=["id","add_user","add_time","update_time","update_user","marked_for_delete","delete_time","delete_user"]
11 | ~}}
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
45 |
46 |
47 |
49 | {{~ for col in table.columns ~}}
50 | {{~ if !(ignoredCols | array.contains col.name) && !(col.name | string.ends_with "id") ~}}
51 | {{~ if col.description && col.description!="" ~}}
52 | {{ col.description }}
53 | {{~ else ~}}
54 | {{ col.name }}
55 | {{~ end ~}}
56 | {{~ end ~}}
57 | {{~ end ~}}
58 |
59 |
60 |
61 |
62 |
64 | {{~ for col in table.columns ~}}
65 | {{~ if !(ignoredCols | array.contains col.name) && !(col.name | string.ends_with "id") ~}}
66 | {%{{{}%}data.{{col.property_name | string.to_camel_case}}{%{}}}%}
67 | {{~ end ~}}
68 | {{~ end ~}}
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Admin/service.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_kebab_case | string.to_singular) + ".service.ts" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~ # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates ~}}
5 | {{~ # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction ~}}
6 | import { Injectable } from '@angular/core';
7 | import { {{ classname }} } from '@models';
8 | import { ApiService } from '../api.service';
9 | import { HttpClient } from '@angular/common/http';
10 |
11 | @Injectable({
12 | providedIn: 'root'
13 | })
14 | export class {{classname}}Service extends ApiService<{{classname}}> {
15 | constructor(private http: HttpClient) {
16 | super('/api/{{classname | string.to_plural | string.to_snake_case}}', http);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Admin/type.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_kebab_case | string.to_singular) + ".type.ts" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~ # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates ~}}
5 | {{~ # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction ~}}
6 | {{~
7 | ignoredCols=["add_user","add_time","update_time","update_user","marked_for_delete","delete_time","delete_user"]
8 | ~}}
9 |
10 | export class {{classname}} {
11 | {{~ for col in table.columns ~}}
12 | {{~ if !(ignoredCols | array.contains col.name) ~}}
13 | {{ col.property_name | string.to_camel_case }}: {{ col.db_type | get_js_property_type_of_pgsql }};
14 | {{~ end ~}}
15 | {{~ end ~}}
16 | }
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Api/controller.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_plural) + "Controller.cs" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~ # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates ~}}
5 | {{~ # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction ~}}
6 | using Microsoft.AspNetCore.Authorization;
7 | using Microsoft.AspNetCore.Mvc;
8 | using Acartons.Api.Controllers.Base;
9 | using Acartons.Domain.{{ classname | string.to_plural }};
10 |
11 | namespace Acartons.Api.Controllers;
12 |
13 | [Route("api/{{ classname | string.to_plural | string.to_snake_case }}")]
14 | [ApiExplorerSettings(GroupName = "")]
15 | [Authorize]
16 | public class {{classname | string.to_plural}}Controller :
17 | CrudControllerBase<{{classname}}, {{classname}}Dto, {{classname}}Query, {{classname}}Save>
18 | {
19 | public {{classname | string.to_plural}}Controller(I{{classname}}Service service, IControllerDependencies dependencies)
20 | : base(service, dependencies)
21 | {
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Api/dto.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular) + "Dto.cs" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~ # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates ~}}
5 | {{~ # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction ~}}
6 | {{~
7 | ignoredCols=["id","add_user","add_time","update_time","update_user","marked_for_delete","delete_time","delete_user"]
8 | ~}}
9 | namespace Acartons.Domain.{{ classname | string.to_plural }};
10 |
11 | public class {{ classname }}Save
12 | {
13 | {{~ for col in table.columns ~}}
14 | {{~ if !(ignoredCols | array.contains col.name) ~}}
15 | {{~ if col.description && col.description!="" ~}}
16 | ///
17 | /// {{col.description}}
18 | ///
19 | {{~ end ~}}
20 | public {{ col.db_type | get_property_type_of_pgsql }} {{ col.property_name | string.to_pascal_case }} { get; set; }
21 |
22 | {{~ end ~}}
23 | {{~ end ~}}
24 | }
25 |
26 | public class {{ classname }}Dto : {{ classname }}Save
27 | {
28 | public int Id { get; set; }
29 | }
30 |
31 | public class {{ classname }}Query
32 | {
33 | {{~ for col in table.columns ~}}
34 | {{~ if !(ignoredCols | array.contains col.name) && (col.name | string.ends_with "id") && col.name!="id" ~}}
35 | {{~ if col.description && col.description!="" ~}}
36 | ///
37 | /// {{col.description}}
38 | ///
39 | {{~ end ~}}
40 | public {{ col.db_type | get_property_type_of_pgsql }}? {{ col.property_name | string.to_pascal_case }} { get; set; }
41 |
42 | {{~ end ~}}
43 | {{~ end ~}}
44 | }
45 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Api/model.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular) + ".cs" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~ # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates ~}}
5 | {{~ # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction ~}}
6 | {{~
7 | cols= table.columns | array.map "name"
8 | ignoredCols=["id","add_user","add_time","update_time","update_user","marked_for_delete","delete_time","delete_user"]
9 | hasDeleteFields= (cols | array.contains "delete_user") && (cols | array.contains "delete_time")
10 | hasUpdateFields= (cols | array.contains "update_user") && (cols | array.contains "update_time")
11 | hasAddFields= (cols | array.contains "add_user") && (cols | array.contains "add_time")
12 |
13 | func get_base_type()
14 | if hasDeleteFields && hasAddFields && hasUpdateFields && hasAddFields
15 | ret "FullAuditedEntityBase"
16 | end
17 | if hasAddFields && hasUpdateFields
18 | ret "AuditedEntityBase"
19 | end
20 | if hasAddFields
21 | ret "CreateAuditedEntityBase"
22 | end
23 | end
24 | ~}}
25 | using System.ComponentModel.DataAnnotations.Schema;
26 | using Acartons.Core.Entities;
27 |
28 | namespace Acartons.Domain.{{ classname | string.to_plural }};
29 |
30 | [Table("{{ table.clean_name }}")]
31 | public class {{ classname }} : {{get_base_type}}
32 | {
33 | {{~ for col in table.columns ~}}
34 | {{~ if !(ignoredCols | array.contains col.name) ~}}
35 | {{~ if col.description && col.description!="" ~}}
36 | ///
37 | /// {{col.description}}
38 | ///
39 | {{~ end ~}}
40 | public {{ col.db_type | get_property_type_of_pgsql }} {{ col.property_name | string.to_pascal_case }} { get; set; }
41 |
42 | {{~ end ~}}
43 | {{~ end ~}}
44 | }
45 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Api/repository.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular) + "Repo.cs" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~ # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates ~}}
5 | {{~ # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction ~}}
6 | using System.Linq;
7 | using Acartons.Core.EfCore;
8 | using Acartons.Domain.EfCore;
9 |
10 | namespace Acartons.Domain.{{ classname | string.to_plural }};
11 |
12 | public interface I{{ classname }}Repo : IEfCoreRepository<{{classname}}>
13 | {
14 | }
15 |
16 | public class {{classname}}Repo : EfCoreRepositoryBase<{{classname}}>, I{{classname}}Repo
17 | {
18 | public {{classname}}Repo(AcartonsDbContext dbContext) : base(dbContext) { }
19 |
20 | protected override IQueryable<{{classname}}> CreateFilteredQuery(object condition)
21 | {
22 | var query = base.CreateFilteredQuery(condition);
23 | if (condition is not {{classname}}Query req) return query;
24 | //query = query.Where(CreateCompanyIdFilter(req.CompanyId));
25 | return query;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/SampleTemplates/Acartons Api/service.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular) + "Service.cs" ~}}
3 | {{~ classname = table.clean_name | regex.replace "^[a-zA-Z0-9]+_" "" | string.to_pascal_case | string.to_singular ~}}
4 | {{~ # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates ~}}
5 | {{~ # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction ~}}
6 | using Acartons.Core.Services;
7 |
8 | namespace Acartons.Domain.{{ classname | string.to_plural }};
9 |
10 | public interface I{{ classname }}Service : ICrudService<{{classname}}, {{classname}}Dto, {{classname}}Save>
11 | {
12 | }
13 |
14 | public class {{classname}}Service : UowCrudServiceBase<{{classname}}, {{classname}}Dto, {{classname}}Save>, I{{classname}}Service
15 | {
16 | public {{classname}}Service(I{{classname}}Repo repository, IUowServiceDependencies dependencies):
17 | base(repository, dependencies)
18 | {
19 | }
20 | }
--------------------------------------------------------------------------------
/SampleTemplates/Netcool Api/controller.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | string.to_pascal_case | string.to_plural) + "Controller.cs" ~}}
3 | {{~ classname = table.clean_name | string.to_pascal_case | string.to_singular ~}}
4 | using Microsoft.AspNetCore.Authorization;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Netcool.Api.Domain.{{ classname }};
7 | using Netcool.Core.AspNetCore.Controllers;
8 |
9 | namespace Netcool.Api.Controllers
10 |
11 | [Route("{{ table.clean_name | string.to_plural | string.to_kebab_case }}")]
12 | [Authorize]
13 | public class {{classname | string.to_plural}}Controller :
14 | CrudControllerBase<{{classname}}Dto, int, {{classname}}Request, {{classname}}SaveInput>
15 | {
16 | private new readonly I{{classname}}Service Service;
17 |
18 | public {{classname | string.to_plural}}Controller(I{{classname}}Service service) : base(service)
19 | {
20 | Service = service;
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/SampleTemplates/Netcool Api/dto.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | string.to_pascal_case | string.to_singular) + "Dto.cs" ~}}
3 | {{~ classname = table.clean_name | string.to_pascal_case | string.to_singular ~}}
4 | {{~ func get_property_type_of_pgsql(db_type)
5 | case db_type
6 | when "int","int2","int8"
7 | ret "int"
8 | when "bytea"
9 | ret "byte[]"
10 | when "float4"
11 | ret "float"
12 | when "float8"
13 | ret "double"
14 | when "money","numeric"
15 | ret "decimal"
16 | when "bool","boolean"
17 | ret "bool"
18 | when "time","timetz","timestamp","timestamptz","date"
19 | ret "DateTime"
20 | else
21 | ret "string"
22 | end
23 | end ~}}
24 | {{~ func get_property_type_of_mysql(db_type)
25 | case db_type
26 | when "int","bigint","smallint"
27 | ret "int"
28 | when "image","binary","blob","mediumblob","longblob","varbinary"
29 | ret "byte[]"
30 | when "float"
31 | ret "float"
32 | when "double"
33 | ret "double"
34 | when "money","smallmoney","numeric","decimal"
35 | ret "decimal"
36 | when "bit","bool","boolean"
37 | ret "bool"
38 | when "guid"
39 | ret "Guid"
40 | when "smalldatetime","timestamp","datetime","date"
41 | ret "DateTime"
42 | else
43 | ret "string"
44 | end
45 | end ~}}
46 | {{~ func get_property_type_of_sql_server(db_type)
47 | case db_type
48 | when "int","bigint","smallint"
49 | ret "int"
50 | when "image","binary","timestamp","varbinary"
51 | ret "byte[]"
52 | when "real"
53 | ret "float"
54 | when "float","double"
55 | ret "double"
56 | when "money","smallmoney","numeric","decimal"
57 | ret "decimal"
58 | when "tinyint"
59 | ret "byte"
60 | when "bit"
61 | ret "bool"
62 | when "uniqueidentifier"
63 | ret "Guid"
64 | when "smalldatetime","datetime","datetime2","date","time"
65 | ret "DateTime"
66 | when "datetimeoffset"
67 | ret "DateTimeOffset"
68 | when "geography"
69 | ret "Microsoft.SqlServer.Types.SqlGeography"
70 | when "geometry"
71 | ret "Microsoft.SqlServer.Types.SqlGeometry"
72 | else
73 | ret "string"
74 | end
75 | end ~}}
76 | {{~ ignoredCols=["id","create_time","create_user_id","update_time","update_user_id","is_deleted","delete_time","delete_user_id"] ~}}
77 | using System;
78 | using Netcool.Core.Services.Dto;
79 |
80 | namespace Netcool.Api.Domain.{{ classname }}
81 |
82 |
83 | public class {{ classname }}SaveInput : EntityDto
84 | {
85 | {{~ for col in table.columns ~}}
86 | {{~ if col.description && col.description!="" ~}}
87 | ///
88 | /// {{col.description}}
89 | ///
90 | {{~ end ~}}
91 | {{~ if !(ignoredCols | array.contains col.name) ~}}
92 | public {{ col.db_type | get_property_type_of_pgsql }} {{ col.property_name | string.to_pascal_case }} { get; set; }
93 |
94 | {{~ end ~}}
95 | {{~ end ~}}
96 | }
97 |
98 | public class {{ classname }}Dto : {{ classname }}SaveInput
99 | {
100 |
101 | }
102 |
103 | public class {{ classname }}Query : PageRequest
104 | {
105 |
106 | }
107 |
108 |
--------------------------------------------------------------------------------
/SampleTemplates/Netcool Api/service.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Required: Defines the output filename here. ~}}
2 | {{~ filename = (table.clean_name | string.to_pascal_case | string.to_singular) + "Service.cs" ~}}
3 | {{~ classname = table.clean_name | string.to_pascal_case | string.to_singular ~}}
4 | using Netcool.Core.Entities;
5 | using Netcool.Core.Repositories;
6 | using Netcool.Core.Services;
7 |
8 | namespace Netcool.Api.Domain.{{classname}}
9 |
10 | public interface I{{classname}}Service : ICrudService<{{classname}}Dto, int, {{classname}}Request>
11 | {
12 |
13 | }
14 |
15 | public class {{ classname }}Service :
16 | CrudService<{{classname}}, {{classname}}Dto, int, {{classname}}Query>,
17 | I{{classname}}Service
18 | {
19 | public {{classname}}Service(IRepository<{{classname}}> repository, IServiceAggregator serviceAggregator) :
20 | base(repository, serviceAggregator)
21 | {
22 | GetPermissionName = "{{ table.clean_name | string.to_kebab_case }}.view";
23 | UpdatePermissionName = "{{ table.clean_name | string.to_kebab_case }}.update";
24 | CreatePermissionName = "{{ table.clean_name | string.to_kebab_case }}.create";
25 | DeletePermissionName = "{{ table.clean_name | string.to_kebab_case }}.delete";
26 | }
27 |
28 | protected override IQueryable<{{classname}}> CreateFilteredQuery({{classname}}Query input)
29 | {
30 | var query = Repository.GetAll();
31 | //query = query.Where(t => t.id == input.id);
32 | return query;
33 | }
34 | }
--------------------------------------------------------------------------------
/images/screen1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/images/screen1.png
--------------------------------------------------------------------------------
/images/screen2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/images/screen2.png
--------------------------------------------------------------------------------
/images/screen3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/images/screen3.png
--------------------------------------------------------------------------------
/images/screen5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/images/screen5.png
--------------------------------------------------------------------------------
/src/.vsconfig:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0",
3 | "components": [
4 | "Microsoft.Component.MSBuild",
5 | "Microsoft.NetCore.Component.Runtime.6.0",
6 | "Microsoft.NetCore.Component.SDK",
7 | "Microsoft.VisualStudio.Component.ManagedDesktop.Core",
8 | "Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites",
9 | "Microsoft.VisualStudio.Component.NuGet",
10 | "Microsoft.VisualStudio.Component.Windows10SDK.19041",
11 | "Microsoft.VisualStudio.Component.Windows10SDK",
12 | "Microsoft.VisualStudio.ComponentGroup.MSIX.Packaging",
13 | "Microsoft.VisualStudio.ComponentGroup.WindowsAppSDK.Cs",
14 | "Microsoft.VisualStudio.Workload.ManagedDesktop"
15 | ]
16 | }
--------------------------------------------------------------------------------
/src/Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | 0.4.0
4 | 邱尘
5 | DbToys
6 | https://github.com/NeilQ/DbToys/
7 | GitHub
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/DbToys.Core/Constants.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace DbToys.Core;
3 |
4 | public static class Constants
5 | {
6 | public static class LocalSettings
7 | {
8 | public const string DatabaseHistorySettingsFileName = "database.json";
9 |
10 | public const string GeneralSettingsFileName = "settings.json";
11 |
12 | public const string UiSettingsFileName = "ui.json";
13 | }
14 |
15 | public static class Notification
16 | {
17 | public const int ShortDuration = 3000;
18 | public const int DefaultDuration = 5000;
19 | }
20 |
21 | public static class FileSystem
22 | {
23 | public const string CachedEmptyItemName = "fileicon_cache";
24 | public const string DefaultApplicationDataFolderPath = "Netcool\\DbToys";
25 | public const string DefaultCodeTemplateFolderPath = "DbToys\\CodeTemplates";
26 | public const string CodeTemplateFileExtension = ".tpl";
27 | }
28 |
29 | public static class CodeTemplate
30 | {
31 | public const string InitialTemplateText = @"{{~ # Required: Defines the output filename here. ~}}
32 | {{~ filename = (table.clean_name | string.to_pascal_case | string.to_singular) + "".cs"" ~}}
33 | {{~ classname = table.clean_name | string.to_pascal_case | string.to_singular ~}}
34 | {{~
35 | # How to write template: https://github.com/NeilQ/DbToys/wiki/Code-template-instruction
36 | # Samples link: https://github.com/NeilQ/DbToys/blob/master/SampleTemplates
37 | # Press 'F1' to show editor commands
38 | ~}}
39 | ";
40 |
41 | public const string DefaultGlobalTemplateFolderName = "$Global";
42 | }
43 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/Database/DataBaseType.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Core.Database;
2 |
3 | public enum DatabaseType
4 | {
5 | SqlServer,
6 | Mysql,
7 | PostgreSql
8 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/Database/SchemaReader.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace DbToys.Core.Database;
5 |
6 | public interface ISchemaReader
7 | {
8 | string GetServerName();
9 |
10 | string Escape(string text);
11 |
12 | List ReadDatabases();
13 |
14 | List ReadTables(string database);
15 |
16 | List ReadColumns(string database, string schema, string table);
17 |
18 | DataTable GetResultSet(Table table, int limit, string sort);
19 | }
20 |
21 | public abstract class SchemaReader : ISchemaReader
22 | {
23 | static readonly Regex RxCleanUp = new Regex(@"[^\w\d_]", RegexOptions.Compiled);
24 |
25 | static readonly string[] CsKeywords =
26 | {
27 | "abstract", "event", "new", "struct", "as", "explicit", "null",
28 | "switch", "base", "extern", "object", "this", "bool", "false", "operator", "throw",
29 | "break", "finally", "out", "true", "byte", "fixed", "override", "try", "case", "float",
30 | "params", "typeof", "catch", "for", "private", "uint", "char", "foreach", "protected",
31 | "ulong", "checked", "goto", "public", "unchecked", "class", "if", "readonly", "unsafe",
32 | "const", "implicit", "ref", "ushort", "continue", "in", "return", "using", "decimal",
33 | "int", "sbyte", "virtual", "default", "interface", "sealed", "volatile", "delegate",
34 | "internal", "short", "void", "do", "is", "sizeof", "while", "double", "lock",
35 | "stackalloc", "else", "long", "static", "enum", "namespace", "string"
36 | };
37 |
38 | public abstract string GetServerName();
39 |
40 | public abstract string Escape(string text);
41 |
42 | public abstract List ReadDatabases();
43 |
44 | public abstract List ReadColumns(string database, string schema, string table);
45 |
46 | public abstract List ReadTables(string database);
47 |
48 | public abstract DataTable GetResultSet(Table table, int limit, string sort);
49 |
50 | ///
51 | /// Convert value to Pascal case.
52 | ///
53 | ///
54 | ///
55 | protected static string ToPascalCase(string value)
56 | {
57 | // If there are 0 or 1 characters, just return the string.
58 | if (value == null) return null;
59 | if (value.Length < 2) return value.ToUpper();
60 |
61 | // Split the string into words.
62 | var words = value.Split(
63 | new[] { '_' },
64 | StringSplitOptions.RemoveEmptyEntries);
65 |
66 | // Combine the words.
67 | var result = "";
68 | foreach (var word in words)
69 | {
70 | result +=
71 | word.Substring(0, 1).ToUpper() +
72 | word.Substring(1);
73 | }
74 |
75 | return result;
76 | }
77 |
78 | protected static Func CleanUp = (str) =>
79 | {
80 | str = RxCleanUp.Replace(str, "_");
81 |
82 | if (char.IsDigit(str[0]) || CsKeywords.Contains(str))
83 | str = "@" + str;
84 |
85 | return str;
86 | };
87 |
88 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/Database/Table.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Core.Database;
2 |
3 | public class Table
4 | {
5 | public List Columns { get; set; }
6 | public string Name { get; set; }
7 | public string Schema { get; set; }
8 | public bool IsView { get; set; }
9 | public string CleanName { get; set; }
10 | public string ClassName { get; set; }
11 | public string Database { get; set; }
12 | public string Description { get; set; }
13 |
14 | public string DisplayName { get; set; }
15 |
16 | public Column Pk
17 | {
18 | get { return Columns?.FirstOrDefault(x => x.IsPk); }
19 | }
20 |
21 | public override string ToString()
22 | {
23 | return (Schema ?? "default") + "." + Name;
24 | }
25 | }
26 |
27 | public class Column
28 | {
29 | public string Name { get; set; }
30 | public string PropertyName { get; set; }
31 | public string PropertyType { get; set; }
32 | public bool IsPk { get; set; }
33 | public bool IsNullable { get; set; }
34 | public bool IsAutoIncrement { get; set; }
35 | public string DbType { get; set; }
36 | public int? Length { get; set; }
37 | public string Description { get; set; }
38 | public string DefaultValue { get; set; }
39 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/DbToys.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 | enable
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/DbToys.Core/Excel/ExcelStyleOptions.cs:
--------------------------------------------------------------------------------
1 | using ClosedXML.Excel;
2 |
3 | namespace DbToys.Core.Excel;
4 |
5 | public class ExcelStyleOptions
6 | {
7 | public static readonly ExcelStyleOptions Default = new();
8 |
9 | public string FontFamily { get; set; } = "Microsoft YaHei";
10 |
11 | public double ValueFontSize { get; set; } = 11;
12 |
13 | public double TitleFontSize { get; set; } = 16;
14 | public XLAlignmentHorizontalValues TitleHorizontalAlignment { get; set; } = XLAlignmentHorizontalValues.Left;
15 | public XLColor TitleFontColor { get; set; } = XLColor.Black;
16 | public XLColor TitleBackgroundColor { get; set; } = XLColor.White;
17 |
18 | public double HeaderFontSize { get; set; } = 12;
19 | public XLColor HeaderFontColor { get; set; } = XLColor.White;
20 | public XLColor HeaderBackgroundColor { get; set; } = XLColor.FromArgb(64, 64, 64);
21 | public XLAlignmentHorizontalValues HeaderHorizontalAlignment { get; set; } = XLAlignmentHorizontalValues.Left;
22 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/Excel/IExcelService.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Core.Database;
2 |
3 | namespace DbToys.Core.Excel;
4 |
5 | public interface IExcelService
6 | {
7 | public void GenerateDatabaseDictionary(IList tableList, string fileName);
8 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/ICodeGenerator.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Core.Database;
2 | using DbToys.Core.Scriban;
3 | using Scriban;
4 | using Scriban.Runtime;
5 | using Scriban.Syntax;
6 |
7 | namespace DbToys.Core;
8 |
9 | public class CodeGenerateResult
10 | {
11 | public string Filename;
12 |
13 | public string Codes;
14 |
15 | public CodeGenerateResult(string filename, string codes)
16 | {
17 | Filename = filename;
18 | Codes = codes;
19 | }
20 | }
21 |
22 | public interface ICodeGenerator
23 | {
24 | public CodeGenerateResult GenerateFromTable(Table table, string templateText);
25 |
26 | }
27 |
28 | public class CodeGenerator : ICodeGenerator
29 | {
30 | public CodeGenerateResult GenerateFromTable(Table table, string templateText)
31 | {
32 | var scriptVisitor = new CodeGeneratorScriptVisitor();
33 | var scriptObject = new ScriptObject { { "table", table } };
34 | //scriptObject.Import(new CustomScribanStringFunctions());
35 | var context = new TemplateContext();
36 | context.PushGlobal(scriptObject);
37 |
38 | //context.BuiltinObject["string"] = new CustomScribanStringFunctions();
39 | var thing = (ScriptObject)context.BuiltinObject["string"];
40 | thing.Import(new CustomScribanStringFunctions());
41 |
42 | var template = Template.Parse(templateText);
43 | template.Page.Accept(scriptVisitor);
44 | var output = template.Render(context);
45 |
46 | string filename = null;
47 | if (scriptVisitor.Variables.TryGetValue("filename", out var variable))
48 | {
49 | filename = (string)variable.GetValue(context);
50 | }
51 |
52 | return new CodeGenerateResult(filename, output);
53 | }
54 | }
55 |
56 | public class CodeGeneratorScriptVisitor : ScriptVisitor
57 | {
58 | public Dictionary Variables { get; } = new();
59 |
60 | public override void Visit(ScriptVariableGlobal node)
61 | {
62 | Variables.TryAdd(node.Name, node);
63 | base.Visit(node);
64 | }
65 |
66 | public override void Visit(ScriptVariableLocal node)
67 | {
68 | Variables.TryAdd(node.Name, node);
69 | base.Visit(node);
70 | }
71 |
72 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/Log/Logger.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Threading.Channels;
3 | using Serilog;
4 | using Serilog.Core;
5 | using Serilog.Events;
6 | using Serilog.Formatting;
7 | using Serilog.Formatting.Display;
8 |
9 | namespace DbToys.Core.Log;
10 |
11 | public static class Logger
12 | {
13 | public static readonly string ApplicationLogPath =
14 | Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
15 | Constants.FileSystem.DefaultApplicationDataFolderPath, "Logs");
16 | // private static readonly LogEventSink Sink = new();
17 |
18 | static Logger()
19 | {
20 | var logFilePath = Path.Combine(ApplicationLogPath, ".md");
21 | Serilog.Log.Logger = new LoggerConfiguration()
22 | .MinimumLevel.Information()
23 | .WriteTo.Debug()
24 | //.WriteTo.Sink(Sink)
25 | .WriteTo.File(new MarkdownFormatter(), logFilePath,
26 | rollingInterval: RollingInterval.Day,
27 | retainedFileCountLimit:3,
28 | rollOnFileSizeLimit: true)
29 | .CreateLogger();
30 | }
31 |
32 | public static void Information(string message)
33 | {
34 | Serilog.Log.Logger.Information(message);
35 | }
36 |
37 | public static void Error(string message)
38 | {
39 | Serilog.Log.Logger.Error(message);
40 | }
41 |
42 | public static void Error(string message, Exception e)
43 | {
44 | Serilog.Log.Logger.Error(e, message);
45 | }
46 |
47 | public static void Debug(string message)
48 | {
49 | Serilog.Log.Logger.Debug(message);
50 | }
51 |
52 | public static void Debug(string message, Exception e)
53 | {
54 | Serilog.Log.Logger.Debug(e, message);
55 | }
56 |
57 | public static void Warning(string message)
58 | {
59 | Serilog.Log.Logger.Warning(message);
60 | }
61 | }
62 |
63 | class MarkdownFormatter : ITextFormatter
64 | {
65 | public void Format(LogEvent logEvent, TextWriter output)
66 | {
67 | output.Write($"**{logEvent.Timestamp.ToLocalTime().ToString($"yyyy-MM-dd HH:mm:ss.fff zzz")}** ");
68 | if (logEvent.Level == LogEventLevel.Error || logEvent.Level == LogEventLevel.Fatal)
69 | {
70 | output.Write($"***[{logEvent.Level}]*** ");
71 | }
72 | else
73 | {
74 | output.Write($"**[{logEvent.Level}]** ");
75 | }
76 | output.WriteLine($"{logEvent.RenderMessage()} ");
77 | if (logEvent.Exception != null)
78 | {
79 | output.WriteLine($"{logEvent.Exception} ");
80 | }
81 | output.Flush();
82 | }
83 | }
84 |
85 | class LogEventSink : ILogEventSink
86 | {
87 | readonly ITextFormatter _textFormatter;
88 |
89 | public readonly Channel Queue = Channel.CreateUnbounded();
90 |
91 | public LogEventSink()
92 | {
93 | _textFormatter = new MessageTemplateTextFormatter(DefaultOutputTemplate);
94 | }
95 |
96 | const string DefaultOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}";
97 |
98 | public void Emit(LogEvent logEvent)
99 | {
100 | var message = logEvent.RenderMessage(new DateTimeFormatInfo());
101 | var sr = new StringWriter();
102 | _textFormatter.Format(logEvent, sr);
103 | Queue.Writer.TryWrite(sr + Environment.NewLine);
104 | }
105 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/NameValue.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Core;
2 |
3 | ///
4 | /// Can be used to store Name/Value (or Key/Value) pairs.
5 | ///
6 | public class NameValue : NameValue
7 | {
8 | ///
9 | /// Creates a new .
10 | ///
11 | public NameValue()
12 | {
13 |
14 | }
15 |
16 | ///
17 | /// Creates a new .
18 | ///
19 | public NameValue(string name, string value)
20 | {
21 | Name = name;
22 | Value = value;
23 | }
24 | }
25 |
26 | ///
27 | /// Can be used to store Name/Value (or Key/Value) pairs.
28 | ///
29 | public class NameValue
30 | {
31 | ///
32 | /// Name.
33 | ///
34 | public string Name { get; set; }
35 |
36 | ///
37 | /// Value.
38 | ///
39 | public T Value { get; set; }
40 |
41 | ///
42 | /// Creates a new .
43 | ///
44 | public NameValue()
45 | {
46 |
47 | }
48 |
49 | ///
50 | /// Creates a new .
51 | ///
52 | public NameValue(string name, T value)
53 | {
54 | Name = name;
55 | Value = value;
56 | }
57 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/Scriban/CustomScribanStringFunctions.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using DbToys.Core.Database;
3 | using Scriban.Functions;
4 |
5 | namespace DbToys.Core.Scriban;
6 |
7 | public class CustomScribanStringFunctions : StringFunctions
8 | {
9 | public static string ToSingular(string text)
10 | {
11 | return Inflector.MakeSingular(text);
12 | }
13 |
14 | public static string ToPlural(string text)
15 | {
16 | return Inflector.MakePlural(text);
17 | }
18 |
19 | public static string ToCamelCase(string text)
20 | {
21 | if (string.IsNullOrWhiteSpace(text)) return string.Empty;
22 | if (text.Length < 2) return text.ToLowerInvariant();
23 | var sb = new StringBuilder();
24 | var chars = text.AsSpan();
25 |
26 | sb.Append(char.ToLowerInvariant(chars[0]));
27 | var newWords = false;
28 | for (var i = 1; i < chars.Length; ++i)
29 | {
30 | var c = chars[i];
31 | if (c is '_' or '-' or ' ')
32 | {
33 | newWords = true;
34 | continue;
35 | }
36 |
37 | if (newWords && char.IsAsciiLetter(c))
38 | {
39 | sb.Append(char.ToUpperInvariant(c));
40 | newWords = false;
41 | continue;
42 | }
43 |
44 | sb.Append(c);
45 | }
46 | return sb.ToString();
47 | }
48 |
49 | public static string ToPascalCase(string text)
50 | {
51 | if (string.IsNullOrWhiteSpace(text)) return string.Empty;
52 | if (text.Length < 2) return text.ToUpperInvariant();
53 | var sb = new StringBuilder();
54 | var chars = text.AsSpan();
55 |
56 | sb.Append(char.ToUpperInvariant(chars[0]));
57 | var newWords = false;
58 | for (var i = 1; i < chars.Length; ++i)
59 | {
60 | var c = chars[i];
61 | if (c is '_' or '-' or ' ')
62 | {
63 | newWords = true;
64 | continue;
65 | }
66 |
67 | if (newWords && char.IsAsciiLetter(c))
68 | {
69 | sb.Append(char.ToUpperInvariant(c));
70 | newWords = false;
71 | continue;
72 | }
73 |
74 | sb.Append(c);
75 | }
76 | return sb.ToString();
77 | }
78 |
79 | public static string ToSnakeCase(string text)
80 | {
81 | return JoinWords(text, '_');
82 | }
83 |
84 | public static string ToKebabCase(string text)
85 | {
86 | return JoinWords(text, '-');
87 | }
88 |
89 | public static string JoinWords(string text, char splitter)
90 | {
91 | if (string.IsNullOrWhiteSpace(text)) return string.Empty;
92 | if (text.Length < 2) return text;
93 | var sb = new StringBuilder();
94 | var chars = text.AsSpan();
95 |
96 | var newWords = false;
97 | sb.Append(char.ToLowerInvariant(chars[0]));
98 | for (var i = 1; i < chars.Length; ++i)
99 | {
100 | var c = chars[i];
101 |
102 | if (c is '_' or '-' or ' ')
103 | {
104 | newWords = true;
105 | continue;
106 | }
107 |
108 | if (newWords && char.IsAsciiLetter(c))
109 | {
110 | sb.Append(splitter);
111 | sb.Append(char.ToLowerInvariant(c));
112 | newWords = false;
113 | continue;
114 | }
115 |
116 | if (char.IsUpper(c))
117 | {
118 | sb.Append(splitter);
119 | sb.Append(char.ToLowerInvariant(c));
120 | }
121 | else
122 | {
123 | sb.Append(c);
124 | }
125 | }
126 | return sb.ToString();
127 | }
128 | }
--------------------------------------------------------------------------------
/src/DbToys.Core/WorkshopContext.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace DbToys.Core;
3 |
4 | public static class WorkshopContext
5 | {
6 |
7 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Activation/ActivationHandler.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Activation;
2 |
3 | // Extend this class to implement new ActivationHandlers. See DefaultActivationHandler for an example.
4 | // https://github.com/microsoft/TemplateStudio/blob/main/docs/WinUI/activation.md
5 | public abstract class ActivationHandler : IActivationHandler
6 | where T : class
7 | {
8 | // Override this method to add the logic for whether to handle the activation.
9 | protected virtual bool CanHandleInternal(T args) => true;
10 |
11 | // Override this method to add the logic for your activation handler.
12 | protected abstract Task HandleInternalAsync(T args);
13 |
14 | public bool CanHandle(object args) => args is T && CanHandleInternal((args as T)!);
15 |
16 | public async Task HandleAsync(object args) => await HandleInternalAsync((args as T)!);
17 | }
18 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Activation/DefaultActivationHandler.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Services;
2 | using DbToys.ViewModels;
3 | using Microsoft.UI.Xaml;
4 |
5 | namespace DbToys.Activation;
6 |
7 | public class DefaultActivationHandler : ActivationHandler
8 | {
9 | private readonly INavigationService _navigationService;
10 |
11 | public DefaultActivationHandler(INavigationService navigationService)
12 | {
13 | _navigationService = navigationService;
14 | }
15 |
16 | protected override bool CanHandleInternal(LaunchActivatedEventArgs args)
17 | {
18 | // None of the ActivationHandlers has handled the activation.
19 | return _navigationService.Frame?.Content == null;
20 | }
21 |
22 | protected async override Task HandleInternalAsync(LaunchActivatedEventArgs args)
23 | {
24 | _navigationService.NavigateTo(typeof(DatabaseViewModel).FullName!, args.Arguments);
25 |
26 | await Task.CompletedTask;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Activation/IActivationHandler.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Activation;
2 |
3 | public interface IActivationHandler
4 | {
5 | bool CanHandle(object args);
6 |
7 | Task HandleAsync(object args);
8 | }
9 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/add_file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/add_file.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/add_folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/add_folder.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/broken_link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/broken_link.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/chain_start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/chain_start.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/code_file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/code_file.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/connected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/connected.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/database.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/database.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/database_server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/database_server.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/document.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/flash_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/flash_on.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/github.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/microsoft_excel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/microsoft_excel.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/microsoft_sql_server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/microsoft_sql_server.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/mysql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/mysql.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/opened_folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/opened_folder.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/paint_palette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/paint_palette.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/postgresql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/postgresql.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/refresh.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/remove.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/rename.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/rename.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/sms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/sms.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/source_code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/source_code.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Icons/table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Icons/table.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Monaco/vs/base/browser/ui/codicons/codicon/codicon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Monaco/vs/base/browser/ui/codicons/codicon/codicon.ttf
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Monaco/vs/base/common/worker/simpleWorker.nls.js:
--------------------------------------------------------------------------------
1 | /*!-----------------------------------------------------------
2 | * Copyright (c) Microsoft Corporation. All rights reserved.
3 | * Version: 0.34.1(0316a754aa4c25208bef91937efbce2ab1e3ce37)
4 | * Released under the MIT license
5 | * https://github.com/microsoft/vscode/blob/main/LICENSE.txt
6 | *-----------------------------------------------------------*/define("vs/base/common/worker/simpleWorker.nls",{"vs/base/common/platform":["_"]});
7 |
8 | //# sourceMappingURL=../../../../../min-maps/vs/base/common/worker/simpleWorker.nls.js.map
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/SplashScreen.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/SplashScreen.scale-400.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square150x150Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square150x150Logo.scale-400.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square310x310Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square310x310Logo.scale-200.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square310x310Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square310x310Logo.scale-400.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.scale-150.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.scale-400.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-20_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-20_altform-unplated.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-256_altform-lightunplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-256_altform-lightunplated.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-256_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-256_altform-unplated.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-32_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-32_altform-unplated.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-48_altform-lightunplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-48_altform-lightunplated.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-48_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Square44x44Logo.targetsize-48_altform-unplated.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/StoreLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/StoreLogo.scale-200.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/StoreLogo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/StoreLogo.scale-400.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/WindowIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeilQ/DbToys/59a799a6fa2dd3462f07da133ff26a8da1dadc96/src/DbToys.WinUI/Assets/WindowIcon.ico
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Assets/global.tpl:
--------------------------------------------------------------------------------
1 | {{~ # Global templates will be appended to all the other templates, you can define global functions or variables in the files under the global folder. ~}}
2 |
3 | {{~ func get_property_type_of_pgsql(db_type)
4 | case db_type
5 | when "int","int2","int4","int8"
6 | ret "int"
7 | when "bytea"
8 | ret "byte[]"
9 | when "float4"
10 | ret "float"
11 | when "float8"
12 | ret "double"
13 | when "money","numeric"
14 | ret "decimal"
15 | when "bool","boolean"
16 | ret "bool"
17 | when "time","timetz","timestamp","timestamptz","date"
18 | ret "DateTime"
19 | else
20 | ret "string"
21 | end
22 | end ~}}
23 |
24 | {{~ func get_property_type_of_mysql(db_type)
25 | case db_type
26 | when "int","bigint","smallint"
27 | ret "int"
28 | when "image","binary","blob","mediumblob","longblob","varbinary"
29 | ret "byte[]"
30 | when "float"
31 | ret "float"
32 | when "double"
33 | ret "double"
34 | when "money","smallmoney","numeric","decimal"
35 | ret "decimal"
36 | when "bit","bool","boolean"
37 | ret "bool"
38 | when "guid"
39 | ret "Guid"
40 | when "smalldatetime","timestamp","datetime","date"
41 | ret "DateTime"
42 | else
43 | ret "string"
44 | end
45 | end ~}}
46 |
47 | {{~ func get_property_type_of_sql_server(db_type)
48 | case db_type
49 | when "int","bigint","smallint"
50 | ret "int"
51 | when "image","binary","timestamp","varbinary"
52 | ret "byte[]"
53 | when "real"
54 | ret "float"
55 | when "float","double"
56 | ret "double"
57 | when "money","smallmoney","numeric","decimal"
58 | ret "decimal"
59 | when "tinyint"
60 | ret "byte"
61 | when "bit"
62 | ret "bool"
63 | when "uniqueidentifier"
64 | ret "Guid"
65 | when "smalldatetime","datetime","datetime2","date","time"
66 | ret "DateTime"
67 | when "datetimeoffset"
68 | ret "DateTimeOffset"
69 | when "geography"
70 | ret "Microsoft.SqlServer.Types.SqlGeography"
71 | when "geometry"
72 | ret "Microsoft.SqlServer.Types.SqlGeometry"
73 | else
74 | ret "string"
75 | end
76 | end ~}}
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Behaviors/NavigationViewHeaderMode.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Behaviors;
2 |
3 | public enum NavigationViewHeaderMode
4 | {
5 | Always,
6 | Never,
7 | Minimal
8 | }
9 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/CodeEditor/CompletionItemKind.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.CodeEditor;
2 |
3 | public enum CompletionItemKind
4 | {
5 | Method = 0,
6 | Function = 1,
7 | Constructor = 2,
8 | Field = 3,
9 | Variable = 4,
10 | Class = 5,
11 | Struct = 6,
12 | Interface = 7,
13 | Module = 8,
14 | Property = 9,
15 | Event = 10,
16 | Operator = 11,
17 | Unit = 12,
18 | Value = 13,
19 | Constant = 14,
20 | Enum = 15,
21 | EnumMember = 16,
22 | Keyword = 17,
23 | Text = 18,
24 | Color = 19,
25 | File = 20,
26 | Reference = 21,
27 | Customcolor = 22,
28 | Folder = 23,
29 | TypeParameter = 24,
30 | User = 25,
31 | Issue = 26,
32 | Snippet = 27
33 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/DbToys.WinUI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net8.0-windows10.0.19041.0
6 | 10.0.17763.0
7 | DbToys
8 | Assets/WindowIcon.ico
9 | app.manifest
10 | x64
11 | win10-x64
12 | Properties\PublishProfiles\win10-$(Platform).pubxml
13 | enable
14 | disable
15 | true
16 | true
17 | true
18 | true
19 | DbToys
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | PreserveNewest
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | https://pkgs.dev.azure.com/dotnet/CommunityToolkit/_packaging/CommunityToolkit-Labs/nuget/v3/index.json
42 |
43 |
44 |
45 | False
46 | False
47 | True
48 | False
49 | Auto
50 | False
51 | SHA256
52 | x64
53 | 10.0.17763.0
54 | True
55 | en-US
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Always
75 |
76 |
77 | MSBuild:Compile
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | true
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/DependencyObjectHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using Microsoft.UI.Xaml;
3 | using Microsoft.UI.Xaml.Media;
4 |
5 | namespace DbToys.Helpers;
6 |
7 | public static class DependencyObjectHelper
8 | {
9 | public static T FindChild(DependencyObject startNode) where T : DependencyObject
10 | {
11 | int count = VisualTreeHelper.GetChildrenCount(startNode);
12 | for (int i = 0; i < count; i++)
13 | {
14 | DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
15 | if (current.GetType() == typeof(T) || current.GetType().GetTypeInfo().IsSubclassOf(typeof(T)))
16 | {
17 | T asType = (T)current;
18 | return asType;
19 | }
20 | var retVal = FindChild(current);
21 | if (retVal is not null)
22 | {
23 | return retVal;
24 | }
25 | }
26 | return null;
27 | }
28 |
29 | public static T FindChild(DependencyObject startNode, Func predicate) where T : DependencyObject
30 | {
31 | int count = VisualTreeHelper.GetChildrenCount(startNode);
32 | for (int i = 0; i < count; i++)
33 | {
34 | DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
35 | if (current.GetType() == typeof(T) || current.GetType().GetTypeInfo().IsSubclassOf(typeof(T)))
36 | {
37 | T asType = (T)current;
38 | if (predicate(asType))
39 | {
40 | return asType;
41 | }
42 | }
43 | var retVal = FindChild(current, predicate);
44 | if (retVal is not null)
45 | {
46 | return retVal;
47 | }
48 | }
49 | return null;
50 | }
51 |
52 | public static IEnumerable FindChildren(DependencyObject startNode) where T : DependencyObject
53 | {
54 | int count = VisualTreeHelper.GetChildrenCount(startNode);
55 | for (int i = 0; i < count; i++)
56 | {
57 | var current = VisualTreeHelper.GetChild(startNode, i);
58 | if (current.GetType() == typeof(T) || current.GetType().GetTypeInfo().IsSubclassOf(typeof(T)))
59 | {
60 | T asType = (T)current;
61 | yield return asType;
62 | }
63 | foreach (var item in FindChildren(current))
64 | {
65 | yield return item;
66 | }
67 | }
68 | }
69 |
70 | public static T FindParent(DependencyObject child) where T : DependencyObject
71 | {
72 | if (child is null) return null;
73 | T parent = null;
74 |
75 | var currentParent = VisualTreeHelper.GetParent(child);
76 | while (currentParent is not null)
77 | {
78 | if (currentParent is T dependencyObject)
79 | {
80 | parent = dependencyObject;
81 | break;
82 | }
83 | currentParent = VisualTreeHelper.GetParent(currentParent);
84 | }
85 | return parent;
86 | }
87 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/DialogHelper.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml.Controls;
2 |
3 | namespace DbToys.Helpers;
4 |
5 | public class DialogHelper
6 | {
7 | public static ContentDialog SetContentDialogRoot(ContentDialog contentDialog)
8 | {
9 | contentDialog.XamlRoot = App.MainWindow.Content.XamlRoot;
10 | return contentDialog;
11 | }
12 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/EnumToBooleanConverter.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Data;
3 |
4 | namespace DbToys.Helpers;
5 |
6 | public class EnumToBooleanConverter : IValueConverter
7 | {
8 | public EnumToBooleanConverter()
9 | {
10 | }
11 |
12 | public object Convert(object value, Type targetType, object parameter, string language)
13 | {
14 | if (parameter is string enumString)
15 | {
16 | if (!Enum.IsDefined(typeof(ElementTheme), value))
17 | {
18 | throw new ArgumentException("ExceptionEnumToBooleanConverterValueMustBeAnEnum");
19 | }
20 |
21 | var enumValue = Enum.Parse(typeof(ElementTheme), enumString);
22 |
23 | return enumValue.Equals(value);
24 | }
25 |
26 | throw new ArgumentException("ExceptionEnumToBooleanConverterParameterMustBeAnEnumName");
27 | }
28 |
29 | public object ConvertBack(object value, Type targetType, object parameter, string language)
30 | {
31 | if (parameter is string enumString)
32 | {
33 | return Enum.Parse(typeof(ElementTheme), enumString);
34 | }
35 |
36 | throw new ArgumentException("ExceptionEnumToBooleanConverterParameterMustBeAnEnumName");
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/FileSystemHelper.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Core;
2 |
3 | namespace DbToys.Helpers;
4 |
5 | public static class FileSystemHelper
6 | {
7 | private static readonly char[] RestrictedCharacters = { '\\', '/', ':', '*', '?', '"', '<', '>', '|' };
8 | private static readonly string[] RestrictedFileNames = {
9 | "CON", "PRN", "AUX",
10 | "NUL", "COM1", "COM2",
11 | "COM3", "COM4", "COM5",
12 | "COM6", "COM7", "COM8",
13 | "COM9", "LPT1", "LPT2",
14 | "LPT3", "LPT4", "LPT5",
15 | "LPT6", "LPT7", "LPT8", "LPT9"
16 | };
17 |
18 | public static string GetDbToysLogFolder()
19 | {
20 | var folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
21 | Constants.FileSystem.DefaultApplicationDataFolderPath, "Logs");
22 | if (!Directory.Exists(folder))
23 | Directory.CreateDirectory(folder);
24 | return folder;
25 | }
26 |
27 | public static string GetDbToysAppDataFolder()
28 | {
29 | var appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
30 | var folder = Path.Combine(appData, Constants.FileSystem.DefaultApplicationDataFolderPath);
31 | if (!Directory.Exists(folder))
32 | Directory.CreateDirectory(folder);
33 | return folder;
34 | }
35 |
36 | public static string FilterRestrictedCharacters(string input)
37 | {
38 | int invalidCharIndex;
39 | while ((invalidCharIndex = input.IndexOfAny(RestrictedCharacters)) >= 0)
40 | {
41 | input = input.Remove(invalidCharIndex, 1);
42 | }
43 | return input;
44 | }
45 |
46 | public static bool ContainsRestrictedCharacters(string input)
47 | {
48 | return input.IndexOfAny(RestrictedCharacters) >= 0;
49 | }
50 |
51 | public static bool ContainsRestrictedFileName(string input)
52 | {
53 | foreach (string name in RestrictedFileNames)
54 | {
55 | if (input.StartsWith(name, StringComparison.OrdinalIgnoreCase) && (input.Length == name.Length || input[name.Length] == '.'))
56 | return true;
57 | }
58 |
59 | return false;
60 | }
61 |
62 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/FrameExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml.Controls;
2 |
3 | namespace DbToys.Helpers;
4 |
5 | public static class FrameExtensions
6 | {
7 | public static object GetPageViewModel(this Frame frame) => frame?.Content?.GetType().GetProperty("ViewModel")?.GetValue(frame.Content, null);
8 | }
9 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/Json.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Text.Encodings.Web;
3 | using System.Text.Json;
4 |
5 | namespace DbToys.Helpers;
6 |
7 | public static class Json
8 | {
9 | private static JsonSerializerOptions _options = new()
10 | {
11 | Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
12 | WriteIndented = true
13 | };
14 |
15 | public static T Deserialize(string value)
16 | {
17 | var type = typeof(T);
18 | var typeInfo = type.GetTypeInfo();
19 |
20 | if (typeInfo.IsPrimitive || type == typeof(string))
21 | {
22 | return (T)Convert.ChangeType(value, type);
23 | }
24 |
25 | return JsonSerializer.Deserialize(value, _options);
26 | }
27 |
28 | public static string Serialize(object value)
29 | {
30 | var type = value.GetType();
31 | var typeInfo = type.GetTypeInfo();
32 |
33 | if (typeInfo.IsPrimitive || type == typeof(string))
34 | {
35 | return (string)value;
36 | }
37 | return JsonSerializer.Serialize(value, type, _options);
38 | }
39 |
40 | public static async Task DeserializeAsync(string value)
41 | {
42 | return await Task.Run(() => Deserialize(value));
43 | }
44 |
45 | public static async Task SerializeAsync(object value)
46 | {
47 | return await Task.Run(() => Serialize(value));
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/NavigationHelper.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 |
4 | namespace DbToys.Helpers;
5 |
6 | // Helper class to set the navigation target for a NavigationViewItem.
7 | //
8 | // Usage in XAML:
9 | //
10 | //
11 | // Usage in code:
12 | // NavigationHelper.SetNavigateTo(navigationViewItem, typeof(MainViewModel).FullName);
13 | public class NavigationHelper
14 | {
15 | public static string GetNavigateTo(NavigationViewItem item) => (string)item.GetValue(NavigateToProperty);
16 |
17 | public static void SetNavigateTo(NavigationViewItem item, string value) => item.SetValue(NavigateToProperty, value);
18 |
19 | public static readonly DependencyProperty NavigateToProperty =
20 | DependencyProperty.RegisterAttached("NavigateTo", typeof(string), typeof(NavigationHelper), new PropertyMetadata(null));
21 | }
22 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/ResourceExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Windows.ApplicationModel.Resources;
2 |
3 | namespace DbToys.Helpers;
4 |
5 | public static class ResourceExtensions
6 | {
7 | private static readonly ResourceLoader _resourceLoader = new();
8 |
9 | public static string GetLocalized(this string resourceKey) => _resourceLoader.GetString(resourceKey);
10 | }
11 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/RuntimeHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 |
4 | namespace DbToys.Helpers;
5 |
6 | public class RuntimeHelper
7 | {
8 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
9 | private static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName);
10 |
11 | public static bool IsMSIX
12 | {
13 | get
14 | {
15 | var length = 0;
16 |
17 | return GetCurrentPackageFullName(ref length, null) != 15700L;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/SettingsStorageExtensions.cs:
--------------------------------------------------------------------------------
1 | using Windows.Storage;
2 | using Windows.Storage.Streams;
3 |
4 | namespace DbToys.Helpers;
5 |
6 | // Use these extension methods to store and retrieve local and roaming app data
7 | // More details regarding storing and retrieving app data at https://docs.microsoft.com/windows/apps/design/app-settings/store-and-retrieve-app-data
8 | public static class SettingsStorageExtensions
9 | {
10 | private const string FileExtension = ".json";
11 |
12 | public static bool IsRoamingStorageAvailable(this ApplicationData appData)
13 | {
14 | return appData.RoamingStorageQuota == 0;
15 | }
16 |
17 | public static async Task SaveAsync(this StorageFolder folder, string name, T content)
18 | {
19 | var file = await folder.CreateFileAsync(GetFileName(name), CreationCollisionOption.ReplaceExisting);
20 | var fileContent = await Json.SerializeAsync(content);
21 |
22 | await FileIO.WriteTextAsync(file, fileContent);
23 | }
24 |
25 | public static async Task ReadAsync(this StorageFolder folder, string name)
26 | {
27 | if (!File.Exists(Path.Combine(folder.Path, GetFileName(name))))
28 | {
29 | return default;
30 | }
31 |
32 | var file = await folder.GetFileAsync($"{name}.json");
33 | var fileContent = await FileIO.ReadTextAsync(file);
34 |
35 | return await Json.DeserializeAsync(fileContent);
36 | }
37 |
38 | public static async Task SaveAsync(this ApplicationDataContainer settings, string key, T value)
39 | {
40 | settings.SaveString(key, await Json.SerializeAsync(value));
41 | }
42 |
43 | public static void SaveString(this ApplicationDataContainer settings, string key, string value)
44 | {
45 | settings.Values[key] = value;
46 | }
47 |
48 | public static async Task ReadAsync(this ApplicationDataContainer settings, string key)
49 | {
50 | object obj;
51 |
52 | if (settings.Values.TryGetValue(key, out obj))
53 | {
54 | return await Json.DeserializeAsync((string)obj);
55 | }
56 |
57 | return default;
58 | }
59 |
60 | public static async Task SaveFileAsync(this StorageFolder folder, byte[] content, string fileName, CreationCollisionOption options = CreationCollisionOption.ReplaceExisting)
61 | {
62 | if (content == null)
63 | {
64 | throw new ArgumentNullException(nameof(content));
65 | }
66 |
67 | if (string.IsNullOrEmpty(fileName))
68 | {
69 | throw new ArgumentException("File name is null or empty. Specify a valid file name", nameof(fileName));
70 | }
71 |
72 | var storageFile = await folder.CreateFileAsync(fileName, options);
73 | await FileIO.WriteBytesAsync(storageFile, content);
74 | return storageFile;
75 | }
76 |
77 | public static async Task ReadFileAsync(this StorageFolder folder, string fileName)
78 | {
79 | var item = await folder.TryGetItemAsync(fileName).AsTask().ConfigureAwait(false);
80 |
81 | if ((item != null) && item.IsOfType(StorageItemTypes.File))
82 | {
83 | var storageFile = await folder.GetFileAsync(fileName);
84 | var content = await storageFile.ReadBytesAsync();
85 | return content;
86 | }
87 |
88 | return null;
89 | }
90 |
91 | public static async Task ReadBytesAsync(this StorageFile file)
92 | {
93 | if (file != null)
94 | {
95 | using IRandomAccessStream stream = await file.OpenReadAsync();
96 | using var reader = new DataReader(stream.GetInputStreamAt(0));
97 | await reader.LoadAsync((uint)stream.Size);
98 | var bytes = new byte[stream.Size];
99 | reader.ReadBytes(bytes);
100 | return bytes;
101 | }
102 |
103 | return null;
104 | }
105 |
106 | private static string GetFileName(string name)
107 | {
108 | return string.Concat(name, FileExtension);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/StorageItemIconHelper.cs:
--------------------------------------------------------------------------------
1 | using Windows.Storage;
2 | using Windows.Storage.FileProperties;
3 | using DbToys.Core;
4 |
5 | namespace DbToys.Helpers;
6 |
7 | public class StorageItemIconHelper
8 | {
9 | public static async Task GetIconForItemType(uint requestedSize, string fileExtension = null)
10 | {
11 | if (string.IsNullOrEmpty(fileExtension))
12 | {
13 | var localFolder = ApplicationData.Current.RoamingFolder;
14 | return await localFolder.GetThumbnailAsync(ThumbnailMode.ListView, requestedSize, ThumbnailOptions.UseCurrentScale);
15 | }
16 |
17 | var emptyFile = await ApplicationData.Current.LocalCacheFolder.CreateFileAsync(string.Concat(Constants.FileSystem.CachedEmptyItemName, fileExtension), CreationCollisionOption.OpenIfExists);
18 | var icon = await emptyFile.GetThumbnailAsync(ThumbnailMode.ListView, requestedSize, ThumbnailOptions.UseCurrentScale);
19 |
20 | return icon;
21 | }
22 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/TitleBarHelper.cs:
--------------------------------------------------------------------------------
1 | using Windows.UI;
2 | using Microsoft.UI;
3 | using Microsoft.UI.Xaml;
4 | using Microsoft.UI.Xaml.Media;
5 |
6 | namespace DbToys.Helpers;
7 |
8 | // Helper class to workaround custom title bar bugs.
9 | // DISCLAIMER: The resource key names and color values used below are subject to change. Do not depend on them.
10 | // https://github.com/microsoft/TemplateStudio/issues/4516
11 | internal class TitleBarHelper
12 | {
13 | private const int WAINACTIVE = 0x00;
14 | private const int WAACTIVE = 0x01;
15 | private const int WMACTIVATE = 0x0006;
16 |
17 | public static void UpdateTitleBar(ElementTheme theme)
18 | {
19 | if (App.MainWindow.ExtendsContentIntoTitleBar)
20 | {
21 | if (theme != ElementTheme.Default)
22 | {
23 | Application.Current.Resources["WindowCaptionForeground"] = theme switch
24 | {
25 | ElementTheme.Dark => new SolidColorBrush(Colors.White),
26 | ElementTheme.Light => new SolidColorBrush(Colors.Black),
27 | _ => new SolidColorBrush(Colors.Transparent)
28 | };
29 |
30 | Application.Current.Resources["WindowCaptionForegroundDisabled"] = theme switch
31 | {
32 | ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x66, 0xFF, 0xFF, 0xFF)),
33 | ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x66, 0x00, 0x00, 0x00)),
34 | _ => new SolidColorBrush(Colors.Transparent)
35 | };
36 |
37 | Application.Current.Resources["WindowCaptionButtonBackgroundPointerOver"] = theme switch
38 | {
39 | ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x33, 0xFF, 0xFF, 0xFF)),
40 | ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x33, 0x00, 0x00, 0x00)),
41 | _ => new SolidColorBrush(Colors.Transparent)
42 | };
43 |
44 | Application.Current.Resources["WindowCaptionButtonBackgroundPressed"] = theme switch
45 | {
46 | ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x66, 0xFF, 0xFF, 0xFF)),
47 | ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x66, 0x00, 0x00, 0x00)),
48 | _ => new SolidColorBrush(Colors.Transparent)
49 | };
50 |
51 | Application.Current.Resources["WindowCaptionButtonStrokePointerOver"] = theme switch
52 | {
53 | ElementTheme.Dark => new SolidColorBrush(Colors.White),
54 | ElementTheme.Light => new SolidColorBrush(Colors.Black),
55 | _ => new SolidColorBrush(Colors.Transparent)
56 | };
57 |
58 | Application.Current.Resources["WindowCaptionButtonStrokePressed"] = theme switch
59 | {
60 | ElementTheme.Dark => new SolidColorBrush(Colors.White),
61 | ElementTheme.Light => new SolidColorBrush(Colors.Black),
62 | _ => new SolidColorBrush(Colors.Transparent)
63 | };
64 | }
65 |
66 | Application.Current.Resources["WindowCaptionBackground"] = new SolidColorBrush(Colors.Transparent);
67 | Application.Current.Resources["WindowCaptionBackgroundDisabled"] = new SolidColorBrush(Colors.Transparent);
68 |
69 | var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
70 | if (hwnd == Win32Helper.GetActiveWindow())
71 | {
72 | Win32Helper.SendMessage(hwnd, WMACTIVATE, WAINACTIVE, IntPtr.Zero);
73 | Win32Helper.SendMessage(hwnd, WMACTIVATE, WAACTIVE, IntPtr.Zero);
74 | }
75 | else
76 | {
77 | Win32Helper.SendMessage(hwnd, WMACTIVATE, WAACTIVE, IntPtr.Zero);
78 | Win32Helper.SendMessage(hwnd, WMACTIVATE, WAINACTIVE, IntPtr.Zero);
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/UIElementExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using Microsoft.UI.Input;
3 | using Microsoft.UI.Xaml;
4 |
5 | namespace DbToys.Helpers;
6 |
7 | public static class UIElementExtensions
8 | {
9 | public static void ChangeCursor(this UIElement uiElement, InputCursor cursor)
10 | {
11 | Type type = typeof(UIElement);
12 | type.InvokeMember("ProtectedCursor", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, uiElement, new object[] { cursor });
13 | }
14 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Helpers/Win32Helper.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace DbToys.Helpers;
4 |
5 | public static class Win32Helper
6 | {
7 | [DllImport("user32.dll")]
8 | public static extern IntPtr GetActiveWindow();
9 |
10 | [DllImport("user32.dll", CharSet = CharSet.Auto)]
11 | public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
12 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Helpers;
2 |
3 | namespace DbToys;
4 |
5 | public sealed partial class MainWindow : WindowEx
6 | {
7 | public MainWindow()
8 | {
9 | InitializeComponent();
10 |
11 | AppWindow.SetIcon(Path.Combine(AppContext.BaseDirectory, "Assets/WindowIcon.ico"));
12 | Content = null;
13 | Title = "AppDisplayName".GetLocalized();
14 | this.CenterOnScreen();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Package.appinstaller:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
16 |
17 |
18 | DbToys
19 | 邱尘
20 | Assets\StoreLogo.png
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Properties/launchsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "WSL": {
4 | "commandName": "WSL2",
5 | "distributionName": ""
6 | },
7 | "Netcool.DbToys.WinUI (Unpackaged)": {
8 | "commandName": "Project"
9 | },
10 | "Netcool.DbToys.WinUI (Package)": {
11 | "commandName": "MsixPackage"
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/README.md:
--------------------------------------------------------------------------------
1 | *Recommended Markdown Viewer: [Markdown Editor](https://marketplace.visualstudio.com/items?itemName=MadsKristensen.MarkdownEditor2)*
2 |
3 | ## Getting Started
4 |
5 | Browse and address `TODO:` comments in `View -> Task List` to learn the codebase and understand next steps for turning the generated code into production code.
6 |
7 | Explore the [WinUI Gallery](https://www.microsoft.com/store/productId/9P3JFPWWDZRC) to learn about available controls and design patterns.
8 |
9 | Relaunch Template Studio to modify the project by right-clicking on the project in `View -> Solution Explorer` then selecting `Add -> New Item (Template Studio)`.
10 |
11 | ## Publishing
12 |
13 | For projects with MSIX packaging, right-click on the application project and select `Package and Publish -> Create App Packages...` to create an MSIX package.
14 |
15 | For projects without MSIX packaging, follow the [deployment guide](https://docs.microsoft.com/windows/apps/windows-app-sdk/deploy-unpackaged-apps) or add the `Self-Contained` Feature to enable xcopy deployment.
16 |
17 | ## CI Pipelines
18 |
19 | See [README.md](https://github.com/microsoft/TemplateStudio/blob/main/docs/WinUI/pipelines/README.md) for guidance on building and testing projects in CI pipelines.
20 |
21 | ## Changelog
22 |
23 | See [releases](https://github.com/microsoft/TemplateStudio/releases) and [milestones](https://github.com/microsoft/TemplateStudio/milestones).
24 |
25 | ## Feedback
26 |
27 | Bugs and feature requests should be filed at https://aka.ms/templatestudio.
28 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/ActivationService.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Activation;
2 | using DbToys.Views;
3 | using Microsoft.UI.Xaml;
4 | using Microsoft.UI.Xaml.Controls;
5 |
6 | namespace DbToys.Services;
7 |
8 | public class ActivationService : IActivationService
9 | {
10 | private readonly ActivationHandler _defaultHandler;
11 | private readonly IEnumerable _activationHandlers;
12 | private readonly IThemeSelectorService _themeSelectorService;
13 | private UIElement _shell = null;
14 |
15 | public ActivationService(ActivationHandler defaultHandler, IEnumerable activationHandlers, IThemeSelectorService themeSelectorService)
16 | {
17 | _defaultHandler = defaultHandler;
18 | _activationHandlers = activationHandlers;
19 | _themeSelectorService = themeSelectorService;
20 | }
21 |
22 | public async Task ActivateAsync(object activationArgs)
23 | {
24 | // Execute tasks before activation.
25 | await InitializeAsync();
26 |
27 | // Set the MainWindow Content.
28 | if (App.MainWindow.Content == null)
29 | {
30 | _shell = App.GetService();
31 | App.MainWindow.Content = _shell ?? new Frame();
32 | }
33 |
34 | // Handle activation via ActivationHandlers.
35 | await HandleActivationAsync(activationArgs);
36 |
37 | // Activate the MainWindow.
38 | App.MainWindow.Activate();
39 |
40 | // Execute tasks after activation.
41 | await StartupAsync();
42 | }
43 |
44 | private async Task HandleActivationAsync(object activationArgs)
45 | {
46 | var activationHandler = _activationHandlers.FirstOrDefault(h => h.CanHandle(activationArgs));
47 |
48 | if (activationHandler != null)
49 | {
50 | await activationHandler.HandleAsync(activationArgs);
51 | }
52 |
53 | if (_defaultHandler.CanHandle(activationArgs))
54 | {
55 | await _defaultHandler.HandleAsync(activationArgs);
56 | }
57 | }
58 |
59 | private async Task InitializeAsync()
60 | {
61 | await _themeSelectorService.InitializeAsync().ConfigureAwait(false);
62 | await Task.CompletedTask;
63 | }
64 |
65 | private async Task StartupAsync()
66 | {
67 | await _themeSelectorService.SetRequestedThemeAsync();
68 | await Task.CompletedTask;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/CodeTemplateStorageService.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Windows.Storage;
3 | using Windows.Storage.Search;
4 | using DbToys.Core;
5 | using System.Text.RegularExpressions;
6 |
7 | namespace DbToys.Services;
8 |
9 | public class CodeTemplateStorageService
10 | {
11 | public string TemplateFolderPath { get; } = Path.Combine(
12 | Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
13 | Constants.FileSystem.DefaultCodeTemplateFolderPath);
14 |
15 | public StorageFolder TemplateFolder { get; private set; }
16 |
17 | public async Task> GetProjectFoldersAsync()
18 | {
19 | await EnsureTemplateFolder();
20 | await EnsureGlobalProject();
21 | var folders = await TemplateFolder.GetFoldersAsync();
22 | return folders.ToList();
23 | }
24 |
25 | public async Task> GetTemplateFilesAsync(StorageFolder folder)
26 | {
27 | ArgumentNullException.ThrowIfNull(nameof(folder));
28 | var files = (await folder.GetFilesAsync(CommonFileQuery.OrderByName)).ToList();
29 | if (folder.Name == Constants.CodeTemplate.DefaultGlobalTemplateFolderName && files.Count == 0)
30 | {
31 | var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/global.tpl"));
32 | var defaultGlobalTemplate = await file.CopyAsync(folder, file.Name);
33 |
34 | files.Add(defaultGlobalTemplate);
35 | }
36 | return files;
37 | }
38 |
39 | public async Task CreateProjectFolder(string folderName)
40 | {
41 | if (string.IsNullOrEmpty(folderName)) return null;
42 | await EnsureTemplateFolder();
43 | if (Directory.Exists(Path.Join(TemplateFolderPath, folderName))) return null;
44 | var folder = await TemplateFolder.CreateFolderAsync(folderName);
45 | return folder;
46 | }
47 |
48 | public async Task CreateTemplateFile(StorageFolder folder, string filename, string initText)
49 | {
50 | if (folder == null || string.IsNullOrEmpty(filename)) return null;
51 |
52 | var file = await folder.CreateFileAsync(filename, CreationCollisionOption.FailIfExists);
53 | if (!string.IsNullOrEmpty(initText))
54 | {
55 | await FileIO.WriteTextAsync(file, Constants.CodeTemplate.InitialTemplateText);
56 | }
57 |
58 | return file;
59 | }
60 |
61 | public async Task GetGlobalTemplateText()
62 | {
63 | var folder = await TemplateFolder.GetFolderAsync(Constants.CodeTemplate.DefaultGlobalTemplateFolderName);
64 | var files = await folder.GetFilesAsync();
65 | if (files == null || files.Count == 0) return null;
66 | var sb = new StringBuilder();
67 | foreach (var file in files)
68 | {
69 | var text = await FileIO.ReadTextAsync(file);
70 | if (string.IsNullOrWhiteSpace(text)) continue;
71 | sb.AppendLine(Regex.Replace(text, @"^\s*$\n|\r", string.Empty, RegexOptions.Multiline).Trim());
72 | }
73 |
74 | return sb.ToString();
75 | }
76 |
77 |
78 | private async Task EnsureTemplateFolder()
79 | {
80 | if (TemplateFolder != null) return;
81 |
82 | if (!Directory.Exists(TemplateFolderPath))
83 | {
84 | Directory.CreateDirectory(TemplateFolderPath);
85 | }
86 |
87 | TemplateFolder = await StorageFolder.GetFolderFromPathAsync(TemplateFolderPath);
88 | }
89 |
90 | private async Task EnsureGlobalProject()
91 | {
92 | var item = await TemplateFolder.TryGetItemAsync(Constants.CodeTemplate.DefaultGlobalTemplateFolderName);
93 | if (item is StorageFolder)
94 | {
95 | return;
96 | }
97 |
98 | await TemplateFolder.CreateFolderAsync(Constants.CodeTemplate.DefaultGlobalTemplateFolderName);
99 | }
100 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/FileSystem/BaseStorageFolder.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Services.FileSystem;
2 |
3 | public abstract class BaseStorageFolder
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/FileSystem/IBaseStorageFile.cs:
--------------------------------------------------------------------------------
1 | using Windows.Foundation;
2 | using Windows.Storage;
3 | using Windows.Storage.FileProperties;
4 |
5 | namespace DbToys.Services.FileSystem;
6 |
7 | public interface IBaseStorageFile : IStorageItem2, IStorageFile, IStorageFile2
8 | , IStorageItemProperties2, IStorageItemPropertiesWithProvider, IStorageFilePropertiesWithAvailability
9 | {
10 | new IStorageItemExtraProperties Properties { get; }
11 |
12 | IAsyncOperation ToStorageFileAsync();
13 |
14 | new IAsyncOperation GetParentAsync();
15 | //new IAsyncOperation GetBasicPropertiesAsync();
16 |
17 | new IAsyncOperation CopyAsync(IStorageFolder destinationFolder);
18 | new IAsyncOperation CopyAsync(IStorageFolder destinationFolder, string desiredNewName);
19 | new IAsyncOperation CopyAsync(IStorageFolder destinationFolder, string desiredNewName, NameCollisionOption option);
20 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/FileSystem/IBaseStorageFolder.cs:
--------------------------------------------------------------------------------
1 | using Windows.Foundation;
2 | using Windows.Storage;
3 | using Windows.Storage.FileProperties;
4 | using Windows.Storage.Search;
5 |
6 | namespace DbToys.Services.FileSystem;
7 |
8 | public interface IBaseStorageFolder : IStorageItem2, IStorageFolder, IStorageFolder2
9 | , IStorageItemProperties2, IStorageItemPropertiesWithProvider, IStorageFolderQueryOperations
10 | {
11 | new IStorageItemExtraProperties Properties { get; }
12 |
13 | IAsyncOperation ToStorageFolderAsync();
14 |
15 | new IAsyncOperation GetParentAsync();
16 | //new IAsyncOperation GetBasicPropertiesAsync();
17 |
18 | new IAsyncOperation GetItemAsync(string name);
19 | new IAsyncOperation> GetItemsAsync();
20 |
21 | new IAsyncOperation GetFileAsync(string name);
22 | new IAsyncOperation> GetFilesAsync();
23 | new IAsyncOperation> GetFilesAsync(CommonFileQuery query);
24 | new IAsyncOperation> GetFilesAsync(CommonFileQuery query, uint startIndex, uint maxItemsToRetrieve);
25 |
26 | new IAsyncOperation GetFolderAsync(string name);
27 | new IAsyncOperation> GetFoldersAsync();
28 | new IAsyncOperation> GetFoldersAsync(CommonFolderQuery query);
29 | new IAsyncOperation> GetFoldersAsync(CommonFolderQuery query, uint startIndex, uint maxItemsToRetrieve);
30 |
31 | new IAsyncOperation CreateFileAsync(string desiredName);
32 | new IAsyncOperation CreateFileAsync(string desiredName, CreationCollisionOption options);
33 | new IAsyncOperation CreateFolderAsync(string desiredName);
34 | new IAsyncOperation CreateFolderAsync(string desiredName, CreationCollisionOption options);
35 |
36 | //new BaseStorageItemQueryResult CreateItemQueryWithOptions(QueryOptions queryOptions);
37 | //new BaseStorageFileQueryResult CreateFileQueryWithOptions(QueryOptions queryOptions);
38 | //new BaseStorageFolderQueryResult CreateFolderQueryWithOptions(QueryOptions queryOptions);
39 | }
40 |
41 | public interface ICreateFileWithStream
42 | {
43 | IAsyncOperation CreateFileAsync(Stream contents, string desiredName);
44 |
45 | IAsyncOperation CreateFileAsync(Stream contents, string desiredName, CreationCollisionOption options);
46 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/IActivationService.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Services;
2 |
3 | public interface IActivationService
4 | {
5 | Task ActivateAsync(object activationArgs);
6 | }
7 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/INavigationService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml.Controls;
2 | using Microsoft.UI.Xaml.Navigation;
3 |
4 | namespace DbToys.Services;
5 |
6 | public interface INavigationService
7 | {
8 | event NavigatedEventHandler Navigated;
9 |
10 | bool CanGoBack
11 | {
12 | get;
13 | }
14 |
15 | Frame Frame
16 | {
17 | get; set;
18 | }
19 |
20 | bool NavigateTo(string pageKey, object parameter = null, bool clearNavigation = false);
21 |
22 | bool GoBack();
23 | }
24 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/INavigationViewService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml.Controls;
2 |
3 | namespace DbToys.Services;
4 |
5 | public interface INavigationViewService
6 | {
7 | IList MenuItems
8 | {
9 | get;
10 | }
11 |
12 | object SettingsItem
13 | {
14 | get;
15 | }
16 |
17 | void Initialize(NavigationView navigationView);
18 |
19 | void UnregisterEvents();
20 |
21 | NavigationViewItem GetSelectedItem(Type pageType);
22 | }
23 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/IPageService.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Services;
2 |
3 | public interface IPageService
4 | {
5 | Type GetPageType(string key);
6 | }
7 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/IThemeSelectorService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 |
3 | namespace DbToys.Services;
4 |
5 | public interface IThemeSelectorService
6 | {
7 | ElementTheme Theme
8 | {
9 | get;
10 | }
11 |
12 | Task InitializeAsync();
13 |
14 | Task SetThemeAsync(ElementTheme theme);
15 |
16 | Task SetRequestedThemeAsync();
17 | }
18 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/LoadingService.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Services;
2 |
3 | public interface ILoadingService
4 | {
5 | public void Active(string text = null);
6 | public void Dismiss();
7 | public Action LoadingRequested { get; set; }
8 | }
9 |
10 | public class LoadingService : ILoadingService
11 | {
12 | public void Active(string text = null)
13 | {
14 | LoadingRequested(true, text);
15 | }
16 |
17 | public void Dismiss()
18 | {
19 | LoadingRequested(false, null);
20 | }
21 |
22 | public Action LoadingRequested { get; set; }
23 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/NavigationService.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using DbToys.Helpers;
3 | using DbToys.ViewModels;
4 | using Microsoft.UI.Xaml.Controls;
5 | using Microsoft.UI.Xaml.Navigation;
6 |
7 | namespace DbToys.Services;
8 |
9 | // For more information on navigation between pages see
10 | // https://github.com/microsoft/TemplateStudio/blob/main/docs/WinUI/navigation.md
11 | public class NavigationService : INavigationService
12 | {
13 | private readonly IPageService _pageService;
14 | private object _lastParameterUsed;
15 | private Frame _frame;
16 |
17 | public event NavigatedEventHandler Navigated;
18 |
19 | public Frame Frame
20 | {
21 | get
22 | {
23 | if (_frame == null)
24 | {
25 | _frame = App.MainWindow.Content as Frame;
26 | RegisterFrameEvents();
27 | }
28 |
29 | return _frame;
30 | }
31 |
32 | set
33 | {
34 | UnregisterFrameEvents();
35 | _frame = value;
36 | RegisterFrameEvents();
37 | }
38 | }
39 |
40 | [MemberNotNullWhen(true, nameof(Frame), nameof(_frame))]
41 | public bool CanGoBack => Frame != null && Frame.CanGoBack;
42 |
43 | public NavigationService(IPageService pageService)
44 | {
45 | _pageService = pageService;
46 | }
47 |
48 | private void RegisterFrameEvents()
49 | {
50 | if (_frame != null)
51 | {
52 | _frame.Navigated += OnNavigated;
53 | }
54 | }
55 |
56 | private void UnregisterFrameEvents()
57 | {
58 | if (_frame != null)
59 | {
60 | _frame.Navigated -= OnNavigated;
61 | }
62 | }
63 |
64 | public bool GoBack()
65 | {
66 | if (CanGoBack)
67 | {
68 | var vmBeforeNavigation = _frame.GetPageViewModel();
69 | _frame.GoBack();
70 | if (vmBeforeNavigation is INavigationAware navigationAware)
71 | {
72 | navigationAware.OnNavigatedFrom();
73 | }
74 |
75 | return true;
76 | }
77 |
78 | return false;
79 | }
80 |
81 | public bool NavigateTo(string pageKey, object parameter = null, bool clearNavigation = false)
82 | {
83 | var pageType = _pageService.GetPageType(pageKey);
84 |
85 | if (_frame != null && (_frame.Content?.GetType() != pageType || (parameter != null && !parameter.Equals(_lastParameterUsed))))
86 | {
87 | _frame.Tag = clearNavigation;
88 | var vmBeforeNavigation = _frame.GetPageViewModel();
89 | var navigated = _frame.Navigate(pageType, parameter);
90 | if (navigated)
91 | {
92 | _lastParameterUsed = parameter;
93 | if (vmBeforeNavigation is INavigationAware navigationAware)
94 | {
95 | navigationAware.OnNavigatedFrom();
96 | }
97 | }
98 |
99 | return navigated;
100 | }
101 |
102 | return false;
103 | }
104 |
105 | private void OnNavigated(object sender, NavigationEventArgs e)
106 | {
107 | if (sender is Frame frame)
108 | {
109 | var clearNavigation = (bool)frame.Tag;
110 | if (clearNavigation)
111 | {
112 | frame.BackStack.Clear();
113 | }
114 |
115 | if (frame.GetPageViewModel() is INavigationAware navigationAware)
116 | {
117 | navigationAware.OnNavigatedTo(e.Parameter);
118 | }
119 |
120 | Navigated?.Invoke(sender, e);
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/NavigationViewService.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using DbToys.Helpers;
3 | using DbToys.ViewModels;
4 | using Microsoft.UI.Xaml.Controls;
5 |
6 | namespace DbToys.Services;
7 |
8 | public class NavigationViewService : INavigationViewService
9 | {
10 | private readonly INavigationService _navigationService;
11 |
12 | private readonly IPageService _pageService;
13 |
14 | private NavigationView _navigationView;
15 |
16 | public IList MenuItems => _navigationView?.MenuItems;
17 |
18 | public object SettingsItem => _navigationView?.SettingsItem;
19 |
20 | public NavigationViewService(INavigationService navigationService, IPageService pageService)
21 | {
22 | _navigationService = navigationService;
23 | _pageService = pageService;
24 | }
25 |
26 | [MemberNotNull(nameof(_navigationView))]
27 | public void Initialize(NavigationView navigationView)
28 | {
29 | _navigationView = navigationView;
30 | _navigationView.BackRequested += OnBackRequested;
31 | _navigationView.ItemInvoked += OnItemInvoked;
32 | }
33 |
34 | public void UnregisterEvents()
35 | {
36 | if (_navigationView != null)
37 | {
38 | _navigationView.BackRequested -= OnBackRequested;
39 | _navigationView.ItemInvoked -= OnItemInvoked;
40 | }
41 | }
42 |
43 | public NavigationViewItem GetSelectedItem(Type pageType)
44 | {
45 | if (_navigationView != null)
46 | {
47 | return GetSelectedItem(_navigationView.MenuItems, pageType) ?? GetSelectedItem(_navigationView.FooterMenuItems, pageType);
48 | }
49 |
50 | return null;
51 | }
52 |
53 | private void OnBackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args) => _navigationService.GoBack();
54 |
55 | private void OnItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
56 | {
57 | if (args.IsSettingsInvoked)
58 | {
59 | _navigationService.NavigateTo(typeof(SettingsViewModel).FullName!);
60 | }
61 | else
62 | {
63 | var selectedItem = args.InvokedItemContainer as NavigationViewItem;
64 |
65 | if (selectedItem?.GetValue(NavigationHelper.NavigateToProperty) is string pageKey)
66 | {
67 | _navigationService.NavigateTo(pageKey);
68 | }
69 | }
70 | }
71 |
72 | private NavigationViewItem GetSelectedItem(IEnumerable menuItems, Type pageType)
73 | {
74 | foreach (var item in menuItems.OfType())
75 | {
76 | if (IsMenuItemForPageType(item, pageType))
77 | {
78 | return item;
79 | }
80 |
81 | var selectedChild = GetSelectedItem(item.MenuItems, pageType);
82 | if (selectedChild != null)
83 | {
84 | return selectedChild;
85 | }
86 | }
87 |
88 | return null;
89 | }
90 |
91 | private bool IsMenuItemForPageType(NavigationViewItem menuItem, Type sourcePageType)
92 | {
93 | if (menuItem.GetValue(NavigationHelper.NavigateToProperty) is string pageKey)
94 | {
95 | return _pageService.GetPageType(pageKey) == sourcePageType;
96 | }
97 |
98 | return false;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/PageService.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using DbToys.ViewModels;
3 | using DbToys.Views;
4 | using Microsoft.UI.Xaml.Controls;
5 |
6 | namespace DbToys.Services;
7 |
8 | public class PageService : IPageService
9 | {
10 | private readonly Dictionary _pages = new();
11 |
12 | public PageService()
13 | {
14 | Configure();
15 | Configure();
16 | Configure();
17 | Configure();
18 | Configure();
19 | }
20 |
21 | public Type GetPageType(string key)
22 | {
23 | Type pageType;
24 | lock (_pages)
25 | {
26 | if (!_pages.TryGetValue(key, out pageType))
27 | {
28 | throw new ArgumentException($"Page not found: {key}. Did you forget to call PageService.Configure?");
29 | }
30 | }
31 |
32 | return pageType;
33 | }
34 |
35 | private void Configure()
36 | where VM : ObservableObject
37 | where V : Page
38 | {
39 | lock (_pages)
40 | {
41 | var key = typeof(VM).FullName!;
42 | if (_pages.ContainsKey(key))
43 | {
44 | throw new ArgumentException($"The key {key} is already configured in PageService");
45 | }
46 |
47 | var type = typeof(V);
48 | if (_pages.Any(p => p.Value == type))
49 | {
50 | throw new ArgumentException($"This type is already configured with key {_pages.First(p => p.Value == type).Key}");
51 | }
52 |
53 | _pages.Add(key, type);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/Settings/FileService.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using DbToys.Helpers;
3 |
4 | namespace DbToys.Services.Settings;
5 |
6 | public class FileService : IFileService
7 | {
8 | public T Read(string folderPath, string fileName)
9 | {
10 | ArgumentException.ThrowIfNullOrEmpty(folderPath);
11 | ArgumentException.ThrowIfNullOrEmpty(fileName);
12 | var path = Path.Combine(folderPath, fileName);
13 | if (File.Exists(path))
14 | {
15 | var json = File.ReadAllText(path);
16 | return Json.Deserialize(json);
17 | }
18 |
19 | return default;
20 | }
21 |
22 | public void Save(string folderPath, string fileName, T content)
23 | {
24 | ArgumentException.ThrowIfNullOrEmpty(folderPath);
25 | ArgumentException.ThrowIfNullOrEmpty(fileName);
26 | if (!Directory.Exists(folderPath))
27 | {
28 | Directory.CreateDirectory(folderPath);
29 | }
30 |
31 | var fileContent = Json.Serialize(content);
32 | File.WriteAllText(Path.Combine(folderPath, fileName), fileContent, Encoding.UTF8);
33 | }
34 |
35 | public void Delete(string folderPath, string fileName)
36 | {
37 | ArgumentException.ThrowIfNullOrEmpty(folderPath);
38 | ArgumentException.ThrowIfNullOrEmpty(fileName);
39 | if (File.Exists(Path.Combine(folderPath, fileName)))
40 | {
41 | File.Delete(Path.Combine(folderPath, fileName));
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/Settings/GeneralSettingsService.cs:
--------------------------------------------------------------------------------
1 |
2 | using DbToys.Core;
3 |
4 | namespace DbToys.Services.Settings;
5 |
6 | public class GeneralSettingsService : SettingsServiceBase
7 | {
8 | public GeneralSettingsService(IFileService fileService)
9 | : base(fileService)
10 | {
11 | }
12 |
13 | public override string SettingFileName { get; set; } = Constants.LocalSettings.GeneralSettingsFileName;
14 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/Settings/IFileService.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Services.Settings;
2 |
3 | public interface IFileService
4 | {
5 | T Read(string folderPath, string fileName);
6 |
7 | void Save(string folderPath, string fileName, T content);
8 |
9 | void Delete(string folderPath, string fileName);
10 | }
11 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/Settings/ISettingsService.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.Services.Settings;
2 |
3 | public interface ISettingsService
4 | {
5 | string SettingFileName { get; set; }
6 |
7 | T GetValue(string key);
8 |
9 | void SetValue(string key, T value);
10 |
11 | Task GetValueAsync(string key);
12 |
13 | Task SetValueAsync(string key, T value);
14 | }
15 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/Settings/SettingsServiceBase.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using System.Text.Json.Serialization;
3 | using Windows.Storage;
4 | using DbToys.Helpers;
5 |
6 | namespace DbToys.Services.Settings;
7 |
8 | public abstract class SettingsServiceBase : ISettingsService
9 | {
10 | [JsonIgnore]
11 | public abstract string SettingFileName { get; set; }
12 |
13 | private readonly IFileService _fileService;
14 |
15 | private readonly string _applicationDataFolder;
16 |
17 | private IDictionary _settings;
18 |
19 | private bool _isInitialized;
20 |
21 | protected SettingsServiceBase(IFileService fileService)
22 | {
23 | _fileService = fileService;
24 |
25 | _applicationDataFolder = FileSystemHelper.GetDbToysAppDataFolder();
26 | _settings = new Dictionary();
27 | }
28 |
29 | protected virtual void Initialize()
30 | {
31 | if (!_isInitialized)
32 | {
33 | _settings = _fileService.Read>(_applicationDataFolder, SettingFileName) ?? new Dictionary();
34 |
35 | _isInitialized = true;
36 | }
37 | }
38 |
39 | protected virtual async Task InitializeAsync()
40 | {
41 | if (!_isInitialized)
42 | {
43 | _settings = await Task.Run(() => _fileService.Read>(_applicationDataFolder, SettingFileName)) ?? new Dictionary();
44 |
45 | _isInitialized = true;
46 | }
47 | }
48 |
49 | public T GetValue(string key)
50 | {
51 | if (RuntimeHelper.IsMSIX)
52 | {
53 | if (ApplicationData.Current.LocalSettings.Values.TryGetValue(key, out var obj))
54 | {
55 | return Json.Deserialize(obj.ToString());
56 | }
57 | }
58 | else
59 | {
60 | Initialize();
61 |
62 | if (_settings == null || !_settings.TryGetValue(key, out var obj)) return default;
63 |
64 | if (obj is JsonElement jElem)
65 | {
66 | return jElem.Deserialize();
67 | }
68 |
69 | return (T)obj;
70 | }
71 |
72 | return default;
73 | }
74 |
75 | public void SetValue(string key, T value)
76 | {
77 | if (RuntimeHelper.IsMSIX)
78 | {
79 | ApplicationData.Current.LocalSettings.Values[key] = Json.Serialize(value);
80 | }
81 | else
82 | {
83 | Initialize();
84 |
85 | _settings[key] = value;
86 |
87 | _fileService.Save(_applicationDataFolder, SettingFileName, _settings);
88 | }
89 | }
90 |
91 | public async Task GetValueAsync(string key)
92 | {
93 | if (RuntimeHelper.IsMSIX)
94 | {
95 | if (ApplicationData.Current.LocalSettings.Values.TryGetValue(key, out var obj))
96 | {
97 | return await Json.DeserializeAsync(obj.ToString());
98 | }
99 | }
100 | else
101 | {
102 | await InitializeAsync();
103 |
104 | if (_settings == null || !_settings.TryGetValue(key, out var obj)) return default;
105 |
106 | if (obj is JsonElement jElem)
107 | {
108 | return jElem.Deserialize();
109 | }
110 |
111 | return (T)obj;
112 | }
113 |
114 | return default;
115 | }
116 |
117 | public async Task SetValueAsync(string key, T value)
118 | {
119 | if (RuntimeHelper.IsMSIX)
120 | {
121 | ApplicationData.Current.LocalSettings.Values[key] = await Json.SerializeAsync(value);
122 | }
123 | else
124 | {
125 | await InitializeAsync();
126 |
127 | _settings[key] = value;
128 |
129 | await Task.Run(() => _fileService.Save(_applicationDataFolder, SettingFileName, _settings));
130 | }
131 | }
132 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/Settings/UiSettingsService.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Core;
2 |
3 | namespace DbToys.Services.Settings;
4 |
5 | public class UiSettingsService : SettingsServiceBase
6 | {
7 | public override string SettingFileName { get; set; } = Constants.LocalSettings.UiSettingsFileName;
8 |
9 | public string CodeGeneratorTemplateProject
10 | {
11 | get => GetValue(nameof(CodeGeneratorTemplateProject));
12 | set => SetValue(nameof(CodeGeneratorTemplateProject), value);
13 | }
14 |
15 | public string CodeGeneratorOutputPath
16 | {
17 | get => GetValue(nameof(CodeGeneratorOutputPath));
18 | set => SetValue(nameof(CodeGeneratorOutputPath), value);
19 | }
20 |
21 | public UiSettingsService(IFileService fileService) : base(fileService) { }
22 |
23 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Services/ThemeSelectorService.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Helpers;
2 | using DbToys.Services.Settings;
3 | using Microsoft.UI.Xaml;
4 |
5 | namespace DbToys.Services;
6 |
7 | public class ThemeSelectorService : IThemeSelectorService
8 | {
9 | private const string SettingsKey = "AppBackgroundRequestedTheme";
10 |
11 | public ElementTheme Theme { get; set; } = ElementTheme.Default;
12 |
13 | private readonly GeneralSettingsService _settingsService;
14 |
15 | public ThemeSelectorService(GeneralSettingsService settingsService)
16 | {
17 | _settingsService = settingsService;
18 | }
19 |
20 | public async Task InitializeAsync()
21 | {
22 | Theme = await LoadThemeFromSettingsAsync();
23 | await Task.CompletedTask;
24 | }
25 |
26 | public async Task SetThemeAsync(ElementTheme theme)
27 | {
28 | Theme = theme;
29 |
30 | await SetRequestedThemeAsync();
31 | await SaveThemeInSettingsAsync(Theme);
32 | }
33 |
34 | public async Task SetRequestedThemeAsync()
35 | {
36 | if (App.MainWindow.Content is FrameworkElement rootElement)
37 | {
38 | rootElement.RequestedTheme = Theme;
39 |
40 | TitleBarHelper.UpdateTitleBar(Theme);
41 | }
42 |
43 | await Task.CompletedTask;
44 | }
45 |
46 | private async Task LoadThemeFromSettingsAsync()
47 | {
48 | var themeName = await _settingsService.GetValueAsync(SettingsKey);
49 |
50 | if (Enum.TryParse(themeName, out ElementTheme cacheTheme))
51 | {
52 | return cacheTheme;
53 | }
54 |
55 | return ElementTheme.Default;
56 | }
57 |
58 | private async Task SaveThemeInSettingsAsync(ElementTheme theme)
59 | {
60 | await _settingsService.SetValueAsync(SettingsKey, theme.ToString());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Styles/Colors.xaml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 | #1677ff
10 | #52c41a
11 | #13c2c2
12 | #faad14
13 | #f5222d
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | #FF333333
24 | #FF444444
25 | #FF555555
26 | #FFDDDDDD
27 | #FFF0F0F0
28 |
30 |
32 |
34 |
36 |
38 |
39 |
40 | #FFF0F0F0
41 | #FFDDDDDD
42 | #FF555555
43 | #FF444444
44 | #FF333333
45 |
47 |
49 |
51 |
53 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Styles/FontSizes.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 | 24
6 |
7 | 16
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Styles/TextBlock.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
12 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Styles/Thickness.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 | 0,36,0,0
6 | 0,36,0,36
7 |
8 | 0,24,0,0
9 | 0,24,0,24
10 | 24,0,24,0
11 | 0,0,0,24
12 |
13 | 12,0,0,0
14 | 12,0,12,0
15 | 0,12,0,0
16 | 0,0,12,0
17 | 0,12,0,12
18 |
19 | 8,0,0,0
20 | 0,0,8,0
21 | 0,8,0,0
22 | 8,8,8,8
23 |
24 | 4,0,0,0
25 | 0,0,4,0
26 | 0,4,0,0
27 | 4,4,4,4
28 |
29 | 1,1,0,0
30 | 8,0,0,0
31 | 0,48,0,0
32 | 24,24,0,0
33 | 16,16,24,0
34 |
35 | 36,24,36,0
36 |
37 | -12,4,0,0
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/TemplateStudio.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Usings.cs:
--------------------------------------------------------------------------------
1 | global using WinUIEx;
2 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/CodeTemplate/ActionArgs.cs:
--------------------------------------------------------------------------------
1 | using Windows.Storage;
2 |
3 | namespace DbToys.ViewModels.CodeTemplate;
4 |
5 | public record RenamedArgs(string OldName, string NewName, string OldPath, string NewPath);
6 |
7 | public record ProjectDeletedArg(string FolderName, string FolderPath);
8 |
9 | public record ProjectCreatedArg(StorageFolder Folder);
10 |
11 | public record TemplateCreatedArg(StorageFile File);
12 |
13 | public record TemplateDeletedArg(string FileName, string FilePath, string FolderName, string FolderPath);
14 |
15 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/CodeTemplate/TemplateFileItem.cs:
--------------------------------------------------------------------------------
1 | using Windows.Storage;
2 | using Windows.Storage.FileProperties;
3 | using CommunityToolkit.Mvvm.Input;
4 | using DbToys.Core;
5 | using DbToys.Helpers;
6 | using DbToys.Services;
7 | using Microsoft.UI.Xaml.Controls;
8 | using Microsoft.UI.Xaml.Media;
9 | using Microsoft.UI.Xaml.Media.Imaging;
10 |
11 | namespace DbToys.ViewModels.CodeTemplate;
12 |
13 | public class TemplateFileItem : TreeItem
14 | {
15 | private readonly Lazy _notificationService = new(App.GetService);
16 |
17 | private ImageSource _icon;
18 | public ImageSource Icon { get => _icon; set => SetProperty(ref _icon, value); }
19 |
20 | public StorageFile File { get; set; }
21 |
22 | public StorageFolder Folder { get; set; }
23 |
24 | public string TabDisplayName => $"{Folder.Name}\\{File.Name}";
25 |
26 | public Action RenamedAction { get; set; }
27 |
28 | public Action DeletedAction { get; set; }
29 |
30 | public IAsyncRelayCommand RenameCommand { get; set; }
31 |
32 | public IAsyncRelayCommand DeleteCommand { get; set; }
33 |
34 | public TemplateFileItem(StorageFile file, StorageFolder folder) : base(file.Name)
35 | {
36 | File = file;
37 | Folder = folder;
38 | RenameCommand = new AsyncRelayCommand(RenameAsync);
39 | DeleteCommand = new AsyncRelayCommand(DeleteAsync);
40 | LoadIcon();
41 | }
42 |
43 | private async Task DeleteAsync()
44 | {
45 | var dialog = DialogFactory.GetFor_DeleteTemplateConfirmDialog();
46 | await dialog.ShowAsync();
47 | if (dialog.ViewModel.DialogResult != ContentDialogResult.Primary)
48 | return;
49 |
50 | await File.DeleteAsync();
51 | DeletedAction?.Invoke(new TemplateDeletedArg(File.Name, File.Path, Folder.Name, Folder.Path));
52 | }
53 |
54 | private async Task RenameAsync()
55 | {
56 | var oldName = File.Name;
57 | var oldPath = File.Path;
58 | string input;
59 |
60 | var templateFileExtension = Constants.FileSystem.CodeTemplateFileExtension;
61 |
62 | if (oldName.EndsWith(templateFileExtension))
63 | {
64 | input = oldName
65 | .Remove(oldName.Length - templateFileExtension.Length, templateFileExtension.Length);
66 | }
67 | else
68 | {
69 | input = oldName;
70 | }
71 | var dialog = DialogFactory.GetFor_RenameDialog(input);
72 | await dialog.ShowAsync();
73 |
74 | string newName;
75 | if (dialog.ViewModel.DialogResult == ContentDialogResult.Primary)
76 | {
77 | input = (string)dialog.ViewModel.AdditionalData;
78 | if (input.EndsWith(Constants.FileSystem.CodeTemplateFileExtension))
79 | {
80 | newName = input;
81 | }
82 | else
83 | {
84 | newName = input + Constants.FileSystem.CodeTemplateFileExtension;
85 | }
86 | }
87 | else return;
88 |
89 | if (string.IsNullOrEmpty(newName) || oldName == newName) return;
90 | try
91 | {
92 | await File.RenameAsync(newName, NameCollisionOption.FailIfExists);
93 | // newName = File.Name; // Unique name may be generated
94 | }
95 | catch (Exception ex)
96 | {
97 | _notificationService.Value.Error($"Rename template file failed with error: {ex.Message}");
98 | return;
99 | }
100 | RenamedAction?.Invoke(new RenamedArgs(oldName, newName, oldPath, File.Path));
101 | }
102 |
103 | public async void LoadIcon()
104 | {
105 | var thumbnail = await File.GetThumbnailAsync(ThumbnailMode.ListView, 32, ThumbnailOptions.UseCurrentScale);
106 | var img = new BitmapImage();
107 | img.SetSource(thumbnail);
108 | Icon = img;
109 | }
110 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/CodeTemplate/TemplateViewModel.cs:
--------------------------------------------------------------------------------
1 | using Windows.Storage;
2 | using Windows.Storage.Streams;
3 | using CommunityToolkit.Mvvm.ComponentModel;
4 | using DbToys.Services;
5 |
6 | namespace DbToys.ViewModels.CodeTemplate;
7 |
8 | public class TemplateViewModel : ObservableObject
9 | {
10 | public StorageFile File { get; set; }
11 |
12 | private readonly Lazy _notificationService = new(App.GetService);
13 |
14 | public async Task ReadTextAsync()
15 | {
16 | if (File == null) return string.Empty;
17 | return await FileIO.ReadTextAsync(File, UnicodeEncoding.Utf8);
18 | }
19 |
20 | public async void SaveText(string text)
21 | {
22 | try
23 | {
24 | await FileIO.WriteTextAsync(File, text);
25 | }
26 | catch (Exception ex)
27 | {
28 | _notificationService.Value.Error($"Save file failed: {ex.Message}");
29 | return;
30 | }
31 | _notificationService.Value.Success("File saved");
32 | }
33 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/CodeTemplateExplorerViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using System.ComponentModel;
3 | using System.Diagnostics;
4 | using Windows.Storage;
5 | using CommunityToolkit.Mvvm.ComponentModel;
6 | using CommunityToolkit.Mvvm.Input;
7 | using DbToys.Helpers;
8 | using DbToys.Services;
9 | using DbToys.ViewModels.CodeTemplate;
10 | using Microsoft.UI.Xaml.Controls;
11 |
12 | namespace DbToys.ViewModels;
13 |
14 | public class CodeTemplateExplorerViewModel : ObservableRecipient
15 | {
16 | private object _selectedItem;
17 | public object SelectedItem
18 | {
19 | get => _selectedItem;
20 | set => SetProperty(ref _selectedItem, value);
21 | }
22 |
23 | public ObservableCollection TreeItems = new();
24 |
25 | private readonly INotificationService _notificationService;
26 | private readonly CodeTemplateStorageService _templateStorageService;
27 |
28 | public IRelayCommand ReloadCommand { get; set; }
29 | public IAsyncRelayCommand CreateProjectCommand { get; set; }
30 | public IRelayCommand ExplorerCommand { get; set; }
31 |
32 | public Action ReloadAction { get; set; }
33 |
34 | public Action ProjectCreatedAction { get; set; }
35 |
36 | public CodeTemplateExplorerViewModel(INotificationService notificationService, CodeTemplateStorageService templateStorageService)
37 | {
38 | _notificationService = notificationService;
39 | _templateStorageService = templateStorageService;
40 | CreateProjectCommand = new AsyncRelayCommand(CreateProjectAsync);
41 | ReloadCommand = new RelayCommand(ReloadProjectTree);
42 | ExplorerCommand = new RelayCommand(ShowInExplorer);
43 | }
44 |
45 | private void ShowInExplorer()
46 | {
47 | try
48 | {
49 | Process.Start("explorer.exe", _templateStorageService.TemplateFolderPath);
50 | }
51 | catch (Win32Exception win32Exception)
52 | {
53 | _notificationService.Error(win32Exception.Message);
54 | }
55 | }
56 |
57 | private async Task CreateProjectAsync()
58 | {
59 | var dialog = DialogFactory.GetFor_CreateProjectDialog();
60 | await dialog.ShowAsync();
61 | string folderName;
62 | if (dialog.ViewModel.DialogResult == ContentDialogResult.Primary)
63 | {
64 | folderName = (string)dialog.ViewModel.AdditionalData;
65 | }
66 | else return;
67 |
68 | if (string.IsNullOrEmpty(folderName)) return;
69 | StorageFolder folder;
70 | try
71 | {
72 | folder = await _templateStorageService.CreateProjectFolder(folderName);
73 | }
74 | catch (Exception ex)
75 | {
76 | _notificationService.Error($"Create project folder failed with error: {ex.Message}");
77 | return;
78 | }
79 | if(folder == null ) return;
80 | ProjectCreatedAction?.Invoke(new ProjectCreatedArg(folder));
81 | }
82 |
83 | public void ReloadProjectTree()
84 | {
85 | ReloadAction?.Invoke();
86 | }
87 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/Database/ConnectionItem.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Core.Database;
2 |
3 | namespace DbToys.ViewModels.Database;
4 |
5 | public class ConnectionItem : TreeItem
6 | {
7 | private DatabaseType _databaseType;
8 | public DatabaseType DatabaseType { get => _databaseType; set => SetProperty(ref _databaseType, value); }
9 |
10 | public ConnectionItem(string name, DatabaseType databaseType) : base(name, false)
11 | {
12 | DatabaseType=databaseType;
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/DatabaseViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using CommunityToolkit.Mvvm.ComponentModel;
3 | using CommunityToolkit.Mvvm.Input;
4 | using DbToys.Core.Database;
5 | using DbToys.Services;
6 | using DbToys.ViewModels.Database;
7 | using DbToys.Views.Dialogs;
8 |
9 | namespace DbToys.ViewModels;
10 |
11 | public class DatabaseViewModel : ObservableObject
12 | {
13 | private readonly INotificationService _notificationService;
14 |
15 | public IAsyncRelayCommand ConnectCommand { get; }
16 |
17 | public ISchemaReader SchemaReader { get; private set; }
18 |
19 | private ObservableCollection _connectionItems = new();
20 | public ObservableCollection ConnectionItems
21 | {
22 | get => _connectionItems;
23 | set => SetProperty(ref _connectionItems, value);
24 | }
25 |
26 | private object _selectedItem;
27 | public object SelectedItem
28 | {
29 | get => _selectedItem;
30 | set => SetProperty(ref _selectedItem, value);
31 | }
32 |
33 | public DatabaseViewModel(INotificationService notificationService)
34 | {
35 | _notificationService = notificationService;
36 | ConnectCommand = new AsyncRelayCommand(ConnectDatabase);
37 | }
38 |
39 | private async Task ConnectDatabase(string dbType)
40 | {
41 | if (dbType == "PostgreSql")
42 | {
43 | var dialog = App.GetService();
44 | dialog.XamlRoot = App.MainWindow.Content.XamlRoot;
45 | await dialog.ShowAsync();
46 | if (dialog.ViewModel.SchemaReader != null)
47 | {
48 | SchemaReader = dialog.ViewModel.SchemaReader;
49 | LoadDatabaseTreeNode(SchemaReader, DatabaseType.PostgreSql);
50 | }
51 | }
52 | else if (dbType == "MySql")
53 | {
54 | var dialog = App.GetService();
55 | dialog.XamlRoot = App.MainWindow.Content.XamlRoot;
56 | await dialog.ShowAsync();
57 | if (dialog.ViewModel.SchemaReader != null)
58 | {
59 | SchemaReader = dialog.ViewModel.SchemaReader;
60 | LoadDatabaseTreeNode(SchemaReader, DatabaseType.Mysql);
61 | }
62 | }
63 | else if (dbType == "SqlServer")
64 | {
65 | var dialog = App.GetService();
66 | dialog.XamlRoot = App.MainWindow.Content.XamlRoot;
67 | await dialog.ShowAsync();
68 | if (dialog.ViewModel.SchemaReader != null)
69 | {
70 | SchemaReader = dialog.ViewModel.SchemaReader;
71 | LoadDatabaseTreeNode(SchemaReader, DatabaseType.SqlServer);
72 | }
73 | }
74 | }
75 |
76 | private void LoadDatabaseTreeNode(ISchemaReader schemaReader, DatabaseType dbType)
77 | {
78 | // issue: may case crash https://github.com/microsoft/microsoft-ui-xaml/issues/2121
79 | ConnectionItems.Clear();
80 | var item = new ConnectionItem(schemaReader.GetServerName(), dbType);
81 | try
82 | {
83 | var dbs = schemaReader.ReadDatabases();
84 | foreach (var db in dbs)
85 | {
86 | item.AddChild(new DatabaseItem(db, schemaReader));
87 | }
88 | }
89 | catch (Exception ex)
90 | {
91 | _notificationService.Error(ex.Message, "Read database schema failed");
92 | }
93 | ConnectionItems.Add(item);
94 | item.ExpandPath();
95 | }
96 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/Dialogs/GenerateCodeViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using Windows.Storage;
3 | using Windows.Storage.Pickers;
4 | using CommunityToolkit.Mvvm.ComponentModel;
5 | using CommunityToolkit.Mvvm.Input;
6 | using DbToys.Core;
7 | using DbToys.Helpers;
8 | using DbToys.Services;
9 | using DbToys.Services.Settings;
10 | using Microsoft.UI.Xaml;
11 | using Microsoft.UI.Xaml.Controls;
12 |
13 | namespace DbToys.ViewModels.Dialogs;
14 |
15 | public class GenerateCodeViewModel : ObservableRecipient
16 | {
17 | private readonly CodeTemplateStorageService _storageService;
18 | private readonly UiSettingsService _uiSettingsService;
19 |
20 | public IRelayCommand ConfirmCommand { get; set; }
21 |
22 | private int _selectedProjectIndex;
23 | public int SelectedProjectIndex
24 | {
25 | get => _selectedProjectIndex;
26 | set => SetProperty(ref _selectedProjectIndex, value);
27 | }
28 |
29 | private StorageFolder _templateProjectFolder;
30 | public StorageFolder TemplateProjectFolder
31 | {
32 | get => _templateProjectFolder;
33 | set => SetProperty(ref _templateProjectFolder, value);
34 | }
35 |
36 | public ContentDialogResult DialogResult { get; private set; }
37 |
38 | private string _outputPath;
39 | public string OutputPath { get => _outputPath; set => SetProperty(ref _outputPath, value); }
40 |
41 | public IAsyncRelayCommand PickOutputFolderCommand { get; set; }
42 |
43 | public ObservableCollection ProjectFolders { get; set; } = new();
44 |
45 | public GenerateCodeViewModel(CodeTemplateStorageService storageService, UiSettingsService uiSettingsService)
46 | {
47 | _storageService = storageService;
48 | _uiSettingsService = uiSettingsService;
49 | PickOutputFolderCommand = new AsyncRelayCommand(PickOutputFolder);
50 | ConfirmCommand = new RelayCommand(OnConfirm);
51 | }
52 |
53 | private void OnConfirm()
54 | {
55 | if (_uiSettingsService.CodeGeneratorOutputPath != OutputPath && !string.IsNullOrEmpty(OutputPath))
56 | _uiSettingsService.CodeGeneratorOutputPath = OutputPath;
57 |
58 | if (TemplateProjectFolder != null &&
59 | _uiSettingsService.CodeGeneratorTemplateProject != TemplateProjectFolder.Name)
60 | _uiSettingsService.CodeGeneratorTemplateProject = TemplateProjectFolder.Name;
61 |
62 | DialogResult = ContentDialogResult.Primary;
63 | }
64 |
65 | private async Task PickOutputFolder()
66 | {
67 | var folderPicker = new FolderPicker { SuggestedStartLocation = PickerLocationId.Desktop };
68 |
69 | // When running on win32, FileOpenPicker needs to know the top-level hwnd via IInitializeWithWindow::Initialize.
70 | if (Window.Current == null)
71 | {
72 | WinRT.Interop.InitializeWithWindow.Initialize(folderPicker, Win32Helper.GetActiveWindow());
73 | }
74 |
75 | var outputFolder = await folderPicker.PickSingleFolderAsync();
76 | if (outputFolder != null)
77 | {
78 | OutputPath = outputFolder.Path;
79 | }
80 | }
81 |
82 | protected override async void OnActivated()
83 | {
84 | OutputPath = _uiSettingsService.CodeGeneratorOutputPath;
85 | var folders = await _storageService.GetProjectFoldersAsync();
86 | if (folders is { Count: > 0 })
87 | {
88 | foreach (var storageFolder in folders)
89 | {
90 | if (storageFolder.Name == Constants.CodeTemplate.DefaultGlobalTemplateFolderName) continue;
91 | ProjectFolders.Add(storageFolder);
92 | }
93 |
94 | foreach (var fo in ProjectFolders)
95 | {
96 | if (fo.Name != _uiSettingsService.CodeGeneratorTemplateProject) continue;
97 | TemplateProjectFolder = fo;
98 | break;
99 | }
100 |
101 | if (TemplateProjectFolder == null) TemplateProjectFolder = ProjectFolders[0];
102 | }
103 | }
104 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/Dialogs/IDialog.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using Microsoft.UI.Xaml.Controls;
3 |
4 | namespace DbToys.ViewModels.Dialogs;
5 |
6 | public interface IDialog where TViewModel : class, INotifyPropertyChanged
7 | {
8 | TViewModel ViewModel { get; set; }
9 |
10 | Task ShowAsync();
11 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/Dialogs/TemplateFilenameViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 |
3 | namespace DbToys.ViewModels.Dialogs;
4 |
5 | public class TemplateFilenameViewModel : ObservableObject
6 | {
7 | private string _title;
8 | public string Title { get => _title; set => SetProperty(ref _title, value); }
9 |
10 | private string _filename;
11 | public string Filename { get => _filename; set => SetProperty(ref _filename, value); }
12 |
13 | private bool _canConfirm;
14 | public bool CanConfirm { get => _canConfirm; set => SetProperty(ref _canConfirm, value); }
15 |
16 | public TemplateFilenameViewModel()
17 | {
18 |
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/INavigationAware.cs:
--------------------------------------------------------------------------------
1 | namespace DbToys.ViewModels;
2 |
3 | public interface INavigationAware
4 | {
5 | void OnNavigatedTo(object parameter);
6 |
7 | void OnNavigatedFrom();
8 | }
9 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/LogViewModel.cs:
--------------------------------------------------------------------------------
1 | using Windows.Storage;
2 | using Windows.Storage.Search;
3 | using CommunityToolkit.Mvvm.ComponentModel;
4 | using DbToys.Core.Log;
5 |
6 | namespace DbToys.ViewModels;
7 |
8 | public class LogViewModel : ObservableRecipient, INavigationAware
9 | {
10 | private string _message;
11 | public string Message { get => _message; set => SetProperty(ref _message, value); }
12 |
13 | private StorageFolder _folder;
14 |
15 | //public IAsyncRelayCommand ReadLogCommand { get; set; }
16 |
17 | public LogViewModel()
18 | {
19 | // ReadLogCommand = new AsyncRelayCommand(ReadLogAsync);
20 | }
21 |
22 | protected override void OnActivated()
23 | {
24 |
25 | }
26 |
27 | public async void ReadLogAsync()
28 | {
29 | try
30 | {
31 | if (_folder == null)
32 | {
33 | _folder = await StorageFolder.GetFolderFromPathAsync(Logger.ApplicationLogPath);
34 | }
35 |
36 | if (_folder == null) return;
37 | var files = await _folder.GetFilesAsync(CommonFileQuery.OrderByName);
38 | if (files == null || files.Count == 0) return;
39 | var logFile = files.Last();
40 | Message = await FileIO.ReadTextAsync(logFile);
41 | }
42 | catch (Exception ex)
43 | {
44 | Logger.Error(ex.Message, ex);
45 | }
46 | }
47 |
48 | public void OnNavigatedTo(object parameter)
49 | {
50 | ReadLogAsync();
51 | }
52 |
53 | public void OnNavigatedFrom()
54 | {
55 | }
56 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/MainViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 |
3 | namespace DbToys.ViewModels;
4 |
5 | public class MainViewModel : ObservableRecipient
6 | {
7 | public MainViewModel()
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/ShellViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using DbToys.Services;
3 | using DbToys.Views;
4 | using Microsoft.UI.Xaml.Navigation;
5 |
6 | namespace DbToys.ViewModels;
7 |
8 | public class ShellViewModel : ObservableRecipient
9 | {
10 | private bool _isBackEnabled;
11 | private object _selected;
12 |
13 | public INavigationService NavigationService
14 | {
15 | get;
16 | }
17 |
18 | public INavigationViewService NavigationViewService
19 | {
20 | get;
21 | }
22 |
23 | public bool IsBackEnabled
24 | {
25 | get => _isBackEnabled;
26 | set => SetProperty(ref _isBackEnabled, value);
27 | }
28 |
29 | public object Selected
30 | {
31 | get => _selected;
32 | set => SetProperty(ref _selected, value);
33 | }
34 |
35 | public ShellViewModel(INavigationService navigationService, INavigationViewService navigationViewService)
36 | {
37 | NavigationService = navigationService;
38 | NavigationService.Navigated += OnNavigated;
39 | NavigationViewService = navigationViewService;
40 | }
41 |
42 | private void OnNavigated(object sender, NavigationEventArgs e)
43 | {
44 | IsBackEnabled = NavigationService.CanGoBack;
45 |
46 | if (e.SourcePageType == typeof(SettingsPage))
47 | {
48 | Selected = NavigationViewService.SettingsItem;
49 | return;
50 | }
51 |
52 | var selectedItem = NavigationViewService.GetSelectedItem(e.SourcePageType);
53 | if (selectedItem != null)
54 | {
55 | Selected = selectedItem;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/TableDetailViewModel.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using System.Collections.ObjectModel;
3 | using System.Data;
4 | using DbToys.Core.Database;
5 | using DbToys.Services;
6 | using Microsoft.UI.Dispatching;
7 |
8 | namespace DbToys.ViewModels;
9 |
10 | public class TableDetailViewModel : ObservableRecipient
11 | {
12 | public Table SelectedTable { get; set; }
13 |
14 | public ObservableCollection TableResultSet { get; set; } = new();
15 |
16 | public ObservableCollection TableColumns { get; set; } = new();
17 |
18 | public ISchemaReader SchemaReader { get; set; }
19 |
20 | public Action OnResultSetLoaded;
21 |
22 | private readonly INotificationService _notificationService;
23 |
24 | public TableDetailViewModel(INotificationService notificationService)
25 | {
26 | _notificationService = notificationService;
27 | }
28 |
29 | protected override void OnActivated()
30 | {
31 | base.OnActivated();
32 | InitData();
33 | }
34 |
35 | protected override void OnDeactivated()
36 | {
37 | base.OnDeactivated();
38 | TableResultSet = null;
39 | SchemaReader = null;
40 | TableColumns = null;
41 | SelectedTable = null;
42 | OnResultSetLoaded = null;
43 | }
44 |
45 | private void InitData()
46 | {
47 | var table = SelectedTable;
48 | if (table == null) return;
49 |
50 | var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
51 | Task.Run(() =>
52 | {
53 | List columns = null;
54 | DataTable resultSet = null;
55 | try
56 | {
57 | columns = SchemaReader?.ReadColumns(table.Database, table.Schema,
58 | table.Name);
59 | var firstPk = columns?.FirstOrDefault(t => t.IsPk);
60 | var sort = firstPk == null ? null : firstPk.Name + " desc";
61 | resultSet = SchemaReader?.GetResultSet(table, 30, sort);
62 | }
63 | catch (Exception ex)
64 | {
65 | dispatcherQueue.TryEnqueue(() =>
66 | {
67 | _notificationService.Error(ex.Message, "Read column info failed");
68 | });
69 | }
70 |
71 | dispatcherQueue.TryEnqueue(() =>
72 | {
73 | TableColumns.Clear();
74 | TableResultSet?.Clear();
75 | columns?.ForEach(item => { TableColumns.Add(item); });
76 | if (resultSet != null)
77 | {
78 | OnResultSetLoaded(resultSet.Columns);
79 | foreach (DataRow row in resultSet.Rows)
80 | {
81 | TableResultSet?.Add(row.ItemArray);
82 | }
83 | }
84 | });
85 | });
86 | }
87 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/ViewModels/TreeItem.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using CommunityToolkit.Mvvm.ComponentModel;
3 |
4 | namespace DbToys.ViewModels;
5 |
6 |
7 | public class TreeItem : ObservableRecipient
8 | {
9 | private string _name;
10 | public string Name
11 | {
12 | get => _name;
13 | set => SetProperty(ref _name, value);
14 | }
15 |
16 | public ObservableCollection Children { get; set; }
17 |
18 | private bool _isExpanded;
19 | public bool IsExpanded
20 | {
21 | get => _isExpanded;
22 | set
23 | {
24 | SetProperty(ref _isExpanded, value);
25 | // Lazy load the child items, if necessary.
26 | if (_isExpanded && HasUnrealizedChildren && Children.Count == 0)
27 | {
28 | LoadChildren();
29 | }
30 | }
31 | }
32 |
33 | protected virtual void LoadChildren()
34 | {
35 | }
36 |
37 | private bool _isSelected;
38 | public bool IsSelected
39 | {
40 | get => _isSelected;
41 | set => SetProperty(ref _isSelected, value);
42 | }
43 |
44 | private bool _hasUnrealizedChildren;
45 | public bool HasUnrealizedChildren
46 | {
47 | get => _hasUnrealizedChildren;
48 | set => SetProperty(ref _hasUnrealizedChildren, value);
49 | }
50 |
51 | private TreeItem _parent;
52 |
53 | protected TreeItem(string name, bool lazyLoadChildren)
54 | {
55 | _name = name;
56 | Children = new ObservableCollection();
57 | if (lazyLoadChildren) _hasUnrealizedChildren = true;
58 | }
59 |
60 | protected TreeItem(string name)
61 |
62 | {
63 | _name = name;
64 | }
65 |
66 | public void AddChild(TreeItem child)
67 | {
68 | child._parent = this;
69 | Children!.Add(child);
70 | }
71 |
72 | public void ExpandPath()
73 | {
74 | IsExpanded = true;
75 | _parent?.ExpandPath();
76 | }
77 |
78 | public void CollapsePath()
79 | {
80 | IsExpanded = false;
81 | _parent?.CollapsePath();
82 | }
83 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/CodeTemplate/TemplatePage.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/DynamicDialog.xaml:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
39 |
40 |
41 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/DynamicDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Helpers;
2 | using DbToys.ViewModels.Dialogs;
3 | using Microsoft.UI.Xaml.Controls;
4 |
5 | namespace DbToys.Views.Dialogs;
6 |
7 | public sealed partial class DynamicDialog
8 | {
9 | public DynamicDialog(DynamicDialogViewModel vm)
10 | {
11 | ViewModel = vm;
12 | InitializeComponent();
13 | ViewModel.HideDialog = Hide;
14 | }
15 |
16 | public DynamicDialogViewModel ViewModel { get; set; }
17 |
18 | public new Task ShowAsync() => DialogHelper.SetContentDialogRoot(this).ShowAsync().AsTask();
19 |
20 | private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
21 | {
22 | ViewModel.PrimaryButtonCommand.Execute(args);
23 | }
24 |
25 | private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
26 | {
27 | ViewModel.SecondaryButtonCommand.Execute(args);
28 | }
29 |
30 | private void ContentDialog_CloseButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
31 | {
32 | ViewModel.CloseButtonCommand.Execute(args);
33 | }
34 |
35 | private void ContentDialog_KeyDown(object sender, Microsoft.UI.Xaml.Input.KeyRoutedEventArgs e)
36 | {
37 | ViewModel.KeyDownCommand.Execute(e);
38 | }
39 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/GenerateCodeDialog.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/GenerateCodeDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.Helpers;
2 | using DbToys.ViewModels.Dialogs;
3 | using Microsoft.UI.Xaml.Controls;
4 |
5 | namespace DbToys.Views.Dialogs
6 | {
7 | public sealed partial class GenerateCodeDialog
8 | {
9 | public GenerateCodeViewModel ViewModel { get; set; }
10 |
11 | public GenerateCodeDialog()
12 | {
13 | ViewModel = App.GetService();
14 | ViewModel.IsActive = true;
15 | InitializeComponent();
16 | }
17 |
18 | public new Task ShowAsync() => DialogHelper.SetContentDialogRoot(this).ShowAsync().AsTask();
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/MysqlConnectDialog.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
41 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/MysqlConnectDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.ViewModels.Dialogs;
2 | using Microsoft.UI.Xaml;
3 | using Microsoft.UI.Xaml.Controls;
4 |
5 | namespace DbToys.Views.Dialogs;
6 |
7 | public sealed partial class MysqlConnectDialog
8 | {
9 | public MysqlConnectViewModel ViewModel { get; }
10 | public MysqlConnectDialog()
11 | {
12 | ViewModel = App.GetService();
13 | ViewModel.IsActive = true;
14 | ViewModel.PasswordChanged += s => { PasswordBox!.Password = s; };
15 | InitializeComponent();
16 | }
17 | private void PasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e)
18 | {
19 | ViewModel.Password = ((PasswordBox)sender).Password;
20 | }
21 |
22 | private void OnClosed(ContentDialog sender, ContentDialogClosedEventArgs args)
23 | {
24 | ViewModel.IsActive = false;
25 | }
26 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/PostgreSqlConnectDialog.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
41 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/PostgreSqlConnectDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.ViewModels.Dialogs;
2 | using Microsoft.UI.Xaml;
3 | using Microsoft.UI.Xaml.Controls;
4 |
5 | namespace DbToys.Views.Dialogs;
6 |
7 | public sealed partial class PostgreSqlConnectDialog : ContentDialog
8 | {
9 | public PostgreSqlConnectViewModel ViewModel { get; }
10 |
11 | public PostgreSqlConnectDialog()
12 | {
13 | ViewModel = App.GetService();
14 | ViewModel.IsActive = true;
15 | ViewModel.PasswordChanged += s =>
16 | {
17 | PasswordBox!.Password = s;
18 | };
19 | InitializeComponent();
20 | }
21 |
22 | private void PasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e)
23 | {
24 | ViewModel.Password = ((PasswordBox)sender).Password;
25 | }
26 |
27 | private void OnClosed(ContentDialog sender, ContentDialogClosedEventArgs args)
28 | {
29 | ViewModel.IsActive = false;
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/SqlServerConnectDialog.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
29 |
30 |
31 |
32 |
34 |
35 |
36 |
37 |
39 |
40 |
41 |
42 |
43 |
44 |
46 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/SqlServerConnectDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.ViewModels.Dialogs;
2 | using Microsoft.UI.Xaml;
3 | using Microsoft.UI.Xaml.Controls;
4 |
5 | namespace DbToys.Views.Dialogs;
6 |
7 | public sealed partial class SqlServerConnectDialog
8 | {
9 | public SqlServerConnectViewModel ViewModel { get; }
10 | public SqlServerConnectDialog()
11 | {
12 | ViewModel = App.GetService();
13 | ViewModel.IsActive = true;
14 | ViewModel.PasswordChanged += s => { PasswordBox!.Password = s; };
15 | InitializeComponent();
16 | }
17 |
18 | private void PasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e)
19 | {
20 | ViewModel.Password = ((PasswordBox)sender).Password;
21 | }
22 |
23 | private void OnClosed(ContentDialog sender, ContentDialogClosedEventArgs args)
24 | {
25 | ViewModel.IsActive = false;
26 | }
27 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/TemplateFilenameDialog.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
19 |
20 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/Dialogs/TemplateFilenameDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.WinUI;
2 | using DbToys.Helpers;
3 | using DbToys.ViewModels.Dialogs;
4 | using Microsoft.UI.Xaml.Controls;
5 |
6 | namespace DbToys.Views.Dialogs
7 | {
8 | public sealed partial class TemplateFilenameDialog
9 | {
10 | public TemplateFilenameViewModel ViewModel { get; set; }
11 |
12 | public TemplateFilenameDialog()
13 | {
14 | ViewModel = App.GetService();
15 | InitializeComponent();
16 | }
17 |
18 | public new Task ShowAsync() => DialogHelper.SetContentDialogRoot(this).ShowAsync().AsTask();
19 |
20 | private async void FilenameTextBox_OnBeforeTextChanging(TextBox sender, TextBoxBeforeTextChangingEventArgs args)
21 | {
22 | if (!FileSystemHelper.ContainsRestrictedCharacters(args.NewText)) return;
23 |
24 | args.Cancel = true;
25 | await sender.DispatcherQueue.EnqueueAsync(() =>
26 | {
27 | var oldSelection = sender.SelectionStart + sender.SelectionLength;
28 | var oldText = sender.Text;
29 | sender.Text = FileSystemHelper.FilterRestrictedCharacters(args.NewText);
30 | sender.SelectionStart = oldSelection + sender.Text.Length - oldText.Length;
31 | });
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/LogPage.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
16 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/LogPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.ViewModels;
2 | using Microsoft.UI.Xaml.Controls;
3 |
4 | namespace DbToys.Views;
5 |
6 | public sealed partial class LogPage : Page
7 | {
8 | public LogViewModel ViewModel { get; }
9 |
10 | public LogPage()
11 | {
12 | ViewModel = App.GetService();
13 | InitializeComponent();
14 | }
15 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.ViewModels;
2 | using Microsoft.UI.Xaml.Controls;
3 |
4 | namespace DbToys.Views;
5 |
6 | public sealed partial class MainPage : Page
7 | {
8 | public MainViewModel ViewModel
9 | {
10 | get;
11 | }
12 |
13 | public MainPage()
14 | {
15 | ViewModel = App.GetService();
16 | InitializeComponent();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/SettingsPage.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
37 |
38 |
39 |
40 |
42 |
43 |
44 |
45 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/SettingsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using DbToys.ViewModels;
2 | using Microsoft.UI.Xaml.Controls;
3 |
4 | namespace DbToys.Views;
5 |
6 | // TODO: Set the URL for your privacy policy by updating SettingsPage_PrivacyTermsLink.NavigateUri in Resources.resw.
7 | public sealed partial class SettingsPage : Page
8 | {
9 | public SettingsViewModel ViewModel
10 | {
11 | get;
12 | }
13 |
14 | public SettingsPage()
15 | {
16 | ViewModel = App.GetService();
17 | InitializeComponent();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/TableDetailPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/Views/TableDetailPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.WinUI.UI.Controls;
2 | using DbToys.ViewModels;
3 | using Microsoft.UI.Xaml;
4 | using Microsoft.UI.Xaml.Controls;
5 | using Microsoft.UI.Xaml.Data;
6 |
7 | namespace DbToys.Views;
8 |
9 | public sealed partial class TableDetailPage : Page
10 | {
11 | public TableDetailViewModel ViewModel { get; }
12 |
13 | public TableDetailPage()
14 | {
15 | InitializeComponent();
16 | ViewModel = App.GetService();
17 |
18 | ViewModel.OnResultSetLoaded += columns =>
19 | {
20 | ResultSetGrid.Columns.Clear();
21 | if (columns == null) return;
22 | for (var i = 0; i < columns.Count; i++)
23 | {
24 | ResultSetGrid.Columns.Add(new DataGridTextColumn
25 | {
26 | Header = columns[i].ColumnName,
27 | Binding = new Binding { Path = new PropertyPath("[" + i + "]") }
28 | });
29 | }
30 | };
31 | }
32 | }
--------------------------------------------------------------------------------
/src/DbToys.WinUI/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/DbToys.WinUI/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | }
3 |
--------------------------------------------------------------------------------