├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md └── SoftFluent.Windows ├── SoftFluent.Windows.Samples ├── AddressListEditorWindow.xaml ├── AddressListEditorWindow.xaml.cs ├── App.xaml ├── App.xaml.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Model.cs ├── Properties │ └── AssemblyInfo.cs ├── SoftFluent.Windows.Samples.csproj └── Utilities.cs ├── SoftFluent.Windows.sln ├── SoftFluent.Windows ├── ActivatorService.cs ├── AutoObject.cs ├── BaseActivator.cs ├── BaseConverter.cs ├── BaseDecamelizer.cs ├── BaseTypeResolver.cs ├── ByteArrayControl.cs ├── ChangeTypeConverter.cs ├── ConversionService.cs ├── DateTimePicker.cs ├── DecamelizationService.cs ├── DecamelizeOptions.cs ├── DecamelizeTextOptions.cs ├── Diagnostics │ └── Tracing.cs ├── EnumerableConverter.cs ├── IActivator.cs ├── IConverter.cs ├── IDecamelizer.cs ├── IPropertyGridCommandHandler.cs ├── IPropertyGridEditor.cs ├── IPropertyGridObject.cs ├── ITypeResolver.cs ├── Properties │ ├── AssemblyInfo.cs │ └── AssemblyVersionInfo.cs ├── PropertyGrid.xaml ├── PropertyGrid.xaml.cs ├── PropertyGridAttribute.cs ├── PropertyGridComboBoxExtension.cs ├── PropertyGridConverter.cs ├── PropertyGridDataProvider.cs ├── PropertyGridDataTemplate.cs ├── PropertyGridDataTemplateSelector.cs ├── PropertyGridEnumProperty.cs ├── PropertyGridEventArgs.cs ├── PropertyGridItem.cs ├── PropertyGridOptionsAttribute.cs ├── PropertyGridProperty.cs ├── PropertyGridWindowManager.cs ├── PropertyGridWindowOptions.cs ├── Resources │ ├── SR.cs │ └── Strings.resx ├── ServiceProvider.cs ├── SoftFluent.Windows.csproj ├── SoftFluent.Windows.snk ├── TypeDataTemplateSelector.cs ├── TypeResolutionService.cs ├── UniversalConverter.cs ├── UniversalConverterCase.cs ├── UniversalConverterInput.cs ├── UniversalConverterOperator.cs ├── UniversalConverterOptions.cs └── Utilities │ ├── DataBindingEvaluator.cs │ ├── DynamicObject.cs │ ├── DynamicObjectProperty.cs │ └── Extensions.cs └── nuget ├── NuGet.exe ├── Publish.bat ├── SoftFluent.Windows.csproj.nuspec └── build.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | *.csproj.DotSettings 44 | 45 | # Build results 46 | 47 | [Dd]ebug/ 48 | [Rr]elease/ 49 | x64/ 50 | build/ 51 | [Bb]in/ 52 | [Oo]bj/ 53 | 54 | # MSTest test Results 55 | [Tt]est[Rr]esult*/ 56 | [Bb]uild[Ll]og.* 57 | 58 | *_i.c 59 | *_p.c 60 | *.ilk 61 | *.meta 62 | *.obj 63 | *.pch 64 | *.pdb 65 | *.pgc 66 | *.pgd 67 | *.rsp 68 | *.sbr 69 | *.tlb 70 | *.tli 71 | *.tlh 72 | *.tmp 73 | *.tmp_proj 74 | *.log 75 | *.vspscc 76 | *.vssscc 77 | .builds 78 | *.pidb 79 | *.log 80 | *.scc 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opensdf 87 | *.sdf 88 | *.cachefile 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | 102 | # TeamCity is a build add-in 103 | _TeamCity* 104 | 105 | # DotCover is a Code Coverage Tool 106 | *.dotCover 107 | 108 | # NCrunch 109 | *.ncrunch* 110 | .*crunch*.local.xml 111 | 112 | # Installshield output folder 113 | [Ee]xpress/ 114 | 115 | # DocProject is a documentation generator add-in 116 | DocProject/buildhelp/ 117 | DocProject/Help/*.HxT 118 | DocProject/Help/*.HxC 119 | DocProject/Help/*.hhc 120 | DocProject/Help/*.hhk 121 | DocProject/Help/*.hhp 122 | DocProject/Help/Html2 123 | DocProject/Help/html 124 | 125 | # Click-Once directory 126 | publish/ 127 | 128 | # Publish Web Output 129 | *.Publish.xml 130 | *.pubxml 131 | *.publishproj 132 | 133 | # NuGet Packages Directory 134 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 135 | #packages/ 136 | 137 | # Windows Azure Build Output 138 | csx 139 | *.build.csdef 140 | 141 | # Windows Store app package directory 142 | AppPackages/ 143 | 144 | # Others 145 | sql/ 146 | *.Cache 147 | ClientBin/ 148 | [Ss]tyle[Cc]op.* 149 | ~$* 150 | *~ 151 | *.dbmdl 152 | *.[Pp]ublish.xml 153 | *.pfx 154 | *.publishsettings 155 | 156 | # RIA/Silverlight projects 157 | Generated_Code/ 158 | 159 | # Backup & report files from converting an old project file to a newer 160 | # Visual Studio version. Backup files are not needed, because we have git ;-) 161 | _UpgradeReport_Files/ 162 | Backup*/ 163 | UpgradeLog*.XML 164 | UpgradeLog*.htm 165 | 166 | # SQL Server files 167 | App_Data/*.mdf 168 | App_Data/*.ldf 169 | 170 | ############# 171 | ## Windows detritus 172 | ############# 173 | 174 | # Windows image file caches 175 | Thumbs.db 176 | ehthumbs.db 177 | 178 | # Folder config file 179 | Desktop.ini 180 | 181 | # Recycle Bin used on file shares 182 | $RECYCLE.BIN/ 183 | 184 | # Mac crap 185 | .DS_Store 186 | 187 | 188 | ############# 189 | ## Python 190 | ############# 191 | 192 | *.py[cod] 193 | 194 | # Packages 195 | *.egg 196 | *.egg-info 197 | dist/ 198 | build/ 199 | eggs/ 200 | parts/ 201 | var/ 202 | sdist/ 203 | develop-eggs/ 204 | .installed.cfg 205 | 206 | # Installer logs 207 | pip-log.txt 208 | 209 | # Unit test / coverage reports 210 | .coverage 211 | .tox 212 | 213 | #Translations 214 | *.mo 215 | 216 | #Mr Developer 217 | .mr.developer.cfg 218 | 219 | # Nuget 220 | SoftFluent.Windows/nuget/lib/ 221 | SoftFluent.Windows/nuget/*.nupkg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 SoftFluent 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository contains useful controls/converter/classes to work with WPF. The current version of the library is also [available on NuGet](https://www.nuget.org/packages/SoftFluent.Windows/). 2 | 3 | # PropertyGrid 4 | 5 | This repository contains a customizable `PropertyGrid` for WPF. 6 | 7 | ![](https://github.com/SoftFluent/SoftFluent.Windows/wiki/Images/Getting-Started-Result.png) 8 | 9 | - Many data types are supported by default: String, Boolean, Date, DateTime, Number, Enum, Multi-Valued Enum, Byte[], Guid, etc., 10 | - Property names are decamelized by default (FirstName => First Name) unless you use the `DisplayNameAttribute`, 11 | - Common attributes are supported: `DisplayNameAttribute`, `CategoryAttribute`, `BrowsableAttribute`, `ReadOnlyAttribute`, 12 | - Customizable: 13 | - `CustomEditor` = `DataTemplate` You can create your own editors to provide a better UX to your user (Slider, Url, Password, etc.) by creating a `DataTemplate` 14 | 15 | ````xaml 16 | 17 | 18 | 19 | 20 | 22 | 23 | ```` 24 | 25 | Go to the [documentation](https://github.com/SoftFluent/SoftFluent.Windows/wiki) 26 | 27 | # AutoObject 28 | 29 | The `AutoObject` class is a light class which implements `INotifyPropertyChanged` and `IDataErrorInfo` so you can easily and quickly create MVVM like classes with data-binding and validation 30 | 31 | # UniversalConverter 32 | 33 | Stop writing boring converters, use the `UniversalConverter`! 34 | 35 | When you create an application using WPF, you often have to write converters to change one value to the desired type. 36 | The .NET Framework already provides some basics converter such as BooleanToVisibilityConverter. 37 | These converters are very specifics and usually not very configurable. 38 | For example you cannot change the visibility from Collapsed to Hidden. 39 | 40 | Let’s see how to use it for a very basic (and to be honest, quite useless) conversion: 41 | 42 | 43 | ````xaml 44 | 45 | 46 | 47 | 48 | 50 | 52 | ```` 53 | In this example, UniversalConverter converts the value to the desired type so string values “true” and “yes” will be converted automatically to the Boolean value “true”. 54 | 55 | With UniversalConverter, you can create a list of cases, like a C# switch. For instance, this is how we would reproduce the boolean to visibility converter behavior using the UniversalConverter: 56 | 57 | ````xaml 58 | 59 | 60 | 61 | 62 | 63 | 64 | ```` 65 | 66 | Like C#, you can use a default value: 67 | 68 | ````xaml 69 | 70 | 71 | 72 | 73 | 74 | ```` 75 | 76 | There are currently these operators available: 77 | 78 | * Equal, 79 | * NotEqual, 80 | * GreaterThan, 81 | * GreaterThanOrEqual, 82 | * LesserThan, 83 | * LesserThanOrEqual, 84 | * Between: minimum and maximum value included => [min:max[, 85 | * StartsWith, 86 | * EndsWith, 87 | * Contains, 88 | * IsType: type match exactly, 89 | * IsOfType: type or direved types, 90 | * JavaScript: Yes, you can use JavaScript to evaluate a condition! 91 | 92 | With some options: 93 | 94 | * StringComparison 95 | * Trim 96 | * Nullify 97 | 98 | Here’s a list of examples using different operators. 99 | 100 | ### Check if a string contains NewLine using JavaScript: 101 | 102 | ````xaml 103 | 104 | 105 | 106 | 107 | 108 | 109 | ```` 110 | 111 | ### Set error message background and foreground color 112 | ````xaml 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | ```` 124 | ### Test if a value is over 21 125 | ````xaml 126 | 127 | 128 | 129 | 130 | 131 | ```` 132 | ### Is teenager 133 | ````xaml 134 | 135 | 136 | 137 | 138 | 139 | ```` 140 | ### Compare types 141 | ````xaml 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | ```` 150 | ### Is empty 151 | ````xaml 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | ```` 161 | -------------------------------------------------------------------------------- /SoftFluent.Windows/SoftFluent.Windows.Samples/AddressListEditorWindow.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 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 | 43 | 44 | 45 |