workspace-architect 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/.env.example +1 -0
  2. package/.gitattributes +1 -0
  3. package/.github/workflows/manual-publish.yml +36 -0
  4. package/.github/workflows/sync-and-publish.yml +58 -0
  5. package/.release-it.json +20 -0
  6. package/CHANGELOG.md +43 -0
  7. package/README.md +62 -0
  8. package/assets/chatmodes/4.1-Beast.chatmode.md +152 -0
  9. package/assets/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
  10. package/assets/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
  11. package/assets/chatmodes/accessibility.chatmode.md +298 -0
  12. package/assets/chatmodes/address-comments.chatmode.md +59 -0
  13. package/assets/chatmodes/aem-frontend-specialist.chatmode.md +385 -0
  14. package/assets/chatmodes/api-architect.chatmode.md +40 -0
  15. package/assets/chatmodes/atlassian-requirements-to-jira.chatmode.md +444 -0
  16. package/assets/chatmodes/azure-logic-apps-expert.chatmode.md +100 -0
  17. package/assets/chatmodes/azure-principal-architect.chatmode.md +58 -0
  18. package/assets/chatmodes/azure-saas-architect.chatmode.md +118 -0
  19. package/assets/chatmodes/azure-verified-modules-bicep.chatmode.md +44 -0
  20. package/assets/chatmodes/azure-verified-modules-terraform.chatmode.md +58 -0
  21. package/assets/chatmodes/bicep-implement.chatmode.md +40 -0
  22. package/assets/chatmodes/bicep-plan.chatmode.md +112 -0
  23. package/assets/chatmodes/blueprint-mode-codex.chatmode.md +110 -0
  24. package/assets/chatmodes/blueprint-mode.chatmode.md +171 -0
  25. package/assets/chatmodes/clojure-interactive-programming.chatmode.md +174 -0
  26. package/assets/chatmodes/code-tour.chatmode.md +205 -0
  27. package/assets/chatmodes/critical-thinking.chatmode.md +23 -0
  28. package/assets/chatmodes/csharp-dotnet-janitor.chatmode.md +83 -0
  29. package/assets/chatmodes/csharp-mcp-expert.chatmode.md +69 -0
  30. package/assets/chatmodes/debug.chatmode.md +79 -0
  31. package/assets/chatmodes/declarative-agents-architect.chatmode.md +76 -0
  32. package/assets/chatmodes/demonstrate-understanding.chatmode.md +60 -0
  33. package/assets/chatmodes/dotnet-upgrade.chatmode.md +222 -0
  34. package/assets/chatmodes/drupal-expert.chatmode.md +687 -0
  35. package/assets/chatmodes/electron-angular-native.chatmode.md +285 -0
  36. package/assets/chatmodes/expert-cpp-software-engineer.chatmode.md +27 -0
  37. package/assets/chatmodes/expert-dotnet-software-engineer.chatmode.md +22 -0
  38. package/assets/chatmodes/expert-nextjs-developer.chatmode.md +477 -0
  39. package/assets/chatmodes/expert-react-frontend-engineer.chatmode.md +738 -0
  40. package/assets/chatmodes/gilfoyle.chatmode.md +66 -0
  41. package/assets/chatmodes/go-mcp-expert.chatmode.md +122 -0
  42. package/assets/chatmodes/gpt-5-beast-mode.chatmode.md +109 -0
  43. package/assets/chatmodes/hlbpa.chatmode.md +232 -0
  44. package/assets/chatmodes/implementation-plan.chatmode.md +159 -0
  45. package/assets/chatmodes/janitor.chatmode.md +89 -0
  46. package/assets/chatmodes/java-mcp-expert.chatmode.md +325 -0
  47. package/assets/chatmodes/kotlin-mcp-expert.chatmode.md +181 -0
  48. package/assets/chatmodes/kusto-assistant.chatmode.md +143 -0
  49. package/assets/chatmodes/laravel-expert-agent.chatmode.md +628 -0
  50. package/assets/chatmodes/mentor.chatmode.md +32 -0
  51. package/assets/chatmodes/meta-agentic-project-scaffold.chatmode.md +15 -0
  52. package/assets/chatmodes/microsoft-agent-framework-dotnet.chatmode.md +62 -0
  53. package/assets/chatmodes/microsoft-agent-framework-python.chatmode.md +62 -0
  54. package/assets/chatmodes/microsoft-study-mode.chatmode.md +32 -0
  55. package/assets/chatmodes/microsoft_learn_contributor.chatmode.md +388 -0
  56. package/assets/chatmodes/ms-sql-dba.chatmode.md +25 -0
  57. package/assets/chatmodes/php-mcp-expert.chatmode.md +498 -0
  58. package/assets/chatmodes/pimcore-expert.chatmode.md +869 -0
  59. package/assets/chatmodes/plan.chatmode.md +114 -0
  60. package/assets/chatmodes/planner.chatmode.md +14 -0
  61. package/assets/chatmodes/playwright-tester.chatmode.md +13 -0
  62. package/assets/chatmodes/postgresql-dba.chatmode.md +17 -0
  63. package/assets/chatmodes/power-bi-data-modeling-expert.chatmode.md +319 -0
  64. package/assets/chatmodes/power-bi-dax-expert.chatmode.md +334 -0
  65. package/assets/chatmodes/power-bi-performance-expert.chatmode.md +533 -0
  66. package/assets/chatmodes/power-bi-visualization-expert.chatmode.md +549 -0
  67. package/assets/chatmodes/power-platform-expert.chatmode.md +116 -0
  68. package/assets/chatmodes/power-platform-mcp-integration-expert.chatmode.md +149 -0
  69. package/assets/chatmodes/prd.chatmode.md +201 -0
  70. package/assets/chatmodes/principal-software-engineer.chatmode.md +41 -0
  71. package/assets/chatmodes/prompt-builder.chatmode.md +352 -0
  72. package/assets/chatmodes/prompt-engineer.chatmode.md +72 -0
  73. package/assets/chatmodes/python-mcp-expert.chatmode.md +99 -0
  74. package/assets/chatmodes/refine-issue.chatmode.md +34 -0
  75. package/assets/chatmodes/research-technical-spike.chatmode.md +169 -0
  76. package/assets/chatmodes/ruby-mcp-expert.chatmode.md +346 -0
  77. package/assets/chatmodes/rust-gpt-4.1-beast-mode.chatmode.md +197 -0
  78. package/assets/chatmodes/rust-mcp-expert.chatmode.md +465 -0
  79. package/assets/chatmodes/search-ai-optimization-expert.chatmode.md +227 -0
  80. package/assets/chatmodes/semantic-kernel-dotnet.chatmode.md +31 -0
  81. package/assets/chatmodes/semantic-kernel-python.chatmode.md +28 -0
  82. package/assets/chatmodes/shopify-expert.chatmode.md +681 -0
  83. package/assets/chatmodes/simple-app-idea-generator.chatmode.md +134 -0
  84. package/assets/chatmodes/software-engineer-agent-v1.chatmode.md +164 -0
  85. package/assets/chatmodes/specification.chatmode.md +127 -0
  86. package/assets/chatmodes/swift-mcp-expert.chatmode.md +240 -0
  87. package/assets/chatmodes/task-planner.chatmode.md +374 -0
  88. package/assets/chatmodes/task-researcher.chatmode.md +254 -0
  89. package/assets/chatmodes/tdd-green.chatmode.md +59 -0
  90. package/assets/chatmodes/tdd-red.chatmode.md +59 -0
  91. package/assets/chatmodes/tdd-refactor.chatmode.md +84 -0
  92. package/assets/chatmodes/tech-debt-remediation-plan.chatmode.md +49 -0
  93. package/assets/chatmodes/terraform-azure-implement.chatmode.md +104 -0
  94. package/assets/chatmodes/terraform-azure-planning.chatmode.md +157 -0
  95. package/assets/chatmodes/typescript-mcp-expert.chatmode.md +91 -0
  96. package/assets/chatmodes/voidbeast-gpt41enhanced.chatmode.md +230 -0
  97. package/assets/chatmodes/wg-code-alchemist.chatmode.md +61 -0
  98. package/assets/chatmodes/wg-code-sentinel.chatmode.md +55 -0
  99. package/assets/collections/ai-prompt-engineering.json +18 -0
  100. package/assets/collections/angular-development.json +7 -0
  101. package/assets/collections/azure-cloud-architect.json +29 -0
  102. package/assets/collections/cpp-development.json +6 -0
  103. package/assets/collections/database-administration.json +8 -0
  104. package/assets/collections/devops-sre.json +11 -0
  105. package/assets/collections/dotnet-development.json +22 -0
  106. package/assets/collections/general-productivity.json +9 -0
  107. package/assets/collections/go-development.json +7 -0
  108. package/assets/collections/java-spring-developer.json +26 -0
  109. package/assets/collections/learning-mentoring.json +10 -0
  110. package/assets/collections/legacy-migration.json +4 -0
  111. package/assets/collections/mcp-specialist.json +41 -0
  112. package/assets/collections/mobile-development.json +4 -0
  113. package/assets/collections/php-cms-development.json +11 -0
  114. package/assets/collections/power-platform-specialist.json +31 -0
  115. package/assets/collections/project-management.json +12 -0
  116. package/assets/collections/python-development.json +13 -0
  117. package/assets/collections/quality-assurance.json +13 -0
  118. package/assets/collections/ruby-development.json +9 -0
  119. package/assets/collections/rust-development.json +10 -0
  120. package/assets/collections/security-specialist.json +8 -0
  121. package/assets/collections/software-architect.json +25 -0
  122. package/assets/collections/technical-writing.json +9 -0
  123. package/assets/collections/web-frontend-development.json +14 -0
  124. package/assets/instructions/a11y.instructions.md +369 -0
  125. package/assets/instructions/ai-prompt-engineering-safety-best-practices.instructions.md +867 -0
  126. package/assets/instructions/angular.instructions.md +104 -0
  127. package/assets/instructions/ansible.instructions.md +88 -0
  128. package/assets/instructions/aspnet-rest-apis.instructions.md +110 -0
  129. package/assets/instructions/astro.instructions.md +182 -0
  130. package/assets/instructions/azure-devops-pipelines.instructions.md +185 -0
  131. package/assets/instructions/azure-functions-typescript.instructions.md +14 -0
  132. package/assets/instructions/azure-logic-apps-power-automate.instructions.md +1943 -0
  133. package/assets/instructions/azure-verified-modules-terraform.instructions.md +229 -0
  134. package/assets/instructions/bicep-code-best-practices.instructions.md +54 -0
  135. package/assets/instructions/blazor.instructions.md +77 -0
  136. package/assets/instructions/clojure.instructions.md +349 -0
  137. package/assets/instructions/cmake-vcpkg.instructions.md +10 -0
  138. package/assets/instructions/codexer.instructions.md +428 -0
  139. package/assets/instructions/coldfusion-cfc.instructions.md +30 -0
  140. package/assets/instructions/coldfusion-cfm.instructions.md +28 -0
  141. package/assets/instructions/collections.instructions.md +54 -0
  142. package/assets/instructions/containerization-docker-best-practices.instructions.md +681 -0
  143. package/assets/instructions/convert-jpa-to-spring-data-cosmos.instructions.md +949 -0
  144. package/assets/instructions/copilot-thought-logging.instructions.md +62 -0
  145. package/assets/instructions/csharp-ja.instructions.md +114 -0
  146. package/assets/instructions/csharp-ko.instructions.md +77 -0
  147. package/assets/instructions/csharp-mcp-server.instructions.md +95 -0
  148. package/assets/instructions/csharp.instructions.md +114 -0
  149. package/assets/instructions/dart-n-flutter.instructions.md +447 -0
  150. package/assets/instructions/declarative-agents-microsoft365.instructions.md +316 -0
  151. package/assets/instructions/devbox-image-definition.instructions.md +302 -0
  152. package/assets/instructions/devops-core-principles.instructions.md +167 -0
  153. package/assets/instructions/dotnet-architecture-good-practices.instructions.md +279 -0
  154. package/assets/instructions/dotnet-framework.instructions.md +113 -0
  155. package/assets/instructions/dotnet-maui-9-to-dotnet-maui-10-upgrade.instructions.md +1922 -0
  156. package/assets/instructions/dotnet-maui.instructions.md +69 -0
  157. package/assets/instructions/dotnet-upgrade.instructions.md +287 -0
  158. package/assets/instructions/dotnet-wpf.instructions.md +79 -0
  159. package/assets/instructions/genaiscript.instructions.md +21 -0
  160. package/assets/instructions/generate-modern-terraform-code-for-azure.instructions.md +82 -0
  161. package/assets/instructions/gilfoyle-code-review.instructions.md +114 -0
  162. package/assets/instructions/github-actions-ci-cd-best-practices.instructions.md +607 -0
  163. package/assets/instructions/go-mcp-server.instructions.md +346 -0
  164. package/assets/instructions/go.instructions.md +373 -0
  165. package/assets/instructions/instructions.instructions.md +256 -0
  166. package/assets/instructions/java-11-to-java-17-upgrade.instructions.md +793 -0
  167. package/assets/instructions/java-17-to-java-21-upgrade.instructions.md +464 -0
  168. package/assets/instructions/java-21-to-java-25-upgrade.instructions.md +311 -0
  169. package/assets/instructions/java-mcp-server.instructions.md +553 -0
  170. package/assets/instructions/java.instructions.md +81 -0
  171. package/assets/instructions/joyride-user-project.instructions.md +206 -0
  172. package/assets/instructions/joyride-workspace-automation.instructions.md +46 -0
  173. package/assets/instructions/kotlin-mcp-server.instructions.md +481 -0
  174. package/assets/instructions/kubernetes-deployment-best-practices.instructions.md +307 -0
  175. package/assets/instructions/langchain-python.instructions.md +229 -0
  176. package/assets/instructions/localization.instructions.md +39 -0
  177. package/assets/instructions/makefile.instructions.md +410 -0
  178. package/assets/instructions/markdown.instructions.md +52 -0
  179. package/assets/instructions/memory-bank.instructions.md +299 -0
  180. package/assets/instructions/mongo-dba.instructions.md +25 -0
  181. package/assets/instructions/ms-sql-dba.instructions.md +25 -0
  182. package/assets/instructions/nestjs.instructions.md +406 -0
  183. package/assets/instructions/nextjs-tailwind.instructions.md +72 -0
  184. package/assets/instructions/nextjs.instructions.md +143 -0
  185. package/assets/instructions/nodejs-javascript-vitest.instructions.md +30 -0
  186. package/assets/instructions/object-calisthenics.instructions.md +302 -0
  187. package/assets/instructions/oqtane.instructions.md +86 -0
  188. package/assets/instructions/performance-optimization.instructions.md +420 -0
  189. package/assets/instructions/php-mcp-server.instructions.md +809 -0
  190. package/assets/instructions/playwright-dotnet.instructions.md +101 -0
  191. package/assets/instructions/playwright-python.instructions.md +62 -0
  192. package/assets/instructions/playwright-typescript.instructions.md +86 -0
  193. package/assets/instructions/power-apps-canvas-yaml.instructions.md +827 -0
  194. package/assets/instructions/power-apps-code-apps.instructions.md +601 -0
  195. package/assets/instructions/power-bi-custom-visuals-development.instructions.md +810 -0
  196. package/assets/instructions/power-bi-data-modeling-best-practices.instructions.md +639 -0
  197. package/assets/instructions/power-bi-dax-best-practices.instructions.md +795 -0
  198. package/assets/instructions/power-bi-devops-alm-best-practices.instructions.md +623 -0
  199. package/assets/instructions/power-bi-report-design-best-practices.instructions.md +752 -0
  200. package/assets/instructions/power-bi-security-rls-best-practices.instructions.md +504 -0
  201. package/assets/instructions/power-platform-connector.instructions.md +430 -0
  202. package/assets/instructions/power-platform-mcp-development.instructions.md +88 -0
  203. package/assets/instructions/powershell-pester-5.instructions.md +197 -0
  204. package/assets/instructions/powershell.instructions.md +356 -0
  205. package/assets/instructions/prompt.instructions.md +73 -0
  206. package/assets/instructions/python-mcp-server.instructions.md +204 -0
  207. package/assets/instructions/python.instructions.md +56 -0
  208. package/assets/instructions/quarkus-mcp-server-sse.instructions.md +49 -0
  209. package/assets/instructions/quarkus.instructions.md +98 -0
  210. package/assets/instructions/r.instructions.md +116 -0
  211. package/assets/instructions/reactjs.instructions.md +162 -0
  212. package/assets/instructions/ruby-mcp-server.instructions.md +629 -0
  213. package/assets/instructions/ruby-on-rails.instructions.md +124 -0
  214. package/assets/instructions/rust-mcp-server.instructions.md +715 -0
  215. package/assets/instructions/rust.instructions.md +135 -0
  216. package/assets/instructions/security-and-owasp.instructions.md +51 -0
  217. package/assets/instructions/self-explanatory-code-commenting.instructions.md +162 -0
  218. package/assets/instructions/shell.instructions.md +132 -0
  219. package/assets/instructions/spec-driven-workflow-v1.instructions.md +323 -0
  220. package/assets/instructions/springboot.instructions.md +68 -0
  221. package/assets/instructions/sql-sp-generation.instructions.md +74 -0
  222. package/assets/instructions/svelte.instructions.md +161 -0
  223. package/assets/instructions/swift-mcp-server.instructions.md +498 -0
  224. package/assets/instructions/taming-copilot.instructions.md +40 -0
  225. package/assets/instructions/tanstack-start-shadcn-tailwind.instructions.md +212 -0
  226. package/assets/instructions/task-implementation.instructions.md +190 -0
  227. package/assets/instructions/tasksync.instructions.md +352 -0
  228. package/assets/instructions/terraform-azure.instructions.md +254 -0
  229. package/assets/instructions/terraform-sap-btp.instructions.md +195 -0
  230. package/assets/instructions/terraform.instructions.md +113 -0
  231. package/assets/instructions/typescript-5-es2022.instructions.md +114 -0
  232. package/assets/instructions/typescript-mcp-server.instructions.md +228 -0
  233. package/assets/instructions/update-code-from-shorthand.instructions.md +130 -0
  234. package/assets/instructions/vuejs3.instructions.md +153 -0
  235. package/assets/instructions/wordpress.instructions.md +186 -0
  236. package/assets/prompts/add-educational-comments.prompt.md +129 -0
  237. package/assets/prompts/ai-prompt-engineering-safety-review.prompt.md +230 -0
  238. package/assets/prompts/architecture-blueprint-generator.prompt.md +322 -0
  239. package/assets/prompts/aspnet-minimal-api-openapi.prompt.md +42 -0
  240. package/assets/prompts/az-cost-optimize.prompt.md +305 -0
  241. package/assets/prompts/azure-resource-health-diagnose.prompt.md +290 -0
  242. package/assets/prompts/boost-prompt.prompt.md +25 -0
  243. package/assets/prompts/breakdown-epic-arch.prompt.md +66 -0
  244. package/assets/prompts/breakdown-epic-pm.prompt.md +58 -0
  245. package/assets/prompts/breakdown-feature-implementation.prompt.md +128 -0
  246. package/assets/prompts/breakdown-feature-prd.prompt.md +61 -0
  247. package/assets/prompts/breakdown-plan.prompt.md +509 -0
  248. package/assets/prompts/breakdown-test.prompt.md +365 -0
  249. package/assets/prompts/code-exemplars-blueprint-generator.prompt.md +126 -0
  250. package/assets/prompts/comment-code-generate-a-tutorial.prompt.md +26 -0
  251. package/assets/prompts/containerize-aspnet-framework.prompt.md +455 -0
  252. package/assets/prompts/containerize-aspnetcore.prompt.md +393 -0
  253. package/assets/prompts/conventional-commit.prompt.md +73 -0
  254. package/assets/prompts/copilot-instructions-blueprint-generator.prompt.md +294 -0
  255. package/assets/prompts/cosmosdb-datamodeling.prompt.md +1045 -0
  256. package/assets/prompts/create-agentsmd.prompt.md +249 -0
  257. package/assets/prompts/create-architectural-decision-record.prompt.md +97 -0
  258. package/assets/prompts/create-github-action-workflow-specification.prompt.md +276 -0
  259. package/assets/prompts/create-github-issue-feature-from-specification.prompt.md +28 -0
  260. package/assets/prompts/create-github-issues-feature-from-implementation-plan.prompt.md +28 -0
  261. package/assets/prompts/create-github-issues-for-unmet-specification-requirements.prompt.md +35 -0
  262. package/assets/prompts/create-github-pull-request-from-specification.prompt.md +24 -0
  263. package/assets/prompts/create-implementation-plan.prompt.md +157 -0
  264. package/assets/prompts/create-llms.prompt.md +210 -0
  265. package/assets/prompts/create-oo-component-documentation.prompt.md +193 -0
  266. package/assets/prompts/create-readme.prompt.md +21 -0
  267. package/assets/prompts/create-specification.prompt.md +127 -0
  268. package/assets/prompts/create-spring-boot-java-project.prompt.md +163 -0
  269. package/assets/prompts/create-spring-boot-kotlin-project.prompt.md +147 -0
  270. package/assets/prompts/create-technical-spike.prompt.md +231 -0
  271. package/assets/prompts/csharp-async.prompt.md +50 -0
  272. package/assets/prompts/csharp-docs.prompt.md +63 -0
  273. package/assets/prompts/csharp-mcp-server-generator.prompt.md +59 -0
  274. package/assets/prompts/csharp-mstest.prompt.md +67 -0
  275. package/assets/prompts/csharp-nunit.prompt.md +72 -0
  276. package/assets/prompts/csharp-tunit.prompt.md +101 -0
  277. package/assets/prompts/csharp-xunit.prompt.md +69 -0
  278. package/assets/prompts/declarative-agents.prompt.md +93 -0
  279. package/assets/prompts/documentation-writer.prompt.md +46 -0
  280. package/assets/prompts/dotnet-best-practices.prompt.md +84 -0
  281. package/assets/prompts/dotnet-design-pattern-review.prompt.md +41 -0
  282. package/assets/prompts/dotnet-upgrade.prompt.md +116 -0
  283. package/assets/prompts/editorconfig.prompt.md +64 -0
  284. package/assets/prompts/ef-core.prompt.md +76 -0
  285. package/assets/prompts/finalize-agent-prompt.prompt.md +27 -0
  286. package/assets/prompts/first-ask.prompt.md +29 -0
  287. package/assets/prompts/folder-structure-blueprint-generator.prompt.md +405 -0
  288. package/assets/prompts/gen-specs-as-issues.prompt.md +165 -0
  289. package/assets/prompts/generate-custom-instructions-from-codebase.prompt.md +240 -0
  290. package/assets/prompts/git-flow-branch-creator.prompt.md +293 -0
  291. package/assets/prompts/github-copilot-starter.prompt.md +372 -0
  292. package/assets/prompts/go-mcp-server-generator.prompt.md +334 -0
  293. package/assets/prompts/java-docs.prompt.md +24 -0
  294. package/assets/prompts/java-junit.prompt.md +64 -0
  295. package/assets/prompts/java-mcp-server-generator.prompt.md +756 -0
  296. package/assets/prompts/java-refactoring-extract-method.prompt.md +105 -0
  297. package/assets/prompts/java-refactoring-remove-parameter.prompt.md +85 -0
  298. package/assets/prompts/java-springboot.prompt.md +66 -0
  299. package/assets/prompts/javascript-typescript-jest.prompt.md +44 -0
  300. package/assets/prompts/kotlin-mcp-server-generator.prompt.md +449 -0
  301. package/assets/prompts/kotlin-springboot.prompt.md +71 -0
  302. package/assets/prompts/mcp-copilot-studio-server-generator.prompt.md +118 -0
  303. package/assets/prompts/memory-merger.prompt.md +107 -0
  304. package/assets/prompts/mkdocs-translations.prompt.md +110 -0
  305. package/assets/prompts/model-recommendation.prompt.md +677 -0
  306. package/assets/prompts/multi-stage-dockerfile.prompt.md +47 -0
  307. package/assets/prompts/my-issues.prompt.md +9 -0
  308. package/assets/prompts/my-pull-requests.prompt.md +15 -0
  309. package/assets/prompts/next-intl-add-language.prompt.md +20 -0
  310. package/assets/prompts/php-mcp-server-generator.prompt.md +522 -0
  311. package/assets/prompts/playwright-automation-fill-in-form.prompt.md +30 -0
  312. package/assets/prompts/playwright-explore-website.prompt.md +19 -0
  313. package/assets/prompts/playwright-generate-test.prompt.md +19 -0
  314. package/assets/prompts/postgresql-code-review.prompt.md +214 -0
  315. package/assets/prompts/postgresql-optimization.prompt.md +406 -0
  316. package/assets/prompts/power-apps-code-app-scaffold.prompt.md +150 -0
  317. package/assets/prompts/power-bi-dax-optimization.prompt.md +175 -0
  318. package/assets/prompts/power-bi-model-design-review.prompt.md +405 -0
  319. package/assets/prompts/power-bi-performance-troubleshooting.prompt.md +384 -0
  320. package/assets/prompts/power-bi-report-design-consultation.prompt.md +353 -0
  321. package/assets/prompts/power-platform-mcp-connector-suite.prompt.md +156 -0
  322. package/assets/prompts/project-workflow-analysis-blueprint-generator.prompt.md +294 -0
  323. package/assets/prompts/prompt-builder.prompt.md +142 -0
  324. package/assets/prompts/pytest-coverage.prompt.md +28 -0
  325. package/assets/prompts/python-mcp-server-generator.prompt.md +105 -0
  326. package/assets/prompts/readme-blueprint-generator.prompt.md +79 -0
  327. package/assets/prompts/remember-interactive-programming.prompt.md +13 -0
  328. package/assets/prompts/remember.prompt.md +125 -0
  329. package/assets/prompts/repo-story-time.prompt.md +156 -0
  330. package/assets/prompts/review-and-refactor.prompt.md +15 -0
  331. package/assets/prompts/ruby-mcp-server-generator.prompt.md +660 -0
  332. package/assets/prompts/rust-mcp-server-generator.prompt.md +578 -0
  333. package/assets/prompts/shuffle-json-data.prompt.md +151 -0
  334. package/assets/prompts/sql-code-review.prompt.md +303 -0
  335. package/assets/prompts/sql-optimization.prompt.md +298 -0
  336. package/assets/prompts/suggest-awesome-github-copilot-agents.prompt.md +72 -0
  337. package/assets/prompts/suggest-awesome-github-copilot-chatmodes.prompt.md +71 -0
  338. package/assets/prompts/suggest-awesome-github-copilot-collections.prompt.md +149 -0
  339. package/assets/prompts/suggest-awesome-github-copilot-instructions.prompt.md +88 -0
  340. package/assets/prompts/suggest-awesome-github-copilot-prompts.prompt.md +71 -0
  341. package/assets/prompts/swift-mcp-server-generator.prompt.md +669 -0
  342. package/assets/prompts/technology-stack-blueprint-generator.prompt.md +242 -0
  343. package/assets/prompts/typescript-mcp-server-generator.prompt.md +90 -0
  344. package/assets/prompts/update-avm-modules-in-bicep.prompt.md +60 -0
  345. package/assets/prompts/update-implementation-plan.prompt.md +157 -0
  346. package/assets/prompts/update-llms.prompt.md +216 -0
  347. package/assets/prompts/update-markdown-file-index.prompt.md +76 -0
  348. package/assets/prompts/update-oo-component-documentation.prompt.md +162 -0
  349. package/assets/prompts/update-specification.prompt.md +127 -0
  350. package/assets/prompts/write-coding-standards-from-file.prompt.md +316 -0
  351. package/bin/cli.js +200 -0
  352. package/package.json +53 -0
  353. package/scripts/sync.js +99 -0
  354. package/verdaccio/config.yaml +202 -0
@@ -0,0 +1,1922 @@
1
+ ---
2
+ description: 'Instructions for upgrading .NET MAUI applications from version 9 to version 10, including breaking changes, deprecated APIs, and migration strategies for ListView to CollectionView.'
3
+ applyTo: '**/*.csproj, **/*.cs, **/*.xaml'
4
+ ---
5
+
6
+ # Upgrading from .NET MAUI 9 to .NET MAUI 10
7
+
8
+ This guide helps you upgrade your .NET MAUI application from .NET 9 to .NET 10 by focusing on the critical breaking changes and obsolete APIs that require code updates.
9
+
10
+ ---
11
+
12
+ ## Table of Contents
13
+
14
+ 1. [Quick Start](#quick-start)
15
+ 2. [Update Target Framework](#update-target-framework)
16
+ 3. [Breaking Changes (P0 - Must Fix)](#breaking-changes-p0---must-fix)
17
+ - [MessagingCenter Made Internal](#messagingcenter-made-internal)
18
+ - [ListView and TableView Deprecated](#listview-and-tableview-deprecated)
19
+ 4. [Deprecated APIs (P1 - Fix Soon)](#deprecated-apis-p1---fix-soon)
20
+ - [Animation Methods](#1-animation-methods)
21
+ - [DisplayAlert and DisplayActionSheet](#2-displayalert-and-displayactionsheet)
22
+ - [Page.IsBusy](#3-pageisbusy)
23
+ - [MediaPicker APIs](#4-mediapicker-apis)
24
+ 5. [Recommended Changes (P2)](#recommended-changes-p2)
25
+ 6. [Bulk Migration Tools](#bulk-migration-tools)
26
+ 7. [Testing Your Upgrade](#testing-your-upgrade)
27
+ 8. [Troubleshooting](#troubleshooting)
28
+
29
+ ---
30
+
31
+ ## Quick Start
32
+
33
+ **Five-Step Upgrade Process:**
34
+
35
+ 1. **Update TargetFramework** to `net10.0`
36
+ 2. **Update CommunityToolkit.Maui** to 12.3.0+ (if you use it) - REQUIRED
37
+ 3. **Fix breaking changes** - MessagingCenter (P0)
38
+ 4. **Migrate ListView/TableView to CollectionView** (P0 - CRITICAL)
39
+ 5. **Fix deprecated APIs** - Animation methods, DisplayAlert, IsBusy, MediaPicker (P1)
40
+
41
+ > ⚠️ **Major Breaking Changes**:
42
+ > - CommunityToolkit.Maui **must** be version 12.3.0 or later
43
+ > - ListView and TableView are now obsolete (most significant migration effort)
44
+
45
+ ---
46
+
47
+ ## Update Target Framework
48
+
49
+ ### Single Platform
50
+
51
+ ```xml
52
+ <Project Sdk="Microsoft.NET.Sdk">
53
+ <PropertyGroup>
54
+ <TargetFramework>net10.0</TargetFramework>
55
+ </PropertyGroup>
56
+ </Project>
57
+ ```
58
+
59
+ ### Multi-Platform
60
+
61
+ ```xml
62
+ <Project Sdk="Microsoft.NET.Sdk">
63
+ <PropertyGroup>
64
+ <TargetFrameworks>net10.0-android;net10.0-ios;net10.0-maccatalyst;net10.0-windows10.0.19041.0</TargetFrameworks>
65
+ </PropertyGroup>
66
+ </Project>
67
+ ```
68
+
69
+ ### Optional: Linux Compatibility (GitHub Copilot, WSL, etc.)
70
+
71
+ > 💡 **For Linux Development**: If you're building on Linux (e.g., GitHub Codespaces, WSL, or using GitHub Copilot), you can make your project compile on Linux by conditionally excluding iOS/Mac Catalyst targets:
72
+
73
+ ```xml
74
+ <Project Sdk="Microsoft.NET.Sdk">
75
+ <PropertyGroup>
76
+ <!-- Start with Android (always supported) -->
77
+ <TargetFrameworks>net10.0-android</TargetFrameworks>
78
+
79
+ <!-- Add iOS/Mac Catalyst only when NOT on Linux -->
80
+ <TargetFrameworks Condition="!$([MSBuild]::IsOSPlatform('linux'))">$(TargetFrameworks);net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
81
+
82
+ <!-- Add Windows only when on Windows -->
83
+ <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.0-windows10.0.19041.0</TargetFrameworks>
84
+ </PropertyGroup>
85
+ </Project>
86
+ ```
87
+
88
+ **Benefits:**
89
+ - ✅ Compiles successfully on Linux (no iOS/Mac tools required)
90
+ - ✅ Works with GitHub Codespaces and Copilot
91
+ - ✅ Automatically includes correct targets based on build OS
92
+ - ✅ No changes needed when switching between OS environments
93
+
94
+ **Reference:** [dotnet/maui#32186](https://github.com/dotnet/maui/pull/32186)
95
+
96
+ ### Update Required NuGet Packages
97
+
98
+ > ⚠️ **CRITICAL**: If you use CommunityToolkit.Maui, you **must** update to version 12.3.0 or later. Earlier versions are not compatible with .NET 10 and will cause compilation errors.
99
+
100
+ ```bash
101
+ # Update CommunityToolkit.Maui (if you use it)
102
+ dotnet add package CommunityToolkit.Maui --version 12.3.0
103
+
104
+ # Update other common packages to .NET 10 compatible versions
105
+ dotnet add package Microsoft.Maui.Controls --version 10.0.0
106
+ ```
107
+
108
+ **Check all your NuGet packages:**
109
+ ```bash
110
+ # List all packages and check for updates
111
+ dotnet list package --outdated
112
+
113
+ # Update all packages to latest compatible versions
114
+ dotnet list package --outdated | grep ">" | cut -d '>' -f 1 | xargs -I {} dotnet add package {}
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Breaking Changes (P0 - Must Fix)
120
+
121
+ ### MessagingCenter Made Internal
122
+
123
+ **Status:** 🚨 **BREAKING** - `MessagingCenter` is now `internal` and cannot be accessed.
124
+
125
+ **Error You'll See:**
126
+ ```
127
+ error CS0122: 'MessagingCenter' is inaccessible due to its protection level
128
+ ```
129
+
130
+ **Migration Required:**
131
+
132
+ #### Step 1: Install CommunityToolkit.Mvvm
133
+
134
+ ```bash
135
+ dotnet add package CommunityToolkit.Mvvm --version 8.3.0
136
+ ```
137
+
138
+ #### Step 2: Define Message Classes
139
+
140
+ ```csharp
141
+ // OLD: No message class needed
142
+ MessagingCenter.Send(this, "UserLoggedIn", userData);
143
+
144
+ // NEW: Create a message class
145
+ public class UserLoggedInMessage
146
+ {
147
+ public UserData Data { get; set; }
148
+
149
+ public UserLoggedInMessage(UserData data)
150
+ {
151
+ Data = data;
152
+ }
153
+ }
154
+ ```
155
+
156
+ #### Step 3: Update Send Calls
157
+
158
+ ```csharp
159
+ // ❌ OLD (Broken in .NET 10)
160
+ using Microsoft.Maui.Controls;
161
+
162
+ MessagingCenter.Send(this, "UserLoggedIn", userData);
163
+ MessagingCenter.Send<App, string>(this, "StatusChanged", "Active");
164
+
165
+ // ✅ NEW (Required)
166
+ using CommunityToolkit.Mvvm.Messaging;
167
+
168
+ WeakReferenceMessenger.Default.Send(new UserLoggedInMessage(userData));
169
+ WeakReferenceMessenger.Default.Send(new StatusChangedMessage("Active"));
170
+ ```
171
+
172
+ #### Step 4: Update Subscribe Calls
173
+
174
+ ```csharp
175
+ // ❌ OLD (Broken in .NET 10)
176
+ MessagingCenter.Subscribe<App, UserData>(this, "UserLoggedIn", (sender, data) =>
177
+ {
178
+ // Handle message
179
+ CurrentUser = data;
180
+ });
181
+
182
+ // ✅ NEW (Required)
183
+ WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(this, (recipient, message) =>
184
+ {
185
+ // Handle message
186
+ CurrentUser = message.Data;
187
+ });
188
+ ```
189
+
190
+ #### ⚠️ Important Behavioral Difference: Duplicate Subscriptions
191
+
192
+ **WeakReferenceMessenger** throws an `InvalidOperationException` if you try to register the same message type multiple times on the same recipient (MessagingCenter allowed this):
193
+
194
+ ```csharp
195
+ // ❌ This THROWS InvalidOperationException in WeakReferenceMessenger
196
+ WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(this, (r, m) => Handler1(m));
197
+ WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(this, (r, m) => Handler2(m)); // ❌ THROWS!
198
+
199
+ // ✅ Solution 1: Unregister before re-registering
200
+ WeakReferenceMessenger.Default.Unregister<UserLoggedInMessage>(this);
201
+ WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(this, (r, m) => Handler1(m));
202
+
203
+ // ✅ Solution 2: Handle multiple actions in one registration
204
+ WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(this, (r, m) =>
205
+ {
206
+ Handler1(m);
207
+ Handler2(m);
208
+ });
209
+ ```
210
+
211
+ **Why this matters:** If your code subscribes to the same message in multiple places (e.g., in a page constructor and in `OnAppearing`), you'll get a runtime crash.
212
+
213
+ #### Step 5: Unregister When Done
214
+
215
+ ```csharp
216
+ // ❌ OLD
217
+ MessagingCenter.Unsubscribe<App, UserData>(this, "UserLoggedIn");
218
+
219
+ // ✅ NEW (CRITICAL - prevents memory leaks)
220
+ WeakReferenceMessenger.Default.Unregister<UserLoggedInMessage>(this);
221
+
222
+ // Or unregister all messages for this recipient
223
+ WeakReferenceMessenger.Default.UnregisterAll(this);
224
+ ```
225
+
226
+ #### Complete Before/After Example
227
+
228
+ **Before (.NET 9):**
229
+ ```csharp
230
+ // Sender
231
+ public class LoginViewModel
232
+ {
233
+ public async Task LoginAsync()
234
+ {
235
+ var user = await AuthService.LoginAsync(username, password);
236
+ MessagingCenter.Send(this, "UserLoggedIn", user);
237
+ }
238
+ }
239
+
240
+ // Receiver
241
+ public partial class MainPage : ContentPage
242
+ {
243
+ public MainPage()
244
+ {
245
+ InitializeComponent();
246
+
247
+ MessagingCenter.Subscribe<LoginViewModel, User>(this, "UserLoggedIn", (sender, user) =>
248
+ {
249
+ WelcomeLabel.Text = $"Welcome, {user.Name}!";
250
+ });
251
+ }
252
+
253
+ protected override void OnDisappearing()
254
+ {
255
+ base.OnDisappearing();
256
+ MessagingCenter.Unsubscribe<LoginViewModel, User>(this, "UserLoggedIn");
257
+ }
258
+ }
259
+ ```
260
+
261
+ **After (.NET 10):**
262
+ ```csharp
263
+ // 1. Define message
264
+ public class UserLoggedInMessage
265
+ {
266
+ public User User { get; }
267
+
268
+ public UserLoggedInMessage(User user)
269
+ {
270
+ User = user;
271
+ }
272
+ }
273
+
274
+ // 2. Sender
275
+ public class LoginViewModel
276
+ {
277
+ public async Task LoginAsync()
278
+ {
279
+ var user = await AuthService.LoginAsync(username, password);
280
+ WeakReferenceMessenger.Default.Send(new UserLoggedInMessage(user));
281
+ }
282
+ }
283
+
284
+ // 3. Receiver
285
+ public partial class MainPage : ContentPage
286
+ {
287
+ public MainPage()
288
+ {
289
+ InitializeComponent();
290
+
291
+ WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(this, (recipient, message) =>
292
+ {
293
+ WelcomeLabel.Text = $"Welcome, {message.User.Name}!";
294
+ });
295
+ }
296
+
297
+ protected override void OnDisappearing()
298
+ {
299
+ base.OnDisappearing();
300
+ WeakReferenceMessenger.Default.UnregisterAll(this);
301
+ }
302
+ }
303
+ ```
304
+
305
+ **Key Differences:**
306
+ - ✅ Type-safe message classes
307
+ - ✅ No magic strings
308
+ - ✅ Better IntelliSense support
309
+ - ✅ Easier to refactor
310
+ - ⚠️ **Must remember to unregister!**
311
+
312
+ ---
313
+
314
+ ### ListView and TableView Deprecated
315
+
316
+ **Status:** 🚨 **DEPRECATED (P0)** - `ListView`, `TableView`, and all Cell types are now obsolete. Migrate to `CollectionView`.
317
+
318
+ **Warning You'll See:**
319
+ ```
320
+ warning CS0618: 'ListView' is obsolete: 'ListView is deprecated. Please use CollectionView instead.'
321
+ warning CS0618: 'TableView' is obsolete: 'Please use CollectionView instead.'
322
+ warning CS0618: 'TextCell' is obsolete: 'The controls which use TextCell (ListView and TableView) are obsolete. Please use CollectionView instead.'
323
+ ```
324
+
325
+ **Obsolete Types:**
326
+ - `ListView` → `CollectionView`
327
+ - `TableView` → `CollectionView` (for settings pages, consider vertical StackLayout with BindableLayout)
328
+ - `TextCell` → Custom DataTemplate with Label(s)
329
+ - `ImageCell` → Custom DataTemplate with Image + Label(s)
330
+ - `EntryCell` → Custom DataTemplate with Entry
331
+ - `SwitchCell` → Custom DataTemplate with Switch
332
+ - `ViewCell` → DataTemplate
333
+
334
+ **Impact:** This is a **MAJOR** breaking change. ListView and TableView are among the most commonly used controls in MAUI apps.
335
+
336
+ #### Why This Takes Time
337
+
338
+ Converting ListView/TableView to CollectionView is not a simple find-replace:
339
+
340
+ 1. **Different event model** - `ItemSelected` → `SelectionChanged` with different arguments
341
+ 2. **Different grouping** - GroupDisplayBinding no longer exists
342
+ 3. **Context actions** - Must convert to SwipeView
343
+ 4. **Item sizing** - `HasUnevenRows` handled differently
344
+ 5. **Platform-specific code** - iOS/Android ListView platform configurations need removal
345
+ 6. **Testing required** - CollectionView virtualizes differently, may affect performance
346
+
347
+ #### Migration Strategy
348
+
349
+ **Step 1: Inventory Your ListViews**
350
+
351
+ ```bash
352
+ # Find all ListView/TableView usages
353
+ grep -r "ListView\|TableView" --include="*.xaml" --include="*.cs" .
354
+ ```
355
+
356
+ **Step 2: Basic ListView → CollectionView**
357
+
358
+ **Before (ListView):**
359
+ ```xaml
360
+ <ListView ItemsSource="{Binding Items}"
361
+ ItemSelected="OnItemSelected"
362
+ HasUnevenRows="True">
363
+ <ListView.ItemTemplate>
364
+ <DataTemplate>
365
+ <TextCell Text="{Binding Title}"
366
+ Detail="{Binding Description}" />
367
+ </DataTemplate>
368
+ </ListView.ItemTemplate>
369
+ </ListView>
370
+ ```
371
+
372
+ **After (CollectionView):**
373
+ ```xaml
374
+ <CollectionView ItemsSource="{Binding Items}"
375
+ SelectionMode="Single"
376
+ SelectionChanged="OnSelectionChanged">
377
+ <CollectionView.ItemTemplate>
378
+ <DataTemplate>
379
+ <VerticalStackLayout Padding="10">
380
+ <Label Text="{Binding Title}"
381
+ FontAttributes="Bold" />
382
+ <Label Text="{Binding Description}"
383
+ FontSize="12"
384
+ TextColor="{StaticResource Gray600}" />
385
+ </VerticalStackLayout>
386
+ </DataTemplate>
387
+ </CollectionView.ItemTemplate>
388
+ </CollectionView>
389
+ ```
390
+
391
+ > ⚠️ **Note:** CollectionView has `SelectionMode="None"` by default (selection disabled). You must explicitly set `SelectionMode="Single"` or `SelectionMode="Multiple"` to enable selection.
392
+
393
+ **Code-behind changes:**
394
+ ```csharp
395
+ // ❌ OLD (ListView)
396
+ void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
397
+ {
398
+ if (e.SelectedItem == null)
399
+ return;
400
+
401
+ var item = (MyItem)e.SelectedItem;
402
+ // Handle selection
403
+
404
+ // Deselect
405
+ ((ListView)sender).SelectedItem = null;
406
+ }
407
+
408
+ // ✅ NEW (CollectionView)
409
+ void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
410
+ {
411
+ if (e.CurrentSelection.Count == 0)
412
+ return;
413
+
414
+ var item = (MyItem)e.CurrentSelection.FirstOrDefault();
415
+ // Handle selection
416
+
417
+ // Deselect (optional)
418
+ ((CollectionView)sender).SelectedItem = null;
419
+ }
420
+ ```
421
+
422
+ **Step 3: Grouped ListView → Grouped CollectionView**
423
+
424
+ **Before (Grouped ListView):**
425
+ ```xaml
426
+ <ListView ItemsSource="{Binding GroupedItems}"
427
+ IsGroupingEnabled="True"
428
+ GroupDisplayBinding="{Binding Key}">
429
+ <ListView.ItemTemplate>
430
+ <DataTemplate>
431
+ <TextCell Text="{Binding Name}" />
432
+ </DataTemplate>
433
+ </ListView.ItemTemplate>
434
+ </ListView>
435
+ ```
436
+
437
+ **After (Grouped CollectionView):**
438
+ ```xaml
439
+ <CollectionView ItemsSource="{Binding GroupedItems}"
440
+ IsGrouped="true">
441
+ <CollectionView.GroupHeaderTemplate>
442
+ <DataTemplate>
443
+ <Label Text="{Binding Key}"
444
+ FontAttributes="Bold"
445
+ BackgroundColor="{StaticResource Gray100}"
446
+ Padding="10,5" />
447
+ </DataTemplate>
448
+ </CollectionView.GroupHeaderTemplate>
449
+
450
+ <CollectionView.ItemTemplate>
451
+ <DataTemplate>
452
+ <VerticalStackLayout Padding="20,10">
453
+ <Label Text="{Binding Name}" />
454
+ </VerticalStackLayout>
455
+ </DataTemplate>
456
+ </CollectionView.ItemTemplate>
457
+ </CollectionView>
458
+ ```
459
+
460
+ **Step 4: Context Actions → SwipeView**
461
+
462
+ > ⚠️ **Platform Note:** SwipeView requires touch input. On Windows desktop, it only works with touch screens, not with mouse/trackpad. Consider providing alternative UI for desktop scenarios (e.g., buttons, right-click menu).
463
+
464
+ **Before (ListView with ContextActions):**
465
+ ```xaml
466
+ <ListView.ItemTemplate>
467
+ <DataTemplate>
468
+ <ViewCell>
469
+ <ViewCell.ContextActions>
470
+ <MenuItem Text="Delete"
471
+ IsDestructive="True"
472
+ Command="{Binding Source={RelativeSource AncestorType={x:Type local:MyPage}}, Path=DeleteCommand}"
473
+ CommandParameter="{Binding .}" />
474
+ </ViewCell.ContextActions>
475
+
476
+ <Label Text="{Binding Title}" Padding="10" />
477
+ </ViewCell>
478
+ </DataTemplate>
479
+ </ListView.ItemTemplate>
480
+ ```
481
+
482
+ **After (CollectionView with SwipeView):**
483
+ ```xaml
484
+ <CollectionView.ItemTemplate>
485
+ <DataTemplate>
486
+ <SwipeView>
487
+ <SwipeView.RightItems>
488
+ <SwipeItems>
489
+ <SwipeItem Text="Delete"
490
+ BackgroundColor="Red"
491
+ Command="{Binding Source={RelativeSource AncestorType={x:Type local:MyPage}}, Path=DeleteCommand}"
492
+ CommandParameter="{Binding .}" />
493
+ </SwipeItems>
494
+ </SwipeView.RightItems>
495
+
496
+ <VerticalStackLayout Padding="10">
497
+ <Label Text="{Binding Title}" />
498
+ </VerticalStackLayout>
499
+ </SwipeView>
500
+ </DataTemplate>
501
+ </CollectionView.ItemTemplate>
502
+ ```
503
+
504
+ **Step 5: TableView for Settings → Alternative Approaches**
505
+
506
+ TableView is commonly used for settings pages. Here are modern alternatives:
507
+
508
+ **Option 1: CollectionView with Grouped Data**
509
+ ```xaml
510
+ <CollectionView ItemsSource="{Binding SettingGroups}"
511
+ IsGrouped="true"
512
+ SelectionMode="None">
513
+ <CollectionView.GroupHeaderTemplate>
514
+ <DataTemplate>
515
+ <Label Text="{Binding Title}"
516
+ FontAttributes="Bold"
517
+ Margin="10,15,10,5" />
518
+ </DataTemplate>
519
+ </CollectionView.GroupHeaderTemplate>
520
+
521
+ <CollectionView.ItemTemplate>
522
+ <DataTemplate>
523
+ <Grid Padding="15,10" ColumnDefinitions="*,Auto">
524
+ <Label Text="{Binding Title}"
525
+ VerticalOptions="Center" />
526
+ <Switch Grid.Column="1"
527
+ IsToggled="{Binding IsEnabled}"
528
+ IsVisible="{Binding ShowSwitch}" />
529
+ </Grid>
530
+ </DataTemplate>
531
+ </CollectionView.ItemTemplate>
532
+ </CollectionView>
533
+ ```
534
+
535
+ **Option 2: Vertical StackLayout (for small settings lists)**
536
+ ```xaml
537
+ <ScrollView>
538
+ <VerticalStackLayout BindableLayout.ItemsSource="{Binding Settings}"
539
+ Spacing="10"
540
+ Padding="15">
541
+ <BindableLayout.ItemTemplate>
542
+ <DataTemplate>
543
+ <Border StrokeThickness="0"
544
+ BackgroundColor="{StaticResource Gray100}"
545
+ Padding="15,10">
546
+ <Grid ColumnDefinitions="*,Auto">
547
+ <Label Text="{Binding Title}"
548
+ VerticalOptions="Center" />
549
+ <Switch Grid.Column="1"
550
+ IsToggled="{Binding IsEnabled}" />
551
+ </Grid>
552
+ </Border>
553
+ </DataTemplate>
554
+ </BindableLayout.ItemTemplate>
555
+ </VerticalStackLayout>
556
+ </ScrollView>
557
+ ```
558
+
559
+ **Step 6: Remove Platform-Specific ListView Code**
560
+
561
+ If you used platform-specific ListView features, remove them:
562
+
563
+ ```csharp
564
+ // ❌ OLD - Remove these using statements (NOW OBSOLETE IN .NET 10)
565
+ using Microsoft.Maui.Controls.PlatformConfiguration;
566
+ using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
567
+ using Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific;
568
+
569
+ // ❌ OLD - Remove ListView platform configurations (NOW OBSOLETE IN .NET 10)
570
+ myListView.On<iOS>().SetSeparatorStyle(SeparatorStyle.FullWidth);
571
+ myListView.On<Android>().IsFastScrollEnabled();
572
+
573
+ // ❌ OLD - Remove Cell platform configurations (NOW OBSOLETE IN .NET 10)
574
+ viewCell.On<iOS>().SetDefaultBackgroundColor(Colors.White);
575
+ viewCell.On<Android>().SetIsContextActionsLegacyModeEnabled(false);
576
+ ```
577
+
578
+ **Migration:** CollectionView does not have platform-specific configurations in the same way. If you need platform-specific styling:
579
+
580
+ ```csharp
581
+ // ✅ NEW - Use conditional compilation
582
+ #if IOS
583
+ var backgroundColor = Colors.White;
584
+ #elif ANDROID
585
+ var backgroundColor = Colors.Transparent;
586
+ #endif
587
+
588
+ var grid = new Grid
589
+ {
590
+ BackgroundColor = backgroundColor,
591
+ // ... rest of cell content
592
+ };
593
+ ```
594
+
595
+ Or in XAML:
596
+ ```xaml
597
+ <CollectionView.ItemTemplate>
598
+ <DataTemplate>
599
+ <Grid>
600
+ <Grid.BackgroundColor>
601
+ <OnPlatform x:TypeArguments="Color">
602
+ <On Platform="iOS" Value="White" />
603
+ <On Platform="Android" Value="Transparent" />
604
+ </OnPlatform>
605
+ </Grid.BackgroundColor>
606
+ <!-- Cell content -->
607
+ </Grid>
608
+ </DataTemplate>
609
+ </CollectionView.ItemTemplate>
610
+ ```
611
+
612
+ #### Common Patterns & Pitfalls
613
+
614
+ **1. Empty View**
615
+ ```xaml
616
+ <!-- CollectionView has built-in EmptyView support -->
617
+ <CollectionView ItemsSource="{Binding Items}">
618
+ <CollectionView.EmptyView>
619
+ <ContentView>
620
+ <VerticalStackLayout Padding="50" VerticalOptions="Center">
621
+ <Label Text="No items found"
622
+ HorizontalTextAlignment="Center" />
623
+ </VerticalStackLayout>
624
+ </ContentView>
625
+ </CollectionView.EmptyView>
626
+ <!-- ... -->
627
+ </CollectionView>
628
+ ```
629
+
630
+ **2. Pull to Refresh**
631
+ ```xaml
632
+ <RefreshView IsRefreshing="{Binding IsRefreshing}"
633
+ Command="{Binding RefreshCommand}">
634
+ <CollectionView ItemsSource="{Binding Items}">
635
+ <!-- ... -->
636
+ </CollectionView>
637
+ </RefreshView>
638
+ ```
639
+
640
+ **3. Item Spacing**
641
+ ```xaml
642
+ <!-- Use ItemsLayout for spacing -->
643
+ <CollectionView ItemsSource="{Binding Items}">
644
+ <CollectionView.ItemsLayout>
645
+ <LinearItemsLayout Orientation="Vertical"
646
+ ItemSpacing="10" />
647
+ </CollectionView.ItemsLayout>
648
+ <!-- ... -->
649
+ </CollectionView>
650
+ ```
651
+
652
+ **4. Header and Footer**
653
+ ```xaml
654
+ <CollectionView ItemsSource="{Binding Items}">
655
+ <CollectionView.Header>
656
+ <Label Text="My List"
657
+ FontSize="24"
658
+ Padding="10" />
659
+ </CollectionView.Header>
660
+
661
+ <CollectionView.Footer>
662
+ <Label Text="End of list"
663
+ Padding="10"
664
+ HorizontalTextAlignment="Center" />
665
+ </CollectionView.Footer>
666
+
667
+ <!-- ItemTemplate -->
668
+ </CollectionView>
669
+ ```
670
+
671
+ **5. Load More / Infinite Scroll**
672
+ ```xaml
673
+ <CollectionView ItemsSource="{Binding Items}"
674
+ RemainingItemsThreshold="5"
675
+ RemainingItemsThresholdReachedCommand="{Binding LoadMoreCommand}">
676
+ <!-- ItemTemplate -->
677
+ </CollectionView>
678
+ ```
679
+
680
+ **6. Item Sizing Optimization**
681
+
682
+ CollectionView uses `ItemSizingStrategy` to control item measurement:
683
+
684
+ ```xaml
685
+ <!-- Default: Each item measured individually (like HasUnevenRows="True") -->
686
+ <CollectionView ItemSizingStrategy="MeasureAllItems">
687
+ <!-- ... -->
688
+ </CollectionView>
689
+
690
+ <!-- Performance: Only first item measured, rest use same height -->
691
+ <CollectionView ItemSizingStrategy="MeasureFirstItem">
692
+ <!-- Use this when all items have similar heights -->
693
+ </CollectionView>
694
+ ```
695
+
696
+ > 💡 **Performance Tip:** If your list items have consistent heights, use `ItemSizingStrategy="MeasureFirstItem"` for better performance with large lists.
697
+
698
+ #### .NET 10 Handler Changes (iOS/Mac Catalyst)
699
+
700
+ > ℹ️ **.NET 10 uses new optimized CollectionView and CarouselView handlers** on iOS and Mac Catalyst by default, providing improved performance and stability.
701
+
702
+ **If you previously opted-in to the new handlers in .NET 9**, you should now **REMOVE** this code:
703
+
704
+ ```csharp
705
+ // ❌ REMOVE THIS in .NET 10 (these handlers are now default)
706
+ #if IOS || MACCATALYST
707
+ builder.ConfigureMauiHandlers(handlers =>
708
+ {
709
+ handlers.AddHandler<CollectionView, CollectionViewHandler2>();
710
+ handlers.AddHandler<CarouselView, CarouselViewHandler2>();
711
+ });
712
+ #endif
713
+ ```
714
+
715
+ The optimized handlers are used automatically in .NET 10 - no configuration needed!
716
+
717
+ **Only if you experience issues**, you can revert to the legacy handler:
718
+
719
+ ```csharp
720
+ // In MauiProgram.cs - only if needed
721
+ #if IOS || MACCATALYST
722
+ builder.ConfigureMauiHandlers(handlers =>
723
+ {
724
+ handlers.AddHandler<Microsoft.Maui.Controls.CollectionView,
725
+ Microsoft.Maui.Controls.Handlers.Items.CollectionViewHandler>();
726
+ });
727
+ #endif
728
+ ```
729
+
730
+ However, Microsoft recommends using the new default handlers for best results.
731
+
732
+ #### Testing Checklist
733
+
734
+ After migration, test these scenarios:
735
+
736
+ - [ ] **Item selection** works correctly
737
+ - [ ] **Grouped lists** display with proper headers
738
+ - [ ] **Swipe actions** (if used) work on both iOS and Android
739
+ - [ ] **Empty view** appears when list is empty
740
+ - [ ] **Pull to refresh** works (if used)
741
+ - [ ] **Scroll performance** is acceptable (especially for large lists)
742
+ - [ ] **Item sizing** is correct (CollectionView auto-sizes by default)
743
+ - [ ] **Selection visual state** shows/hides correctly
744
+ - [ ] **Data binding** updates the list correctly
745
+ - [ ] **Navigation** from list items works
746
+
747
+ #### Migration Complexity Factors
748
+
749
+ ListView to CollectionView migration is complex because:
750
+ - Each ListView may have unique behaviors
751
+ - Platform-specific code needs updating
752
+ - Extensive testing required
753
+ - Context actions need SwipeView conversion
754
+ - Grouped lists need template updates
755
+ - ViewModel changes may be needed
756
+
757
+ #### Quick Reference: ListView vs CollectionView
758
+
759
+ | Feature | ListView | CollectionView |
760
+ |---------|----------|----------------|
761
+ | **Selection Event** | `ItemSelected` | `SelectionChanged` |
762
+ | **Selection Args** | `SelectedItemChangedEventArgs` | `SelectionChangedEventArgs` |
763
+ | **Getting Selected** | `e.SelectedItem` | `e.CurrentSelection.FirstOrDefault()` |
764
+ | **Context Menus** | `ContextActions` | `SwipeView` |
765
+ | **Grouping** | `IsGroupingEnabled="True"` | `IsGrouped="true"` |
766
+ | **Group Header** | `GroupDisplayBinding` | `GroupHeaderTemplate` |
767
+ | **Even Rows** | `HasUnevenRows="False"` | Auto-sizes (default) |
768
+ | **Empty State** | Manual | `EmptyView` property |
769
+ | **Cells** | TextCell, ImageCell, etc. | Custom DataTemplate |
770
+
771
+ ---
772
+
773
+ ## Deprecated APIs (P1 - Fix Soon)
774
+
775
+ These APIs still work in .NET 10 but show compiler warnings. They will be removed in future versions.
776
+
777
+ ### 1. Animation Methods
778
+
779
+ **Status:** ⚠️ **DEPRECATED** - All sync animation methods replaced with async versions.
780
+
781
+ **Warning You'll See:**
782
+ ```
783
+ warning CS0618: 'ViewExtensions.FadeTo(VisualElement, double, uint, Easing)' is obsolete: 'Please use FadeToAsync instead.'
784
+ ```
785
+
786
+ **Migration Table:**
787
+
788
+ | Old Method | New Method | Example |
789
+ |-----------|-----------|---------|
790
+ | `FadeTo()` | `FadeToAsync()` | `await view.FadeToAsync(0, 500);` |
791
+ | `ScaleTo()` | `ScaleToAsync()` | `await view.ScaleToAsync(1.5, 300);` |
792
+ | `TranslateTo()` | `TranslateToAsync()` | `await view.TranslateToAsync(100, 100, 250);` |
793
+ | `RotateTo()` | `RotateToAsync()` | `await view.RotateToAsync(360, 500);` |
794
+ | `RotateXTo()` | `RotateXToAsync()` | `await view.RotateXToAsync(45, 300);` |
795
+ | `RotateYTo()` | `RotateYToAsync()` | `await view.RotateYToAsync(45, 300);` |
796
+ | `ScaleXTo()` | `ScaleXToAsync()` | `await view.ScaleXToAsync(2.0, 300);` |
797
+ | `ScaleYTo()` | `ScaleYToAsync()` | `await view.ScaleYToAsync(2.0, 300);` |
798
+ | `RelRotateTo()` | `RelRotateToAsync()` | `await view.RelRotateToAsync(90, 300);` |
799
+ | `RelScaleTo()` | `RelScaleToAsync()` | `await view.RelScaleToAsync(0.5, 300);` |
800
+ | `LayoutTo()` | `LayoutToAsync()` | See special note below |
801
+
802
+ #### Migration Examples
803
+
804
+ **Simple Animation:**
805
+ ```csharp
806
+ // ❌ OLD (Deprecated)
807
+ await myButton.FadeTo(0, 500);
808
+ await myButton.ScaleTo(1.5, 300);
809
+ await myButton.TranslateTo(100, 100, 250);
810
+
811
+ // ✅ NEW (Required)
812
+ await myButton.FadeToAsync(0, 500);
813
+ await myButton.ScaleToAsync(1.5, 300);
814
+ await myButton.TranslateToAsync(100, 100, 250);
815
+ ```
816
+
817
+ **Sequential Animations:**
818
+ ```csharp
819
+ // ❌ OLD
820
+ await image.FadeTo(0, 300);
821
+ await image.ScaleTo(0.5, 300);
822
+ await image.FadeTo(1, 300);
823
+
824
+ // ✅ NEW
825
+ await image.FadeToAsync(0, 300);
826
+ await image.ScaleToAsync(0.5, 300);
827
+ await image.FadeToAsync(1, 300);
828
+ ```
829
+
830
+ **Parallel Animations:**
831
+ ```csharp
832
+ // ❌ OLD
833
+ await Task.WhenAll(
834
+ image.FadeTo(0, 300),
835
+ image.ScaleTo(0.5, 300),
836
+ image.RotateTo(360, 300)
837
+ );
838
+
839
+ // ✅ NEW
840
+ await Task.WhenAll(
841
+ image.FadeToAsync(0, 300),
842
+ image.ScaleToAsync(0.5, 300),
843
+ image.RotateToAsync(360, 300)
844
+ );
845
+ ```
846
+
847
+ **With Cancellation:**
848
+ ```csharp
849
+ // NEW: Async methods support cancellation
850
+ CancellationTokenSource cts = new();
851
+
852
+ try
853
+ {
854
+ await view.FadeToAsync(0, 2000);
855
+ }
856
+ catch (TaskCanceledException)
857
+ {
858
+ // Animation was cancelled
859
+ }
860
+
861
+ // Cancel from elsewhere
862
+ cts.Cancel();
863
+ ```
864
+
865
+ #### Special Case: LayoutTo
866
+
867
+ `LayoutToAsync()` is deprecated with a special message: "Use Translation to animate layout changes."
868
+
869
+ ```csharp
870
+ // ❌ OLD (Deprecated)
871
+ await view.LayoutToAsync(new Rect(100, 100, 200, 200), 250);
872
+
873
+ // ✅ NEW (Use TranslateToAsync instead)
874
+ await view.TranslateToAsync(100, 100, 250);
875
+
876
+ // Or animate Translation properties directly
877
+ var animation = new Animation(v => view.TranslationX = v, 0, 100);
878
+ animation.Commit(view, "MoveX", length: 250);
879
+ ```
880
+
881
+ ---
882
+
883
+ ### 2. DisplayAlert and DisplayActionSheet
884
+
885
+ **Status:** ⚠️ **DEPRECATED** - Sync methods replaced with async versions.
886
+
887
+ **Warning You'll See:**
888
+ ```
889
+ warning CS0618: 'Page.DisplayAlert(string, string, string)' is obsolete: 'Use DisplayAlertAsync instead'
890
+ ```
891
+
892
+ #### Migration Examples
893
+
894
+ **DisplayAlert:**
895
+ ```csharp
896
+ // ❌ OLD (Deprecated)
897
+ await DisplayAlert("Success", "Data saved successfully", "OK");
898
+ await DisplayAlert("Error", "Failed to save", "Cancel");
899
+ bool result = await DisplayAlert("Confirm", "Delete this item?", "Yes", "No");
900
+
901
+ // ✅ NEW (Required)
902
+ await DisplayAlertAsync("Success", "Data saved successfully", "OK");
903
+ await DisplayAlertAsync("Error", "Failed to save", "Cancel");
904
+ bool result = await DisplayAlertAsync("Confirm", "Delete this item?", "Yes", "No");
905
+ ```
906
+
907
+ **DisplayActionSheet:**
908
+ ```csharp
909
+ // ❌ OLD (Deprecated)
910
+ string action = await DisplayActionSheet(
911
+ "Choose an action",
912
+ "Cancel",
913
+ "Delete",
914
+ "Edit", "Share", "Duplicate"
915
+ );
916
+
917
+ // ✅ NEW (Required)
918
+ string action = await DisplayActionSheetAsync(
919
+ "Choose an action",
920
+ "Cancel",
921
+ "Delete",
922
+ "Edit", "Share", "Duplicate"
923
+ );
924
+ ```
925
+
926
+ **In ViewModels (with IDispatcher):**
927
+ ```csharp
928
+ // If you're calling from a ViewModel, you'll need access to a Page
929
+ public class MyViewModel
930
+ {
931
+ private readonly IDispatcher _dispatcher;
932
+ private readonly Page _page;
933
+
934
+ public MyViewModel(IDispatcher dispatcher, Page page)
935
+ {
936
+ _dispatcher = dispatcher;
937
+ _page = page;
938
+ }
939
+
940
+ public async Task ShowAlertAsync()
941
+ {
942
+ await _dispatcher.DispatchAsync(async () =>
943
+ {
944
+ await _page.DisplayAlertAsync("Info", "Message from ViewModel", "OK");
945
+ });
946
+ }
947
+ }
948
+ ```
949
+
950
+ ---
951
+
952
+ ### 3. Page.IsBusy
953
+
954
+ **Status:** ⚠️ **DEPRECATED** - Property will be removed in .NET 11.
955
+
956
+ **Warning You'll See:**
957
+ ```
958
+ warning CS0618: 'Page.IsBusy' is obsolete: 'Page.IsBusy has been deprecated and will be removed in .NET 11'
959
+ ```
960
+
961
+ **Why It's Deprecated:**
962
+ - Inconsistent behavior across platforms
963
+ - Limited customization options
964
+ - Doesn't work well with modern MVVM patterns
965
+
966
+ #### Migration Examples
967
+
968
+ **Simple Page:**
969
+ ```xaml
970
+ <!-- ❌ OLD (Deprecated) -->
971
+ <ContentPage IsBusy="{Binding IsLoading}">
972
+ <StackLayout>
973
+ <Label Text="Content here" />
974
+ </StackLayout>
975
+ </ContentPage>
976
+
977
+ <!-- ✅ NEW (Recommended) -->
978
+ <ContentPage>
979
+ <Grid>
980
+ <!-- Main content -->
981
+ <StackLayout>
982
+ <Label Text="Content here" />
983
+ </StackLayout>
984
+
985
+ <!-- Loading indicator overlay -->
986
+ <ActivityIndicator IsRunning="{Binding IsLoading}"
987
+ IsVisible="{Binding IsLoading}"
988
+ Color="{StaticResource Primary}"
989
+ VerticalOptions="Center"
990
+ HorizontalOptions="Center" />
991
+ </Grid>
992
+ </ContentPage>
993
+ ```
994
+
995
+ **With Loading Overlay:**
996
+ ```xaml
997
+ <!-- ✅ Better: Custom loading overlay -->
998
+ <ContentPage>
999
+ <Grid>
1000
+ <!-- Main content -->
1001
+ <ScrollView>
1002
+ <VerticalStackLayout Padding="20">
1003
+ <Label Text="Your content here" />
1004
+ </VerticalStackLayout>
1005
+ </ScrollView>
1006
+
1007
+ <!-- Loading overlay -->
1008
+ <Grid IsVisible="{Binding IsLoading}"
1009
+ BackgroundColor="#80000000">
1010
+ <VerticalStackLayout VerticalOptions="Center"
1011
+ HorizontalOptions="Center"
1012
+ Spacing="10">
1013
+ <ActivityIndicator IsRunning="True"
1014
+ Color="White" />
1015
+ <Label Text="Loading..."
1016
+ TextColor="White" />
1017
+ </VerticalStackLayout>
1018
+ </Grid>
1019
+ </Grid>
1020
+ </ContentPage>
1021
+ ```
1022
+
1023
+ **In Code-Behind:**
1024
+ ```csharp
1025
+ // ❌ OLD (Deprecated)
1026
+ public partial class MyPage : ContentPage
1027
+ {
1028
+ async Task LoadDataAsync()
1029
+ {
1030
+ IsBusy = true;
1031
+ try
1032
+ {
1033
+ await LoadDataFromServerAsync();
1034
+ }
1035
+ finally
1036
+ {
1037
+ IsBusy = false;
1038
+ }
1039
+ }
1040
+ }
1041
+
1042
+ // ✅ NEW (Recommended)
1043
+ public partial class MyPage : ContentPage
1044
+ {
1045
+ async Task LoadDataAsync()
1046
+ {
1047
+ LoadingIndicator.IsVisible = true;
1048
+ LoadingIndicator.IsRunning = true;
1049
+ try
1050
+ {
1051
+ await LoadDataFromServerAsync();
1052
+ }
1053
+ finally
1054
+ {
1055
+ LoadingIndicator.IsVisible = false;
1056
+ LoadingIndicator.IsRunning = false;
1057
+ }
1058
+ }
1059
+ }
1060
+ ```
1061
+
1062
+ **In ViewModel:**
1063
+ ```csharp
1064
+ public class MyViewModel : INotifyPropertyChanged
1065
+ {
1066
+ private bool _isLoading;
1067
+ public bool IsLoading
1068
+ {
1069
+ get => _isLoading;
1070
+ set
1071
+ {
1072
+ _isLoading = value;
1073
+ OnPropertyChanged();
1074
+ }
1075
+ }
1076
+
1077
+ public async Task LoadDataAsync()
1078
+ {
1079
+ IsLoading = true;
1080
+ try
1081
+ {
1082
+ await LoadDataFromServerAsync();
1083
+ }
1084
+ finally
1085
+ {
1086
+ IsLoading = false;
1087
+ }
1088
+ }
1089
+ }
1090
+ ```
1091
+
1092
+ ---
1093
+
1094
+ ### 4. MediaPicker APIs
1095
+
1096
+ **Status:** ⚠️ **DEPRECATED** - Single-selection methods replaced with multi-selection variants.
1097
+
1098
+ **Warning You'll See:**
1099
+ ```
1100
+ warning CS0618: 'MediaPicker.PickPhotoAsync(MediaPickerOptions)' is obsolete: 'Switch to PickPhotosAsync which also allows multiple selections.'
1101
+ warning CS0618: 'MediaPicker.PickVideoAsync(MediaPickerOptions)' is obsolete: 'Switch to PickVideosAsync which also allows multiple selections.'
1102
+ ```
1103
+
1104
+ **What Changed:**
1105
+ - `PickPhotoAsync()` → `PickPhotosAsync()` (returns `List<FileResult>`)
1106
+ - `PickVideoAsync()` → `PickVideosAsync()` (returns `List<FileResult>`)
1107
+ - New `SelectionLimit` property on `MediaPickerOptions` (default: 1)
1108
+ - Old methods still work but are marked obsolete
1109
+
1110
+ **Key Behavior:**
1111
+ - **Default behavior preserved:** `SelectionLimit = 1` (single selection)
1112
+ - Set `SelectionLimit = 0` for unlimited multi-select
1113
+ - Set `SelectionLimit > 1` for specific limits
1114
+
1115
+ **Platform Notes:**
1116
+ - ✅ **iOS:** Selection limit enforced by native picker UI
1117
+ - ⚠️ **Android:** Not all custom pickers honor `SelectionLimit` - be aware!
1118
+ - ⚠️ **Windows:** `SelectionLimit` not supported - implement your own validation
1119
+
1120
+ #### Migration Examples
1121
+
1122
+ **Simple Photo Picker (maintain single-selection behavior):**
1123
+ ```csharp
1124
+ // ❌ OLD (Deprecated)
1125
+ var photo = await MediaPicker.PickPhotoAsync(new MediaPickerOptions
1126
+ {
1127
+ Title = "Pick a photo"
1128
+ });
1129
+
1130
+ if (photo != null)
1131
+ {
1132
+ var stream = await photo.OpenReadAsync();
1133
+ MyImage.Source = ImageSource.FromStream(() => stream);
1134
+ }
1135
+
1136
+ // ✅ NEW (maintains same behavior - picks only 1 photo)
1137
+ var photos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
1138
+ {
1139
+ Title = "Pick a photo",
1140
+ SelectionLimit = 1 // Explicit: only 1 photo
1141
+ });
1142
+
1143
+ var photo = photos.FirstOrDefault();
1144
+ if (photo != null)
1145
+ {
1146
+ var stream = await photo.OpenReadAsync();
1147
+ MyImage.Source = ImageSource.FromStream(() => stream);
1148
+ }
1149
+ ```
1150
+
1151
+ **Simple Video Picker (maintain single-selection behavior):**
1152
+ ```csharp
1153
+ // ❌ OLD (Deprecated)
1154
+ var video = await MediaPicker.PickVideoAsync(new MediaPickerOptions
1155
+ {
1156
+ Title = "Pick a video"
1157
+ });
1158
+
1159
+ if (video != null)
1160
+ {
1161
+ VideoPlayer.Source = video.FullPath;
1162
+ }
1163
+
1164
+ // ✅ NEW (maintains same behavior - picks only 1 video)
1165
+ var videos = await MediaPicker.PickVideosAsync(new MediaPickerOptions
1166
+ {
1167
+ Title = "Pick a video",
1168
+ SelectionLimit = 1 // Explicit: only 1 video
1169
+ });
1170
+
1171
+ var video = videos.FirstOrDefault();
1172
+ if (video != null)
1173
+ {
1174
+ VideoPlayer.Source = video.FullPath;
1175
+ }
1176
+ ```
1177
+
1178
+ **Photo Picker without Options (uses defaults):**
1179
+ ```csharp
1180
+ // ❌ OLD (Deprecated)
1181
+ var photo = await MediaPicker.PickPhotoAsync();
1182
+
1183
+ // ✅ NEW (default SelectionLimit = 1, so same behavior)
1184
+ var photos = await MediaPicker.PickPhotosAsync();
1185
+ var photo = photos.FirstOrDefault();
1186
+ ```
1187
+
1188
+ **Multi-Photo Selection (new capability):**
1189
+ ```csharp
1190
+ // ✅ NEW: Pick up to 5 photos
1191
+ var photos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
1192
+ {
1193
+ Title = "Pick up to 5 photos",
1194
+ SelectionLimit = 5
1195
+ });
1196
+
1197
+ foreach (var photo in photos)
1198
+ {
1199
+ var stream = await photo.OpenReadAsync();
1200
+ // Process each photo
1201
+ }
1202
+
1203
+ // ✅ NEW: Unlimited selection
1204
+ var allPhotos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
1205
+ {
1206
+ Title = "Pick photos",
1207
+ SelectionLimit = 0 // No limit
1208
+ });
1209
+ ```
1210
+
1211
+ **Multi-Video Selection (new capability):**
1212
+ ```csharp
1213
+ // ✅ NEW: Pick up to 3 videos
1214
+ var videos = await MediaPicker.PickVideosAsync(new MediaPickerOptions
1215
+ {
1216
+ Title = "Pick up to 3 videos",
1217
+ SelectionLimit = 3
1218
+ });
1219
+
1220
+ foreach (var video in videos)
1221
+ {
1222
+ // Process each video
1223
+ Console.WriteLine($"Selected: {video.FileName}");
1224
+ }
1225
+ ```
1226
+
1227
+ **Handling Empty Results:**
1228
+ ```csharp
1229
+ // NEW: Returns empty list if user cancels (not null)
1230
+ var photos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
1231
+ {
1232
+ SelectionLimit = 1
1233
+ });
1234
+
1235
+ // ✅ Check for empty list
1236
+ if (photos.Count == 0)
1237
+ {
1238
+ await DisplayAlertAsync("Cancelled", "No photo selected", "OK");
1239
+ return;
1240
+ }
1241
+
1242
+ var photo = photos.First();
1243
+ // Process photo...
1244
+ ```
1245
+
1246
+ **With Try-Catch (same as before):**
1247
+ ```csharp
1248
+ try
1249
+ {
1250
+ var photos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
1251
+ {
1252
+ Title = "Pick a photo",
1253
+ SelectionLimit = 1
1254
+ });
1255
+
1256
+ if (photos.Count > 0)
1257
+ {
1258
+ await ProcessPhotoAsync(photos.First());
1259
+ }
1260
+ }
1261
+ catch (PermissionException)
1262
+ {
1263
+ await DisplayAlertAsync("Permission Denied", "Camera access required", "OK");
1264
+ }
1265
+ catch (Exception ex)
1266
+ {
1267
+ await DisplayAlertAsync("Error", $"Failed to pick photo: {ex.Message}", "OK");
1268
+ }
1269
+ ```
1270
+
1271
+ #### Migration Checklist
1272
+
1273
+ When migrating to the new MediaPicker APIs:
1274
+
1275
+ - [ ] Replace `PickPhotoAsync()` with `PickPhotosAsync()`
1276
+ - [ ] Replace `PickVideoAsync()` with `PickVideosAsync()`
1277
+ - [ ] Set `SelectionLimit = 1` to maintain single-selection behavior
1278
+ - [ ] Change `FileResult?` to `List<FileResult>` (or use `.FirstOrDefault()`)
1279
+ - [ ] Update null checks to empty list checks (`photos.Count == 0`)
1280
+ - [ ] Test on Android - ensure custom pickers respect limit (or add validation)
1281
+ - [ ] Test on Windows - add your own limit validation if needed
1282
+ - [ ] Consider if multi-select would improve your UX (optional)
1283
+
1284
+ #### Platform-Specific Validation (Windows & Android)
1285
+
1286
+ ```csharp
1287
+ // ✅ Recommended: Validate selection limit on platforms that don't enforce it
1288
+ var photos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
1289
+ {
1290
+ Title = "Pick up to 5 photos",
1291
+ SelectionLimit = 5
1292
+ });
1293
+
1294
+ // On Windows and some Android pickers, the limit might not be enforced
1295
+ if (photos.Count > 5)
1296
+ {
1297
+ await DisplayAlertAsync(
1298
+ "Too Many Photos",
1299
+ $"Please select up to 5 photos. You selected {photos.Count}.",
1300
+ "OK"
1301
+ );
1302
+ return;
1303
+ }
1304
+
1305
+ // Continue processing...
1306
+ ```
1307
+
1308
+ #### Capture Methods (unchanged)
1309
+
1310
+ **Note:** Capture methods (`CapturePhotoAsync`, `CaptureVideoAsync`) are **NOT** deprecated and remain unchanged:
1311
+
1312
+ ```csharp
1313
+ // ✅ These still work as-is (no changes needed)
1314
+ var photo = await MediaPicker.CapturePhotoAsync();
1315
+ var video = await MediaPicker.CaptureVideoAsync();
1316
+ ```
1317
+
1318
+ #### Quick Migration Pattern
1319
+
1320
+ **For all existing single-selection code, use this pattern:**
1321
+
1322
+ ```csharp
1323
+ // ❌ OLD
1324
+ var photo = await MediaPicker.PickPhotoAsync(options);
1325
+ if (photo != null)
1326
+ {
1327
+ // Process photo
1328
+ }
1329
+
1330
+ // ✅ NEW (drop-in replacement)
1331
+ var photos = await MediaPicker.PickPhotosAsync(options ?? new MediaPickerOptions { SelectionLimit = 1 });
1332
+ var photo = photos.FirstOrDefault();
1333
+ if (photo != null)
1334
+ {
1335
+ // Process photo (same code as before)
1336
+ }
1337
+ ```
1338
+
1339
+ ---
1340
+
1341
+ ## Recommended Changes (P2)
1342
+
1343
+ These changes are recommended but not required immediately. Consider migrating during your next refactoring cycle.
1344
+
1345
+ ### Application.MainPage
1346
+
1347
+ **Status:** ⚠️ **DEPRECATED** - Property will be removed in future version.
1348
+
1349
+ **Warning You'll See:**
1350
+ ```
1351
+ warning CS0618: 'Application.MainPage' is obsolete: 'This property is deprecated. Initialize your application by overriding Application.CreateWindow...'
1352
+ ```
1353
+
1354
+ #### Migration Example
1355
+
1356
+ ```csharp
1357
+ // ❌ OLD (Deprecated)
1358
+ public partial class App : Application
1359
+ {
1360
+ public App()
1361
+ {
1362
+ InitializeComponent();
1363
+ MainPage = new AppShell();
1364
+ }
1365
+
1366
+ // Changing page later
1367
+ public void SwitchToLoginPage()
1368
+ {
1369
+ MainPage = new LoginPage();
1370
+ }
1371
+ }
1372
+
1373
+ // ✅ NEW (Recommended)
1374
+ public partial class App : Application
1375
+ {
1376
+ public App()
1377
+ {
1378
+ InitializeComponent();
1379
+ }
1380
+
1381
+ protected override Window CreateWindow(IActivationState? activationState)
1382
+ {
1383
+ return new Window(new AppShell());
1384
+ }
1385
+
1386
+ // Changing page later
1387
+ public void SwitchToLoginPage()
1388
+ {
1389
+ if (Windows.Count > 0)
1390
+ {
1391
+ Windows[0].Page = new LoginPage();
1392
+ }
1393
+ }
1394
+ }
1395
+ ```
1396
+
1397
+ **Benefits of CreateWindow:**
1398
+ - Better multi-window support
1399
+ - More explicit initialization
1400
+ - Cleaner separation of concerns
1401
+ - Works better with Shell
1402
+
1403
+ ---
1404
+
1405
+ ## Bulk Migration Tools
1406
+
1407
+ Use these find/replace patterns to quickly update your codebase.
1408
+
1409
+ ### Visual Studio / VS Code
1410
+
1411
+ **Regex Mode - Find/Replace**
1412
+
1413
+ #### Animation Methods
1414
+
1415
+ ```regex
1416
+ Find: \.FadeTo\(
1417
+ Replace: .FadeToAsync(
1418
+
1419
+ Find: \.ScaleTo\(
1420
+ Replace: .ScaleToAsync(
1421
+
1422
+ Find: \.TranslateTo\(
1423
+ Replace: .TranslateToAsync(
1424
+
1425
+ Find: \.RotateTo\(
1426
+ Replace: .RotateToAsync(
1427
+
1428
+ Find: \.RotateXTo\(
1429
+ Replace: .RotateXToAsync(
1430
+
1431
+ Find: \.RotateYTo\(
1432
+ Replace: .RotateYToAsync(
1433
+
1434
+ Find: \.ScaleXTo\(
1435
+ Replace: .ScaleXToAsync(
1436
+
1437
+ Find: \.ScaleYTo\(
1438
+ Replace: .ScaleYToAsync(
1439
+
1440
+ Find: \.RelRotateTo\(
1441
+ Replace: .RelRotateToAsync(
1442
+
1443
+ Find: \.RelScaleTo\(
1444
+ Replace: .RelScaleToAsync(
1445
+ ```
1446
+
1447
+ #### Display Methods
1448
+
1449
+ ```regex
1450
+ Find: DisplayAlert\(
1451
+ Replace: DisplayAlertAsync(
1452
+
1453
+ Find: DisplayActionSheet\(
1454
+ Replace: DisplayActionSheetAsync(
1455
+ ```
1456
+
1457
+ #### MediaPicker Methods
1458
+
1459
+ **⚠️ Note:** MediaPicker migration requires manual code changes due to return type changes (`FileResult?` → `List<FileResult>`). Use these searches to find instances:
1460
+
1461
+ ```bash
1462
+ # Find PickPhotoAsync usages
1463
+ grep -rn "PickPhotoAsync" --include="*.cs" .
1464
+
1465
+ # Find PickVideoAsync usages
1466
+ grep -rn "PickVideoAsync" --include="*.cs" .
1467
+ ```
1468
+
1469
+ **Manual Migration Pattern:**
1470
+ ```csharp
1471
+ // Find: await MediaPicker.PickPhotoAsync(
1472
+ // Replace with:
1473
+ var photos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions { SelectionLimit = 1 });
1474
+ var photo = photos.FirstOrDefault();
1475
+
1476
+ // Find: await MediaPicker.PickVideoAsync(
1477
+ // Replace with:
1478
+ var videos = await MediaPicker.PickVideosAsync(new MediaPickerOptions { SelectionLimit = 1 });
1479
+ var video = videos.FirstOrDefault();
1480
+ ```
1481
+
1482
+ #### ListView/TableView Detection (Manual Migration Required)
1483
+
1484
+ **⚠️ Note:** ListView/TableView migration CANNOT be automated. Use these searches to find instances:
1485
+
1486
+ ```bash
1487
+ # Find all ListView usages in XAML
1488
+ grep -r "<ListView" --include="*.xaml" .
1489
+
1490
+ # Find all TableView usages in XAML
1491
+ grep -r "<TableView" --include="*.xaml" .
1492
+
1493
+ # Find ListView in C# code
1494
+ grep -r "new ListView\|ListView " --include="*.cs" .
1495
+
1496
+ # Find Cell types in XAML
1497
+ grep -r "TextCell\|ImageCell\|EntryCell\|SwitchCell\|ViewCell" --include="*.xaml" .
1498
+
1499
+ # Find ItemSelected handlers (need to change to SelectionChanged)
1500
+ grep -r "ItemSelected=" --include="*.xaml" .
1501
+ grep -r "ItemSelected\s*\+=" --include="*.cs" .
1502
+
1503
+ # Find ContextActions (need to change to SwipeView)
1504
+ grep -r "ContextActions" --include="*.xaml" .
1505
+
1506
+ # Find platform-specific ListView code (needs removal)
1507
+ grep -r "PlatformConfiguration.*ListView" --include="*.cs" .
1508
+ ```
1509
+
1510
+ **Create a Migration Inventory:**
1511
+ ```bash
1512
+ # Generate a report of all ListView/TableView instances
1513
+ echo "=== ListView/TableView Migration Inventory ===" > migration-report.txt
1514
+ echo "" >> migration-report.txt
1515
+ echo "XAML ListView instances:" >> migration-report.txt
1516
+ grep -rn "<ListView" --include="*.xaml" . >> migration-report.txt
1517
+ echo "" >> migration-report.txt
1518
+ echo "XAML TableView instances:" >> migration-report.txt
1519
+ grep -rn "<TableView" --include="*.xaml" . >> migration-report.txt
1520
+ echo "" >> migration-report.txt
1521
+ echo "ItemSelected handlers:" >> migration-report.txt
1522
+ grep -rn "ItemSelected" --include="*.xaml" --include="*.cs" . >> migration-report.txt
1523
+ echo "" >> migration-report.txt
1524
+ cat migration-report.txt
1525
+ ```
1526
+
1527
+ ### PowerShell Script
1528
+
1529
+ ```powershell
1530
+ # Replace animation methods in all .cs files
1531
+ Get-ChildItem -Path . -Recurse -Filter *.cs | ForEach-Object {
1532
+ $content = Get-Content $_.FullName -Raw
1533
+
1534
+ # Animation methods
1535
+ $content = $content -replace '\.FadeTo\(', '.FadeToAsync('
1536
+ $content = $content -replace '\.ScaleTo\(', '.ScaleToAsync('
1537
+ $content = $content -replace '\.TranslateTo\(', '.TranslateToAsync('
1538
+ $content = $content -replace '\.RotateTo\(', '.RotateToAsync('
1539
+ $content = $content -replace '\.RotateXTo\(', '.RotateXToAsync('
1540
+ $content = $content -replace '\.RotateYTo\(', '.RotateYToAsync('
1541
+ $content = $content -replace '\.ScaleXTo\(', '.ScaleXToAsync('
1542
+ $content = $content -replace '\.ScaleYTo\(', '.ScaleYToAsync('
1543
+ $content = $content -replace '\.RelRotateTo\(', '.RelRotateToAsync('
1544
+ $content = $content -replace '\.RelScaleTo\(', '.RelScaleToAsync('
1545
+
1546
+ # Display methods
1547
+ $content = $content -replace 'DisplayAlert\(', 'DisplayAlertAsync('
1548
+ $content = $content -replace 'DisplayActionSheet\(', 'DisplayActionSheetAsync('
1549
+
1550
+ Set-Content $_.FullName $content
1551
+ }
1552
+
1553
+ Write-Host "✅ Migration complete!"
1554
+ ```
1555
+
1556
+ ---
1557
+
1558
+ ## Testing Your Upgrade
1559
+
1560
+ ### Build Validation
1561
+
1562
+ ```bash
1563
+ # Clean solution
1564
+ dotnet clean
1565
+
1566
+ # Restore packages
1567
+ dotnet restore
1568
+
1569
+ # Build for each platform
1570
+ dotnet build -f net10.0-android -c Release
1571
+ dotnet build -f net10.0-ios -c Release
1572
+ dotnet build -f net10.0-maccatalyst -c Release
1573
+ dotnet build -f net10.0-windows -c Release
1574
+
1575
+ # Check for warnings
1576
+ dotnet build --no-incremental 2>&1 | grep -i "warning CS0618"
1577
+ ```
1578
+
1579
+ ### Enable Warnings as Errors (Temporary)
1580
+
1581
+ ```xml
1582
+ <!-- Add to your .csproj to catch all obsolete API usage -->
1583
+ <PropertyGroup>
1584
+ <WarningsAsErrors>CS0618</WarningsAsErrors>
1585
+ </PropertyGroup>
1586
+ ```
1587
+
1588
+ ### Test Checklist
1589
+
1590
+ - [ ] App launches successfully on all platforms
1591
+ - [ ] All animations work correctly
1592
+ - [ ] Dialogs (alerts/action sheets) display properly
1593
+ - [ ] Loading indicators work (if you used IsBusy)
1594
+ - [ ] Inter-component communication works (MessagingCenter replacement)
1595
+ - [ ] No CS0618 warnings in build output
1596
+ - [ ] No runtime exceptions related to obsolete APIs
1597
+
1598
+ ---
1599
+
1600
+ ## Troubleshooting
1601
+
1602
+ ### Error: 'MessagingCenter' is inaccessible due to its protection level
1603
+
1604
+ **Cause:** MessagingCenter is now internal in .NET 10.
1605
+
1606
+ **Solution:**
1607
+ 1. Install `CommunityToolkit.Mvvm` package
1608
+ 2. Replace with `WeakReferenceMessenger` (see [MessagingCenter section](#messagingcenter-made-internal))
1609
+ 3. Create message classes for each message type
1610
+ 4. Don't forget to unregister!
1611
+
1612
+ ---
1613
+
1614
+ ### Warning: Animation method is obsolete
1615
+
1616
+ **Cause:** Using sync animation methods (`FadeTo`, `ScaleTo`, etc.)
1617
+
1618
+ **Quick Fix:**
1619
+ ```bash
1620
+ # Use PowerShell script from Bulk Migration Tools section
1621
+ # Or use Find/Replace patterns
1622
+ ```
1623
+
1624
+ **Manual Fix:**
1625
+ Add `Async` to the end of each animation method call:
1626
+ - `FadeTo` → `FadeToAsync`
1627
+ - `ScaleTo` → `ScaleToAsync`
1628
+ - etc.
1629
+
1630
+ ---
1631
+
1632
+ ### Page.IsBusy doesn't work anymore
1633
+
1634
+ **Cause:** IsBusy still works but is deprecated.
1635
+
1636
+ **Solution:** Replace with explicit ActivityIndicator (see [IsBusy section](#3-pageisbusy))
1637
+
1638
+ ---
1639
+
1640
+ ### Build fails with "Target framework 'net10.0' not found"
1641
+
1642
+ **Cause:** .NET 10 SDK not installed or not latest version.
1643
+
1644
+ **Solution:**
1645
+ ```bash
1646
+ # Check SDK version
1647
+ dotnet --version # Should be 10.0.100 or later
1648
+
1649
+ # Install .NET 10 SDK from:
1650
+ # https://dotnet.microsoft.com/download/dotnet/10.0
1651
+
1652
+ # Update workloads
1653
+ dotnet workload update
1654
+ ```
1655
+
1656
+ ---
1657
+
1658
+ ### MessagingCenter migration breaks existing code
1659
+
1660
+ **Common Issues:**
1661
+
1662
+ 1. **Forgot to unregister:**
1663
+ ```csharp
1664
+ // ⚠️ Memory leak if you don't unregister
1665
+ protected override void OnDisappearing()
1666
+ {
1667
+ base.OnDisappearing();
1668
+ WeakReferenceMessenger.Default.UnregisterAll(this);
1669
+ }
1670
+ ```
1671
+
1672
+ 2. **Wrong message type:**
1673
+ ```csharp
1674
+ // ❌ Wrong
1675
+ WeakReferenceMessenger.Default.Register<UserLoggedIn>(this, handler);
1676
+ WeakReferenceMessenger.Default.Send(new UserData()); // Wrong type!
1677
+
1678
+ // ✅ Correct
1679
+ WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(this, handler);
1680
+ WeakReferenceMessenger.Default.Send(new UserLoggedInMessage(userData));
1681
+ ```
1682
+
1683
+ 3. **Recipient parameter confusion:**
1684
+ ```csharp
1685
+ // The recipient parameter is the object that registered (this)
1686
+ WeakReferenceMessenger.Default.Register<MyMessage>(this, (recipient, message) =>
1687
+ {
1688
+ // recipient == this
1689
+ // message == the message that was sent
1690
+ });
1691
+ ```
1692
+
1693
+ ---
1694
+
1695
+ ### Warning: MediaPicker methods are obsolete
1696
+
1697
+ **Cause:** Using deprecated `PickPhotoAsync` or `PickVideoAsync` methods.
1698
+
1699
+ **Solution:** Migrate to `PickPhotosAsync` or `PickVideosAsync`:
1700
+
1701
+ ```csharp
1702
+ // ❌ OLD
1703
+ var photo = await MediaPicker.PickPhotoAsync(options);
1704
+
1705
+ // ✅ NEW (maintain single-selection)
1706
+ var photos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
1707
+ {
1708
+ Title = options?.Title,
1709
+ SelectionLimit = 1
1710
+ });
1711
+ var photo = photos.FirstOrDefault();
1712
+ ```
1713
+
1714
+ **Key Changes:**
1715
+ - Return type changes from `FileResult?` to `List<FileResult>`
1716
+ - Use `.FirstOrDefault()` to get single result
1717
+ - Set `SelectionLimit = 1` to maintain old behavior
1718
+ - Check `photos.Count == 0` instead of `photo == null`
1719
+
1720
+ ---
1721
+
1722
+ ### MediaPicker returns more items than SelectionLimit
1723
+
1724
+ **Cause:** Windows and some Android custom pickers don't enforce `SelectionLimit`.
1725
+
1726
+ **Solution:** Add manual validation:
1727
+
1728
+ ```csharp
1729
+ var photos = await MediaPicker.PickPhotosAsync(new MediaPickerOptions
1730
+ {
1731
+ SelectionLimit = 5
1732
+ });
1733
+
1734
+ if (photos.Count > 5)
1735
+ {
1736
+ await DisplayAlertAsync("Error", "Too many photos selected", "OK");
1737
+ return;
1738
+ }
1739
+ ```
1740
+
1741
+ ---
1742
+
1743
+ ### Animation doesn't complete after migration
1744
+
1745
+ **Cause:** Forgetting `await` keyword.
1746
+
1747
+ ```csharp
1748
+ // ❌ Wrong - animation runs but code continues immediately
1749
+ view.FadeToAsync(0, 500);
1750
+ DoSomethingElse();
1751
+
1752
+ // ✅ Correct - wait for animation to complete
1753
+ await view.FadeToAsync(0, 500);
1754
+ DoSomethingElse();
1755
+ ```
1756
+
1757
+ ---
1758
+
1759
+ ### Warning: ListView/TableView/TextCell is obsolete
1760
+
1761
+ **Cause:** Using deprecated ListView, TableView, or Cell types.
1762
+
1763
+ **Solution:** Migrate to CollectionView (see [ListView and TableView section](#listview-and-tableview-deprecated))
1764
+
1765
+ **Quick Decision Guide:**
1766
+ - **Simple list** → CollectionView with custom DataTemplate
1767
+ - **Settings page with <20 items** → VerticalStackLayout with BindableLayout
1768
+ - **Settings page with 20+ items** → Grouped CollectionView
1769
+ - **Grouped data list** → CollectionView with `IsGrouped="True"`
1770
+
1771
+ ---
1772
+
1773
+ ### CollectionView doesn't have SelectedItem event
1774
+
1775
+ **Cause:** CollectionView uses `SelectionChanged` instead of `ItemSelected`.
1776
+
1777
+ **Solution:**
1778
+ ```csharp
1779
+ // ❌ OLD (ListView)
1780
+ void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
1781
+ {
1782
+ var item = e.SelectedItem as MyItem;
1783
+ }
1784
+
1785
+ // ✅ NEW (CollectionView)
1786
+ void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
1787
+ {
1788
+ var item = e.CurrentSelection.FirstOrDefault() as MyItem;
1789
+ }
1790
+ ```
1791
+
1792
+ ---
1793
+
1794
+ ### Platform-specific ListView configuration is obsolete
1795
+
1796
+ **Cause:** Using `Microsoft.Maui.Controls.PlatformConfiguration.*Specific.ListView` extensions.
1797
+
1798
+ **Error:**
1799
+ ```
1800
+ warning CS0618: 'ListView' is obsolete: 'With the deprecation of ListView, this class is obsolete. Please use CollectionView instead.'
1801
+ ```
1802
+
1803
+ **Solution:**
1804
+ 1. Remove platform-specific ListView using statements:
1805
+ ```csharp
1806
+ // ❌ Remove these
1807
+ using Microsoft.Maui.Controls.PlatformConfiguration;
1808
+ using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
1809
+ using Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific;
1810
+ ```
1811
+
1812
+ 2. Remove platform-specific ListView calls:
1813
+ ```csharp
1814
+ // ❌ Remove these
1815
+ myListView.On<iOS>().SetSeparatorStyle(SeparatorStyle.FullWidth);
1816
+ myListView.On<Android>().IsFastScrollEnabled();
1817
+ viewCell.On<iOS>().SetDefaultBackgroundColor(Colors.White);
1818
+ ```
1819
+
1820
+ 3. CollectionView has different platform customization options - consult CollectionView docs for alternatives.
1821
+
1822
+ ---
1823
+
1824
+ ### CollectionView performance issues after ListView migration
1825
+
1826
+ **Common Causes:**
1827
+
1828
+ 1. **Not using DataTemplate caching:**
1829
+ ```xaml
1830
+ <!-- ❌ Bad performance -->
1831
+ <CollectionView.ItemTemplate>
1832
+ <DataTemplate>
1833
+ <ComplexView />
1834
+ </DataTemplate>
1835
+ </CollectionView.ItemTemplate>
1836
+
1837
+ <!-- ✅ Better - use simpler templates -->
1838
+ <CollectionView.ItemTemplate>
1839
+ <DataTemplate>
1840
+ <VerticalStackLayout Padding="10">
1841
+ <Label Text="{Binding Title}" />
1842
+ </VerticalStackLayout>
1843
+ </DataTemplate>
1844
+ </CollectionView.ItemTemplate>
1845
+ ```
1846
+
1847
+ 2. **Complex nested layouts:**
1848
+ - Avoid deeply nested layouts in ItemTemplate
1849
+ - Use Grid instead of StackLayout when possible
1850
+ - Consider FlexLayout for complex layouts
1851
+
1852
+ 3. **Images not being cached:**
1853
+ ```xaml
1854
+ <Image Source="{Binding ImageUrl}"
1855
+ Aspect="AspectFill"
1856
+ HeightRequest="80"
1857
+ WidthRequest="80">
1858
+ <Image.Behaviors>
1859
+ <!-- Add caching behavior if needed -->
1860
+ </Image.Behaviors>
1861
+ </Image>
1862
+ ```
1863
+
1864
+ ---
1865
+
1866
+ ## Quick Reference Card
1867
+
1868
+ ### Priority Checklist
1869
+
1870
+ **Must Fix (P0 - Breaking/Critical):**
1871
+ - [ ] Replace `MessagingCenter` with `WeakReferenceMessenger`
1872
+ - [ ] Migrate `ListView` to `CollectionView`
1873
+ - [ ] Migrate `TableView` to `CollectionView` or `BindableLayout`
1874
+ - [ ] Replace `TextCell`, `ImageCell`, etc. with custom DataTemplates
1875
+ - [ ] Convert `ContextActions` to `SwipeView`
1876
+ - [ ] Remove platform-specific ListView configurations
1877
+
1878
+ **Should Fix (P1 - Deprecated):**
1879
+ - [ ] Update animation methods: add `Async` suffix
1880
+ - [ ] Update `DisplayAlert` → `DisplayAlertAsync`
1881
+ - [ ] Update `DisplayActionSheet` → `DisplayActionSheetAsync`
1882
+ - [ ] Replace `Page.IsBusy` with `ActivityIndicator`
1883
+ - [ ] Replace `PickPhotoAsync` → `PickPhotosAsync` (with `SelectionLimit = 1`)
1884
+ - [ ] Replace `PickVideoAsync` → `PickVideosAsync` (with `SelectionLimit = 1`)
1885
+
1886
+ **Nice to Have (P2):**
1887
+ - [ ] Migrate `Application.MainPage` to `CreateWindow`
1888
+
1889
+ ### Common Patterns
1890
+
1891
+ ```csharp
1892
+ // Animation
1893
+ await view.FadeToAsync(0, 500);
1894
+
1895
+ // Alert
1896
+ await DisplayAlertAsync("Title", "Message", "OK");
1897
+
1898
+ // Messaging
1899
+ WeakReferenceMessenger.Default.Send(new MyMessage());
1900
+ WeakReferenceMessenger.Default.Register<MyMessage>(this, (r, m) => { });
1901
+ WeakReferenceMessenger.Default.UnregisterAll(this);
1902
+
1903
+ // Loading
1904
+ IsLoading = true;
1905
+ try { await LoadAsync(); }
1906
+ finally { IsLoading = false; }
1907
+ ```
1908
+
1909
+ ---
1910
+
1911
+ ## Additional Resources
1912
+
1913
+ - **Official Docs:** https://learn.microsoft.com/dotnet/maui/
1914
+ - **Migration Guide:** https://learn.microsoft.com/dotnet/maui/migration/
1915
+ - **GitHub Issues:** https://github.com/dotnet/maui/issues
1916
+ - **CommunityToolkit.Mvvm:** https://learn.microsoft.com/dotnet/communitytoolkit/mvvm/
1917
+
1918
+ ---
1919
+
1920
+ **Document Version:** 2.0
1921
+ **Last Updated:** November 2025
1922
+ **Applies To:** .NET MAUI 10.0.100 and later