├── .gitignore ├── LICENSE ├── README.md ├── XamarinControlsLogo.png ├── media ├── Keypad │ ├── KeypadAndroid1.png │ ├── KeypadUWP1.png │ ├── KeypadiOS8.png │ ├── iOSKeypad1.png │ ├── iOSKeypad2.png │ ├── iOSKeypad3.png │ ├── iOSKeypad4.png │ ├── iOSKeypad5.png │ ├── iOSKeypad6.png │ └── iOSKeypad7.png ├── XamarinControlsLogo.png ├── card_android.png ├── card_ios.png ├── checkbox.gif ├── checkbox.jpg ├── droid_checkbox_native.gif ├── ios_checkbox_native.gif ├── nuget.png └── uwp_checked.png └── src ├── Controls ├── CardView.cs ├── Checkbox.cs ├── Controls.csproj └── Keypad.cs ├── Directory.build.props └── IntelliAbb.Xamarin.sln /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | media/.DS_Store 332 | .DS_Store 333 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Xamarin Controls 2 | 3 | 4 | Cross-platform controls for Xamarin and Xamarin.Forms. 5 | 6 | NuGet | 7 | ---| 8 | [![Nuget](https://img.shields.io/nuget/v/IntelliAbb.Xamarin.Controls)](https://www.nuget.org/packages/IntelliAbb.Xamarin.Controls/) 9 | 10 | Release notes: https://github.com/Intelliabb/XamarinControls/wiki/Release-Notes 11 | 12 | Package | Status 13 | ---|--- 14 | Release|[![Build status](https://intelliabb.visualstudio.com/XamarinControls/_apis/build/status/XamarinControls)](https://intelliabb.visualstudio.com/XamarinControls/_build/latest?definitionId=8) 15 | Pre Release|[![Build status](https://intelliabb.visualstudio.com/XamarinControls/_apis/build/status/XamarinControls%20Pre-release)](https://intelliabb.visualstudio.com/XamarinControls/_build/latest?definitionId=7) 16 | CI Builds|[![Build Status](https://intelliabb.visualstudio.com/XamarinControls/_apis/build/status/XamarinControls%20Dev)](https://intelliabb.visualstudio.com/XamarinControls/_build/latest?definitionId=6) 17 | 18 | # Installation Instructions 19 | Add this package to your shared project that holds the control, and each platform project. 20 | 21 | Control | iOS | Android | UWP 22 | ---|---|---|--- 23 | [Checkbox](https://github.com/Intelliabb/XamarinControls/wiki/Checkbox) | || 24 | [CardView](https://github.com/Intelliabb/XamarinControls/wiki/CardView) | || Coming soon 25 | [Keypad](https://github.com/Intelliabb/XamarinControls/wiki/Keypad)| | | 26 | 27 | 28 | # Roadmap 29 | * Repeater View (coming soon) 30 | * Radio button control (coming soon) 31 | 32 | # Contribute 33 | * New controls 34 | * Enhance controls 35 | * Bug fixes 36 | Note: To submit a new idea for a control, please first create an issue so we can approve the change/enhancement before you put in a lot of effort. 37 | 38 | # Feedback 39 | As usual, please provide feedback so we can continue to make better controls that can benefit us all and save us a bunch of time. 40 | * Tweet at [@intelliAbb](www.twitter.com/intelliabb) 41 | 42 | 43 | ##### Copyright 2018 intelliAbb 44 | -------------------------------------------------------------------------------- /XamarinControlsLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/XamarinControlsLogo.png -------------------------------------------------------------------------------- /media/Keypad/KeypadAndroid1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/KeypadAndroid1.png -------------------------------------------------------------------------------- /media/Keypad/KeypadUWP1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/KeypadUWP1.png -------------------------------------------------------------------------------- /media/Keypad/KeypadiOS8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/KeypadiOS8.png -------------------------------------------------------------------------------- /media/Keypad/iOSKeypad1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/iOSKeypad1.png -------------------------------------------------------------------------------- /media/Keypad/iOSKeypad2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/iOSKeypad2.png -------------------------------------------------------------------------------- /media/Keypad/iOSKeypad3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/iOSKeypad3.png -------------------------------------------------------------------------------- /media/Keypad/iOSKeypad4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/iOSKeypad4.png -------------------------------------------------------------------------------- /media/Keypad/iOSKeypad5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/iOSKeypad5.png -------------------------------------------------------------------------------- /media/Keypad/iOSKeypad6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/iOSKeypad6.png -------------------------------------------------------------------------------- /media/Keypad/iOSKeypad7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/Keypad/iOSKeypad7.png -------------------------------------------------------------------------------- /media/XamarinControlsLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/XamarinControlsLogo.png -------------------------------------------------------------------------------- /media/card_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/card_android.png -------------------------------------------------------------------------------- /media/card_ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/card_ios.png -------------------------------------------------------------------------------- /media/checkbox.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/checkbox.gif -------------------------------------------------------------------------------- /media/checkbox.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/checkbox.jpg -------------------------------------------------------------------------------- /media/droid_checkbox_native.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/droid_checkbox_native.gif -------------------------------------------------------------------------------- /media/ios_checkbox_native.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/ios_checkbox_native.gif -------------------------------------------------------------------------------- /media/nuget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/nuget.png -------------------------------------------------------------------------------- /media/uwp_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intelliabb/XamarinControls/82bf781698ce6d714dec1485de45a4addb1a4d1d/media/uwp_checked.png -------------------------------------------------------------------------------- /src/Controls/CardView.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace IntelliAbb.Xamarin.Controls 4 | { 5 | public class CardView : Frame 6 | { 7 | #region Control Templates 8 | readonly ControlTemplate _iconTitleTemplate = new ControlTemplate(typeof(IconTitleTemplate)); 9 | readonly ControlTemplate _titleTemplate = new ControlTemplate(typeof(TitleTemplate)); 10 | #endregion 11 | 12 | public CardView() 13 | { 14 | CornerRadius = 8; 15 | Padding = new Thickness(8); 16 | } 17 | 18 | #region Defaults 19 | static Style DEFAULT_TITLE_STYLE 20 | { 21 | get 22 | { 23 | return new Style(typeof(Label)) 24 | { 25 | Setters = 26 | { 27 | new Setter 28 | { 29 | Property = Label.FontAttributesProperty, Value=FontAttributes.Bold 30 | }, 31 | new Setter 32 | { 33 | Property = Label.FontSizeProperty, Value= 14 34 | }, 35 | new Setter 36 | { 37 | Property = Label.TextColorProperty, Value = Color.Gray 38 | }, 39 | new Setter 40 | { 41 | Property = Label.VerticalTextAlignmentProperty, Value = TextAlignment.Center 42 | } 43 | } 44 | }; 45 | } 46 | } 47 | 48 | static Style DEFAULT_ICON_STYLE 49 | { 50 | get 51 | { 52 | return new Style(typeof(Image)) 53 | { 54 | Setters = 55 | { 56 | new Setter 57 | { 58 | Property = Image.WidthRequestProperty, Value=24 59 | }, 60 | new Setter 61 | { 62 | Property = Image.HeightRequestProperty, Value=24 63 | }, 64 | new Setter 65 | { 66 | Property = Image.AspectProperty, Value=Aspect.AspectFit 67 | } 68 | } 69 | }; 70 | } 71 | } 72 | #endregion 73 | 74 | #region Bindable Properties 75 | public static BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), 76 | typeof(string), 77 | typeof(CardView), 78 | propertyChanged: OnTitleChanged); 79 | 80 | public static BindableProperty IconProperty = BindableProperty.Create(nameof(Icon), 81 | typeof(ImageSource), 82 | typeof(CardView), 83 | propertyChanged: OnTitleChanged); 84 | 85 | public static BindableProperty TitleStyleProperty = BindableProperty.Create(nameof(TitleStyle), 86 | typeof(Style), 87 | typeof(CardView), 88 | DEFAULT_TITLE_STYLE); 89 | 90 | public static BindableProperty IconStyleProperty = BindableProperty.Create(nameof(IconStyle), 91 | typeof(Style), 92 | typeof(CardView), 93 | DEFAULT_ICON_STYLE); 94 | 95 | public string Title 96 | { 97 | get { return (string)GetValue(TitleProperty); } 98 | set { SetValue(TitleProperty, value); } 99 | } 100 | 101 | public Style TitleStyle 102 | { 103 | get { return (Style)GetValue(TitleStyleProperty); } 104 | set { SetValue(TitleStyleProperty, value); } 105 | } 106 | 107 | public ImageSource Icon 108 | { 109 | get { return (ImageSource)GetValue(IconProperty); } 110 | set { SetValue(IconProperty, value); } 111 | } 112 | 113 | public Style IconStyle 114 | { 115 | get { return (Style)GetValue(IconStyleProperty); } 116 | set { SetValue(IconStyleProperty, value); } 117 | } 118 | 119 | private static void OnTitleChanged(BindableObject bindable, object oldValue, object newValue) 120 | { 121 | if (!(bindable is CardView card)) return; 122 | card.ControlTemplate = card.Icon != null ? card._iconTitleTemplate : card._titleTemplate; 123 | } 124 | #endregion 125 | } 126 | 127 | /// 128 | /// Control template for Icon and Title. 129 | /// 130 | public class IconTitleTemplate : ContentView 131 | { 132 | public IconTitleTemplate() 133 | { 134 | var titleLabel = new Label(); 135 | titleLabel.SetBinding(Label.TextProperty, new TemplateBinding("Title")); 136 | titleLabel.SetBinding(Label.StyleProperty, new TemplateBinding("TitleStyle")); 137 | 138 | Image icon = new Image(); 139 | icon.SetBinding(Image.SourceProperty, new TemplateBinding("Icon")); 140 | icon.SetBinding(Image.StyleProperty, new TemplateBinding("IconStyle")); 141 | 142 | Content = new StackLayout 143 | { 144 | Children = 145 | { 146 | new StackLayout 147 | { 148 | Orientation = StackOrientation.Horizontal, 149 | Children = 150 | { 151 | icon, 152 | titleLabel 153 | } 154 | }, 155 | new ContentPresenter(), 156 | } 157 | }; 158 | } 159 | } 160 | 161 | /// 162 | /// Control template for Title only. 163 | /// 164 | public class TitleTemplate : ContentView 165 | { 166 | public TitleTemplate() 167 | { 168 | var titleLabel = new Label(); 169 | titleLabel.SetBinding(Label.TextProperty, new TemplateBinding("Title")); 170 | titleLabel.SetBinding(Label.StyleProperty, new TemplateBinding("TitleStyle")); 171 | 172 | Content = new StackLayout 173 | { 174 | Children = 175 | { 176 | titleLabel, 177 | new ContentPresenter(), 178 | } 179 | }; 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/Controls/Checkbox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xamarin.Forms; 4 | using SkiaSharp.Views.Forms; 5 | using SkiaSharp; 6 | using System.ComponentModel; 7 | using System.Windows.Input; 8 | using System.Threading.Tasks; 9 | 10 | namespace IntelliAbb.Xamarin.Controls 11 | { 12 | /// 13 | /// This is a cross-platform checkbox control. 14 | /// 15 | [Browsable(true)] 16 | public class Checkbox : ContentView, IDisposable 17 | { 18 | #region Fields 19 | 20 | bool _isAnimating; 21 | SKCanvasView _skiaView; 22 | ICommand _toggleCommand; 23 | 24 | #endregion 25 | 26 | #region Constructor 27 | 28 | public Checkbox() 29 | { 30 | InitializeCanvas(); 31 | WidthRequest = HeightRequest = DEFAULT_SIZE; 32 | HorizontalOptions = VerticalOptions = new LayoutOptions(LayoutAlignment.Center, false); 33 | Content = _skiaView; 34 | GestureRecognizers.Add(new TapGestureRecognizer 35 | { 36 | Command = _toggleCommand 37 | }); 38 | } 39 | 40 | #endregion 41 | 42 | #region Defaults 43 | 44 | static Design DEFAULT_DESIGN => Design.Unified; 45 | 46 | static Shape DEFAULT_SHAPE { 47 | get 48 | { 49 | Shape shape; 50 | 51 | switch (Device.RuntimePlatform) 52 | { 53 | case Device.Android: 54 | case Device.UWP: 55 | shape = Shape.Rectangle; 56 | break; 57 | 58 | case Device.iOS: 59 | default: 60 | shape = Shape.Circle; 61 | break; 62 | } 63 | return shape; 64 | } 65 | } 66 | 67 | static float DEFAULT_OUTLINE_WIDTH { 68 | get { 69 | float retVal; 70 | 71 | switch (Device.RuntimePlatform) 72 | { 73 | case Device.iOS: 74 | retVal = 4.0f; 75 | break; 76 | case Device.UWP: 77 | retVal = 2.5f; 78 | break; 79 | case Device.Android: 80 | default: 81 | retVal = 6.0f; 82 | break; 83 | } 84 | return retVal; 85 | } 86 | } 87 | 88 | static double DEFAULT_SIZE { 89 | get { 90 | double retVal; 91 | switch(Device.RuntimePlatform) 92 | { 93 | case Device.UWP: 94 | retVal = 20.0; 95 | break; 96 | case Device.iOS: 97 | case Device.Android: 98 | default: 99 | retVal = 24.0; 100 | break; 101 | } 102 | return retVal; 103 | } 104 | } 105 | 106 | #endregion 107 | 108 | #region Initialize Canvas 109 | 110 | void InitializeCanvas() 111 | { 112 | _toggleCommand = new Command(OnTappedCommand); 113 | 114 | _skiaView = new SKCanvasView(); 115 | _skiaView.PaintSurface += Handle_PaintSurface; 116 | _skiaView.WidthRequest = _skiaView.HeightRequest = DEFAULT_SIZE; 117 | } 118 | 119 | void OnTappedCommand(object obj) 120 | { 121 | if (_isAnimating) 122 | return; 123 | 124 | IsChecked = !IsChecked; 125 | } 126 | 127 | async Task AnimateToggle() 128 | { 129 | _isAnimating = true; 130 | await _skiaView.ScaleTo(0.85, 100); 131 | _skiaView.InvalidateSurface(); 132 | await _skiaView.ScaleTo(1, 100, Easing.BounceOut); 133 | _isAnimating = false; 134 | } 135 | #endregion 136 | 137 | #region Checkmark Paint Surface 138 | void Handle_PaintSurface(object sender, SKPaintSurfaceEventArgs e) 139 | { 140 | e?.Surface?.Canvas?.Clear(); 141 | 142 | DrawOutline(e); 143 | 144 | if (IsChecked) 145 | DrawCheckFilled(e); 146 | } 147 | 148 | void DrawCheckFilled(SKPaintSurfaceEventArgs e) 149 | { 150 | var imageInfo = e.Info; 151 | var canvas = e?.Surface?.Canvas; 152 | 153 | using (var checkfill = new SKPaint 154 | { 155 | Style = SKPaintStyle.Fill, 156 | Color = FillColor.ToSKColor(), 157 | StrokeJoin = SKStrokeJoin.Round, 158 | IsAntialias = true 159 | }) 160 | { 161 | var shape = Design == Design.Unified ? Shape : DEFAULT_SHAPE; 162 | if (shape == Shape.Circle) 163 | canvas.DrawCircle(imageInfo.Width / 2, imageInfo.Height / 2, (imageInfo.Width / 2) - (OutlineWidth / 2), checkfill); 164 | else { 165 | var cornerRadius = Design == Design.Native && Device.RuntimePlatform == Device.UWP ? 0 : OutlineWidth; 166 | canvas.DrawRoundRect(OutlineWidth, OutlineWidth, imageInfo.Width - (OutlineWidth * 2), imageInfo.Height - (OutlineWidth * 2), cornerRadius, cornerRadius, checkfill); 167 | } 168 | } 169 | 170 | using (var checkPath = new SKPath()) 171 | { 172 | if (Design == Design.Unified) 173 | { 174 | checkPath.MoveTo(.275f * imageInfo.Width, .5f * imageInfo.Height); 175 | checkPath.LineTo(.425f * imageInfo.Width, .65f * imageInfo.Height); 176 | checkPath.LineTo(.725f * imageInfo.Width, .375f * imageInfo.Height); 177 | } else 178 | { 179 | switch (Device.RuntimePlatform) 180 | { 181 | case Device.iOS: 182 | checkPath.MoveTo(.2f * imageInfo.Width, .5f * imageInfo.Height); 183 | checkPath.LineTo(.375f * imageInfo.Width, .675f * imageInfo.Height); 184 | checkPath.LineTo(.75f * imageInfo.Width, .3f * imageInfo.Height); 185 | break; 186 | case Device.Android: 187 | checkPath.MoveTo(.2f * imageInfo.Width, .5f * imageInfo.Height); 188 | checkPath.LineTo(.425f * imageInfo.Width, .7f * imageInfo.Height); 189 | checkPath.LineTo(.8f * imageInfo.Width, .275f * imageInfo.Height); 190 | break; 191 | case Device.UWP: 192 | checkPath.MoveTo(.15f * imageInfo.Width, .5f * imageInfo.Height); 193 | checkPath.LineTo(.375f * imageInfo.Width, .75f * imageInfo.Height); 194 | checkPath.LineTo(.85f * imageInfo.Width, .25f * imageInfo.Height); 195 | break; 196 | default: 197 | break; 198 | } 199 | } 200 | 201 | using (var checkStroke = new SKPaint 202 | { 203 | Style = SKPaintStyle.Stroke, 204 | Color = CheckColor.ToSKColor(), 205 | StrokeWidth = OutlineWidth, 206 | IsAntialias = true 207 | }) 208 | { 209 | checkStroke.StrokeCap = Design == Design.Unified ? SKStrokeCap.Round : SKStrokeCap.Butt; 210 | canvas.DrawPath(checkPath, checkStroke); 211 | } 212 | } 213 | } 214 | 215 | void DrawOutline(SKPaintSurfaceEventArgs e) 216 | { 217 | 218 | var imageInfo = e.Info; 219 | var canvas = e?.Surface?.Canvas; 220 | 221 | using (var outline = new SKPaint 222 | { 223 | Style = SKPaintStyle.Stroke, 224 | Color = OutlineColor.ToSKColor(), 225 | StrokeWidth = OutlineWidth, 226 | StrokeJoin = SKStrokeJoin.Round, 227 | IsAntialias = true 228 | }) 229 | { 230 | var shape = Design == Design.Unified ? Shape : DEFAULT_SHAPE; 231 | if (shape == Shape.Circle) 232 | canvas.DrawCircle(imageInfo.Width / 2, imageInfo.Height / 2, (imageInfo.Width / 2) - (OutlineWidth / 2), outline); 233 | else { 234 | var cornerRadius = Design == Design.Native && Device.RuntimePlatform == Device.UWP ? 0 : OutlineWidth; 235 | canvas.DrawRoundRect(OutlineWidth, OutlineWidth, imageInfo.Width - (OutlineWidth * 2), imageInfo.Height - (OutlineWidth * 2), cornerRadius, cornerRadius, outline); 236 | } 237 | } 238 | } 239 | #endregion 240 | 241 | #region Events 242 | /// 243 | /// Raised when IsChecked is changed. 244 | /// 245 | public event EventHandler IsCheckedChanged; 246 | #endregion 247 | 248 | #region Bindable Properties 249 | public static BindableProperty OutlineColorProperty = BindableProperty.Create(nameof(OutlineColor), typeof(Color), typeof(Checkbox), Color.Blue); 250 | 251 | /// 252 | /// Gets or sets the color of the outline. 253 | /// 254 | /// Xamarin.Forms.Color value of the outline 255 | public Color OutlineColor 256 | { 257 | get { return (Color)GetValue(OutlineColorProperty); } 258 | set { SetValue(OutlineColorProperty, value); } 259 | } 260 | 261 | public static BindableProperty FillColorProperty = BindableProperty.Create(nameof(FillColor), typeof(Color), typeof(Checkbox), Color.Blue); 262 | /// 263 | /// Gets or sets the color of the fill. 264 | /// 265 | /// Xamarin.Forms.Color value of the fill. 266 | public Color FillColor 267 | { 268 | get { return (Color)GetValue(FillColorProperty); } 269 | set { SetValue(FillColorProperty, value); } 270 | } 271 | 272 | public static BindableProperty CheckColorProperty = BindableProperty.Create(nameof(CheckColor), typeof(Color), typeof(Checkbox), Color.White); 273 | /// 274 | /// Gets or sets the color of the check. 275 | /// 276 | /// Xamarin.Forms.Color value of the check. 277 | public Color CheckColor 278 | { 279 | get { return (Color)GetValue(CheckColorProperty); } 280 | set { SetValue(CheckColorProperty, value); } 281 | } 282 | 283 | public static BindableProperty OutlineWidthProperty = BindableProperty.Create(nameof(OutlineWidth), typeof(float), typeof(Checkbox), DEFAULT_OUTLINE_WIDTH); 284 | /// 285 | /// Gets or sets the width of the outline and check. 286 | /// 287 | /// The width of the outline and check. 288 | public float OutlineWidth 289 | { 290 | get { return (float)GetValue(OutlineWidthProperty); } 291 | set { SetValue(OutlineWidthProperty, value); } 292 | } 293 | 294 | public static BindableProperty ShapeProperty = BindableProperty.Create(nameof(Shape), typeof(Shape), typeof(Checkbox), DEFAULT_SHAPE); 295 | /// 296 | /// Gets or sets the shape of the . 297 | /// 298 | public Shape Shape 299 | { 300 | get { return (Shape)GetValue(ShapeProperty); } 301 | set { SetValue(ShapeProperty, value); } 302 | } 303 | 304 | public static BindableProperty DesignProperty = BindableProperty.Create(nameof(Design), typeof(Design), typeof(Checkbox), DEFAULT_DESIGN); 305 | /// 306 | /// Gets or sets the shape of the . 307 | /// 308 | public Design Design 309 | { 310 | get { return (Design)GetValue(DesignProperty); } 311 | set { SetValue(DesignProperty, value); } 312 | } 313 | 314 | public static new BindableProperty StyleProperty = BindableProperty.Create(nameof(Style), typeof(Style), typeof(Checkbox), propertyChanged: OnStyleChanged); 315 | 316 | /// 317 | /// Gets or sets the style for . 318 | /// 319 | /// The style. 320 | public new Style Style 321 | { 322 | get { return (Style)GetValue(StyleProperty); } 323 | set { SetValue(StyleProperty, value); } 324 | } 325 | 326 | static void OnStyleChanged(BindableObject bindable, object oldValue, object newValue) 327 | { 328 | if (!(bindable is Checkbox checkbox)) return; 329 | 330 | var setters = ((Style)newValue).Setters; 331 | var dict = new Dictionary(); 332 | 333 | foreach (var setter in setters) 334 | { 335 | dict.Add(setter.Property.PropertyName, (Color)setter.Value); 336 | } 337 | 338 | checkbox.OutlineColor = dict[nameof(OutlineColor)]; 339 | checkbox.FillColor = dict[nameof(FillColor)]; 340 | checkbox.CheckColor = dict[nameof(CheckColor)]; 341 | } 342 | 343 | public static readonly BindableProperty IsCheckedProperty = BindableProperty.Create(nameof(IsChecked), typeof(bool), typeof(Checkbox), false, BindingMode.TwoWay, propertyChanged: OnIsCheckedChanged); 344 | /// 345 | /// Gets or sets a value indicating whether this is checked. 346 | /// 347 | /// true if is checked; otherwise, false. 348 | public bool IsChecked 349 | { 350 | get { return (bool)GetValue(IsCheckedProperty); } 351 | set { SetValue(IsCheckedProperty, value); } 352 | } 353 | 354 | static async void OnIsCheckedChanged(BindableObject bindable, object oldValue, object newValue) 355 | { 356 | if(!(bindable is Checkbox checkbox)) return; 357 | checkbox.IsCheckedChanged?.Invoke(checkbox, new TappedEventArgs((bool)newValue)); 358 | await checkbox.AnimateToggle(); 359 | } 360 | #endregion 361 | 362 | #region IDisposable 363 | 364 | public void Dispose() 365 | { 366 | _skiaView.PaintSurface -= Handle_PaintSurface; 367 | GestureRecognizers.Clear(); 368 | } 369 | 370 | #endregion 371 | } 372 | 373 | public enum Shape 374 | { 375 | Circle, 376 | Rectangle 377 | } 378 | 379 | public enum Design 380 | { 381 | Unified, 382 | Native 383 | } 384 | } -------------------------------------------------------------------------------- /src/Controls/Controls.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | netstandard2.0;Xamarin.iOS10;MonoAndroid81;uap10.0.16299 6 | netstandard2.0;Xamarin.iOS10;MonoAndroid81 7 | intelliAbb 8 | Cross-platform controls for Xamarin.Forms 9 | IntelliAbb.Xamarin.Controls 10 | IntelliAbb.Xamarin.Controls 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Controls/Keypad.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xamarin.Forms; 4 | 5 | namespace IntelliAbb.Xamarin.Controls 6 | { 7 | public class Keypad : Grid, IDisposable 8 | { 9 | #region Fields 10 | const string CLEAR = "CLR"; 11 | #endregion 12 | 13 | #region Modes 14 | readonly string[] keys = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "" }; 15 | readonly string[] currencyKeys = { "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "0", CLEAR }; 16 | readonly string[] dialpadKeys = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#" }; 17 | readonly string[] calculatorKeys = { "C", "+/-", "%", "÷", "7", "8", "9", "×", "4", "5", "6", "-", "1", "2", "3", "+", "DEL", "0", ".", "=" }; 18 | #endregion 19 | 20 | #region Events 21 | public event EventHandler KeyPressed; 22 | #endregion 23 | 24 | #region Bindable Properties 25 | 26 | public static BindableProperty ModeProperty = BindableProperty.Create( 27 | nameof(Mode), typeof(Mode), typeof(Keypad), Mode.Default, propertyChanged: ResetView); 28 | 29 | public static BindableProperty KeyStyleProperty = BindableProperty.Create( 30 | nameof(KeyStyle), typeof(Style), typeof(Keypad), propertyChanged: ResetView); 31 | 32 | public static BindableProperty BackspaceTextProperty = BindableProperty.Create( 33 | nameof(BackspaceText), typeof(string), typeof(Keypad), propertyChanged: ResetView); 34 | 35 | #endregion 36 | 37 | #region Properties 38 | 39 | public string BackspaceText 40 | { 41 | get => (string)GetValue(BackspaceTextProperty); 42 | set => SetValue(BackspaceTextProperty, value); 43 | } 44 | 45 | public Mode Mode 46 | { 47 | get => (Mode)GetValue(ModeProperty); 48 | set => SetValue(ModeProperty, value); 49 | } 50 | 51 | public Style KeyStyle 52 | { 53 | get => (Style)GetValue(KeyStyleProperty); 54 | set => SetValue(KeyStyleProperty, value); 55 | } 56 | 57 | private static void ResetView(BindableObject bindable, object oldValue, object newValue) 58 | { 59 | (bindable as Keypad)?.BuildView(); 60 | } 61 | 62 | #endregion 63 | 64 | public Keypad() 65 | { 66 | ColumnSpacing = RowSpacing = 12; 67 | BuildView(); 68 | } 69 | 70 | void BuildView() 71 | { 72 | Children.Clear(); 73 | switch (Mode) 74 | { 75 | case Mode.Currency: 76 | BuildCurrencyKeypad(); 77 | break; 78 | case Mode.Dialpad: 79 | BuildDialpad(); 80 | break; 81 | case Mode.Calculator: 82 | BuildCalculator(); 83 | break; 84 | default: 85 | BuildKeypad(); 86 | break; 87 | } 88 | } 89 | 90 | void BuildKeypad() 91 | { 92 | var queue = new Queue(keys); 93 | BuildKeys(queue, 4, 3); 94 | } 95 | 96 | void BuildDialpad() 97 | { 98 | var queue = new Queue(dialpadKeys); 99 | BuildKeys(queue, 4, 3); 100 | } 101 | 102 | void BuildCurrencyKeypad() 103 | { 104 | var queue = new Queue(currencyKeys); 105 | BuildKeys(queue, 4, 3); 106 | } 107 | 108 | void BuildCalculator() 109 | { 110 | var queue = new Queue(calculatorKeys); 111 | BuildKeys(queue, 5, 4); 112 | } 113 | 114 | void BuildKeys(Queue queue, int rows, int columns) 115 | { 116 | if (queue.Count < 1) 117 | return; 118 | 119 | for (int row = 0; row < rows; row++) 120 | { 121 | for (int col = 0; col < columns; col++) 122 | { 123 | if (queue.Count < 1) 124 | break; 125 | 126 | var key = queue.Dequeue(); 127 | 128 | if (string.IsNullOrWhiteSpace(key)) 129 | continue; 130 | 131 | if (key.Equals(CLEAR) && !string.IsNullOrWhiteSpace(BackspaceText)) 132 | key = BackspaceText; 133 | 134 | var button = new Button { Text = key, CommandParameter = key, Style = KeyStyle }; 135 | button.Clicked += Button_Clicked; 136 | Children.Add(button, col, row); 137 | } 138 | } 139 | } 140 | void Button_Clicked(object sender, EventArgs e) 141 | { 142 | KeyPressed?.Invoke(this, (sender as Button)?.CommandParameter?.ToString()); 143 | } 144 | 145 | public void Dispose() 146 | { 147 | foreach (var key in Children) 148 | { 149 | if (key is Button) (key as Button).Clicked -= Button_Clicked; 150 | } 151 | } 152 | } 153 | 154 | public enum Mode 155 | { 156 | Default, 157 | Currency, 158 | Dialpad, 159 | Calculator 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/Directory.build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | XamarinControls 4 | IntelliAbb.Xamarin.Controls 5 | Cross platform controls for Xamarin.Forms 6 | $(AssemblyName) ($(TargetFramework)) 7 | en-US 8 | Hussain Abbasi 9 | © $([System.DateTime]::Now.Year) intelliAbb 10 | https://raw.githubusercontent.com/Intelliabb/XamarinControls/master/XamarinControlsLogo.png 11 | https://opensource.org/licenses/Apache-2.0 12 | LICENSE 13 | 14 | https://github.com/Intelliabb/XamarinControls 15 | https://github.com/Intelliabb/XamarinControls 16 | true 17 | git 18 | 19 | 1.0.0 20 | Cross platform controls for Xamarin.Forms 21 | xamarin;forms;controls;checkbox;card;keypad 22 | Release notes are located at https://github.com/Intelliabb/XamarinControls/wiki/Release-Notes 23 | 24 | 25 | 26 | 27 | $(MSBuildThisFileDirectory)/Artifacts 28 | $(BUILD_ARTIFACTSTAGINGDIRECTORY) 29 | false 30 | false 31 | $(IsPackable) 32 | false 33 | false 34 | $(VersionPrefix)$(BUILD_BUILDNUMBER) 35 | ci 36 | pre 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/IntelliAbb.Xamarin.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2042 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Controls", "Controls\Controls.csproj", "{EB9677E3-647D-4DEE-B7C4-8783B675AB14}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Ad-Hoc|Any CPU = Ad-Hoc|Any CPU 11 | Ad-Hoc|ARM = Ad-Hoc|ARM 12 | Ad-Hoc|iPhone = Ad-Hoc|iPhone 13 | Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator 14 | Ad-Hoc|x64 = Ad-Hoc|x64 15 | Ad-Hoc|x86 = Ad-Hoc|x86 16 | AppStore|Any CPU = AppStore|Any CPU 17 | AppStore|ARM = AppStore|ARM 18 | AppStore|iPhone = AppStore|iPhone 19 | AppStore|iPhoneSimulator = AppStore|iPhoneSimulator 20 | AppStore|x64 = AppStore|x64 21 | AppStore|x86 = AppStore|x86 22 | Debug|Any CPU = Debug|Any CPU 23 | Debug|ARM = Debug|ARM 24 | Debug|iPhone = Debug|iPhone 25 | Debug|iPhoneSimulator = Debug|iPhoneSimulator 26 | Debug|x64 = Debug|x64 27 | Debug|x86 = Debug|x86 28 | Release|Any CPU = Release|Any CPU 29 | Release|ARM = Release|ARM 30 | Release|iPhone = Release|iPhone 31 | Release|iPhoneSimulator = Release|iPhoneSimulator 32 | Release|x64 = Release|x64 33 | Release|x86 = Release|x86 34 | EndGlobalSection 35 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 36 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU 37 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU 38 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU 39 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|ARM.Build.0 = Release|Any CPU 40 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU 41 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU 42 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU 43 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU 44 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU 45 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|x64.Build.0 = Release|Any CPU 46 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU 47 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Ad-Hoc|x86.Build.0 = Release|Any CPU 48 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|Any CPU.ActiveCfg = Release|Any CPU 49 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|Any CPU.Build.0 = Release|Any CPU 50 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|ARM.ActiveCfg = Release|Any CPU 51 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|ARM.Build.0 = Release|Any CPU 52 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|iPhone.ActiveCfg = Release|Any CPU 53 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|iPhone.Build.0 = Release|Any CPU 54 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU 55 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU 56 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|x64.ActiveCfg = Release|Any CPU 57 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|x64.Build.0 = Release|Any CPU 58 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|x86.ActiveCfg = Release|Any CPU 59 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.AppStore|x86.Build.0 = Release|Any CPU 60 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|ARM.ActiveCfg = Debug|Any CPU 63 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|ARM.Build.0 = Debug|Any CPU 64 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|iPhone.ActiveCfg = Debug|Any CPU 65 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|iPhone.Build.0 = Debug|Any CPU 66 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 67 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 68 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|x64.ActiveCfg = Debug|Any CPU 69 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|x64.Build.0 = Debug|Any CPU 70 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|x86.ActiveCfg = Debug|Any CPU 71 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Debug|x86.Build.0 = Debug|Any CPU 72 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|Any CPU.ActiveCfg = Release|Any CPU 73 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|Any CPU.Build.0 = Release|Any CPU 74 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|ARM.ActiveCfg = Release|Any CPU 75 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|ARM.Build.0 = Release|Any CPU 76 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|iPhone.ActiveCfg = Release|Any CPU 77 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|iPhone.Build.0 = Release|Any CPU 78 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 79 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 80 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|x64.ActiveCfg = Release|Any CPU 81 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|x64.Build.0 = Release|Any CPU 82 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|x86.ActiveCfg = Release|Any CPU 83 | {EB9677E3-647D-4DEE-B7C4-8783B675AB14}.Release|x86.Build.0 = Release|Any CPU 84 | EndGlobalSection 85 | GlobalSection(SolutionProperties) = preSolution 86 | HideSolutionNode = FALSE 87 | EndGlobalSection 88 | GlobalSection(ExtensibilityGlobals) = postSolution 89 | SolutionGuid = {07612AD2-6F7D-43D5-8FB7-1E6C8A820E83} 90 | EndGlobalSection 91 | EndGlobal 92 | --------------------------------------------------------------------------------