Skip to content

Commit d6beee0

Browse files
authored
XAML module (#140)
1 parent e89f1d2 commit d6beee0

File tree

267 files changed

+9400
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

267 files changed

+9400
-0
lines changed
64.7 KB
Loading
24.2 KB
Loading
57.5 KB
Loading
182 KB
Loading
81.3 KB
Loading
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project>
2+
<PropertyGroup>
3+
<SupportedOSPlatformVersion Condition="'$(TargetFramework)' == 'net8.0-ios'">14.2</SupportedOSPlatformVersion>
4+
<SupportedOSPlatformVersion Condition="'$(TargetFramework)' == 'net8.0-maccatalyst'">14.0</SupportedOSPlatformVersion>
5+
<SupportedOSPlatformVersion Condition="'$(TargetFramework)' == 'net8.0-android'">21.0</SupportedOSPlatformVersion>
6+
<SupportedOSPlatformVersion Condition="$(TargetFramework.Contains('-windows'))">10.0.17763.0</SupportedOSPlatformVersion>
7+
<TargetPlatformMinVersion Condition="$(TargetFramework.Contains('-windows'))">10.0.17763.0</TargetPlatformMinVersion>
8+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
9+
</PropertyGroup>
10+
11+
<!-- Build Properties must be defined within these property groups to ensure successful publishing
12+
to the Mac App Store. See: https://aka.ms/maui-publish-app-store#define-build-properties-in-your-project-file -->
13+
<PropertyGroup Condition="$(TargetFramework.Contains('-maccatalyst')) and '$(Configuration)' == 'Debug'">
14+
<CodesignEntitlements>Platforms/MacCatalyst/Entitlements.Debug.plist</CodesignEntitlements>
15+
</PropertyGroup>
16+
17+
<PropertyGroup Condition="$(TargetFramework.Contains('-maccatalyst')) and '$(Configuration)' == 'Release'">
18+
<CodesignEntitlements>Platforms/MacCatalyst/Entitlements.Release.plist</CodesignEntitlements>
19+
<UseHardenedRuntime>true</UseHardenedRuntime>
20+
</PropertyGroup>
21+
</Project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project>
2+
<ItemGroup>
3+
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
4+
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
5+
<PackageReference Include="Microsoft.Maui.Controls" Version="8.0.21" />
6+
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.21" />
7+
</ItemGroup>
8+
9+
<ItemGroup Condition="$(TargetFramework.Contains('-windows'))">
10+
<!-- Required - WinUI does not yet have buildTransitive for everything -->
11+
</ItemGroup>
12+
13+
<PropertyGroup>
14+
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
15+
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
16+
17+
<!-- Note for MacCatalyst:
18+
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
19+
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifer>.
20+
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
21+
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
22+
<!-- ex. <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
23+
</PropertyGroup>
24+
</Project>
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Part 0 - Overview
2+
3+
In this workshop, we will focus on creating UIs with XAML. If you're not a fan of XAML and prefer to make the UI with C#, that's a valid option, and you're welcome to do so, but we won't be covering that here. However, you might want to stick around (or skip to the end) and see if the XAML we end up with is more to your liking.
4+
5+
Let's start by looking at an example [page from the final version](https://github.com/mrlacey/dotnet-maui-workshop-xaml/blob/main/Part%205%20-%20Custom%20Types/Finish/MonkeyFinder/View/DetailsPage.xaml).
6+
Now, compare it with [the version we started with](https://github.com/mrlacey/dotnet-maui-workshop-xaml/blob/main/Part%201%20-%20Fundamentals/Start/MonkeyFinder/View/DetailsPage.xaml).
7+
8+
It looks very different:
9+
10+
- It's much shorter: 27 lines rather than 56
11+
- It contains fewer elements: 7 rather than 12
12+
- Those elements include fewer attributes: 21 rather than 48
13+
14+
![Diff: DetailsPage.xaml before and after](../Art/diff-detailspage-xaml.png)
15+
16+
Those changes are what's easily quantifiable, but there are some intangible differences too:
17+
18+
- **It's now quicker to read**. And not just because there's less text on the screen.
19+
- **It's easier to understand**. Because you don't have to determine what the elements represent or why they're there.
20+
- **It's easier to support and modify (maintain)**. By understanding what's there and why, there's less chance of unexpected consequences when making a change.
21+
22+
There are many ways to improve the **Monkey Finder** app you created as part of the .NET MAUI Workshop, but in this workshop, we'll only look at the XAML.
23+
This focus is because many people frequently overlook XAML, but it's one of the most criticized aspects of building apps with .NET MAUI.
24+
25+
## 0.1 - Why it's important to look in detail at how we write XAML
26+
27+
XAML is often criticized as being overly complex and verbose. This is often due to the way it's written, but this doesn't have to be the case. If there are two different ways of writing something, one that takes six lines and another that only requires a single line, and you choose to use the longer version, complaining about the need for extra lines is, at best, misplaced. However, some people never learn that the shorter option is available. That's what this workshop is here to show you.
28+
29+
Many people are unaware that there are multiple ways of writing XAML, and I've met very few developers who have ever thought about what "good XAML" looks like.
30+
31+
If you haven't considered this before, take a moment now to consider what makes a good XAML file.
32+
33+
It's ok, I'll wait.
34+
35+
...
36+
37+
...
38+
39+
...
40+
41+
...
42+
43+
What did you come up with?
44+
45+
Here's my list.
46+
47+
Good XAML should be:
48+
49+
- **Clear** - so it's easy to read and understand.
50+
- **Concise** - so there's no unnecessary duplication or unnecessary text.
51+
- **Consistent** - which makes it easier to read and understand.
52+
- **Self-describing** - so it doesn't need extra comments or time spent deciphering the complex nested XML.
53+
- **Maintainable** - which results from all of the above.
54+
55+
Hopefully, you can appreciate that none of my points about what makes good XAML are specific to XAML but apply to _any_ programming language.
56+
57+
These points will help you write good code in any programming language. And yes, I do consider XAML to be a programming language. No, it's not Turing-complete, and it's not capable of many things that other programming languages are. Still, it's text files that we pass to the compiler and ultimately end up helping to create our application. When we think of XAML files this way, it's clear that we should be treating them with more care and attention.
58+
59+
If you're new to working with XAML and aren't familiar with some of the problems I've already hinted at, I'll show bad examples in the coming parts so you can see the types of issues you can avoid.
60+
61+
## 0.2 - Why is this workshop necessary?
62+
63+
If you're one of the people who has never before considered what counts as "good XAML," then it should be obvious why this is important.
64+
65+
From a broader perspective, I think there are three factors that have led to the widespread use of low-quality XAML today.
66+
67+
1. Developers treat XAML as the designer's responsibility - and designers don't care about XAML.
68+
2. XAML was originally intended to be written by tools and not by hand.
69+
3. There are very few examples of what "good" can look like or effort to improve things.
70+
71+
### 0.2.1 - Whose responsibility is XAML?
72+
73+
I'm sure you're an exception to these generalizations, but many (most?) developers don't spend much time and effort focusing on the UI of their applications. The design and styling of the UI often falls to other people (designers), and they are not the ones who implement the designs. This disconnect means that no one person takes full ownership of the code used to implement the UI, and as long as the running app matches the images created by the designer, everyone can move on to other things (that they'd rather be doing.)
74+
75+
Break the habit and take responsibility for what your XAML files look like. You'll benefit in the future when you come to modify them.
76+
77+
### 0.2.2 - Write for humans
78+
79+
In 2006, when XAML was first released (as part of WPF), the intention and expectation was that developers would use specific design-related tools to create their UIs with XAML and not write it all by hand. Over time, we've lost many of these design tools, and now there is little option (especially for .NET MAUI) other than to write XAML by hand. Elements defined with multiple levels of nesting and over many lines aren't a problem if you only see the UI through a design tool, but if you have to write that by hand (even in an editor with intellisense) it's far from ideal.
80+
81+
You are not a robot. Your XAML will need to be read by other humans. Therefore, it makes sense to optimize writing XAML so that it's easier and simpler for people to write and read. The tooling doesn't have a preference for how the code is formatted, so you can use what's easiest (and best) for you and your team.
82+
83+
### 0.2.3 - We can make things better, together
84+
85+
"It's only XAML. It doesn't matter." Until it does.
86+
When you have to explain why what should be a simple change to the UI is taking ages because it's hard to alter one thing without unintended side effects. Or when you dread having to work with a particular code base because it's so hard to work out what the existing code does.
87+
88+
These are scenarios that have been shared with me many times. But it's not our fault:
89+
90+
- Over the years, very little time has been spent teaching more than the fundamentals of writing XAML.
91+
- There is a lack of samples and examples we can look at to see XAML being done well.
92+
- There are only a handful of people who have built tools to make working with XAML easier.
93+
- And, the effort to change or evolve the language has been minimal.
94+
95+
While these are why we're in this situation, they don't excuse it.
96+
97+
We still need to create applications we can easily modify and maintain. It should not be expected that UIs are hard to change without much effort, testing, and unintended consequences.
98+
99+
There is a better way. And we need it.
100+
101+
## 0.3 - What we'll be looking at
102+
103+
Through the following parts of this workshop, we'll look at principles, "best practices," and techniques for writing good code (of any kind/language) and applying them to our XAML.
104+
105+
- In part 1, we'll look at the fundamentals of setting up our code base.
106+
- In part 2, we'll look at applying the Single Responsibility Principle to our XAML.
107+
- In part 3, we'll see how "magic values" often permeate XAML files in ways that would not be tolerated in any other language.
108+
- In part 4, we'll explore how naming elements in XAML is especially important and how most people and samples get this wrong.
109+
- And part 5, we'll see how custom types (of varying levels of complexity) can make a big difference.
110+
111+
## 0.4 - Disclaimer
112+
113+
Many of the techniques, principles, and ideas covered in this workshop only have noticeable benefits when working on larger projects and applications. For a simple app like the **Monkey Finder** there is a perfectly valid argument that the XAML you already have is adequate for such an application.
114+
115+
However, you are likely to want to build other applications that are larger and have more pages, views, and other functionality. Many of the problems people run into with building and maintaining larger code bases are that they try to write them like they do trivial apps and then wonder why they encounter issues. You wouldn't write a large, complex amount of C# in the same way you wrote your first Console app to display "Hello World".
116+
117+
The aim of this workshop isn't to show how to change the XAML of the **Monkey Finder** app; _it's to show you principles you can apply to other, more complex apps_.
118+
119+
My intention is not that you build apps with XAML in the ways shown in the original workshop (and elsewhere) and then modify that XAML to be easier to work with. Instead, it is that you get to a point where you can start with the better version. However, jumping straight into a different way of doing things can make it hard to understand why the reasons for the changes. Instead, we'll work through the list of principles to see how to apply them to existing XAML code. You'll then understand how to use them in the code you write in the future.
120+
121+
## 0.5 - Getting started
122+
123+
Now that you know why it's important to think about XAML like any other programming language
124+
125+
Now that you're ready to focus on XAML let's look at some code! [Head over to Part 1 to get started](../Part%201%20-%20Fundamentals/README.md)!
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31611.283
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyFinder", "MonkeyFinder\MonkeyFinder.csproj", "{C60F2B1C-790E-4432-A719-52182A333ADE}"
7+
EndProject
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{393B8F30-F402-46A9-B209-8C71897A3416}"
9+
ProjectSection(SolutionItems) = preProject
10+
..\Directory.build.props = ..\Directory.build.props
11+
..\Directory.build.targets = ..\Directory.build.targets
12+
EndProjectSection
13+
EndProject
14+
Global
15+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
16+
Debug|Any CPU = Debug|Any CPU
17+
Release|Any CPU = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20+
{C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
23+
{C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
24+
{C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Build.0 = Release|Any CPU
25+
{C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Deploy.0 = Release|Any CPU
26+
EndGlobalSection
27+
GlobalSection(SolutionProperties) = preSolution
28+
HideSolutionNode = FALSE
29+
EndGlobalSection
30+
GlobalSection(ExtensibilityGlobals) = postSolution
31+
SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
32+
EndGlobalSection
33+
EndGlobal
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Application
3+
x:Class="MonkeyFinder.App"
4+
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
6+
xmlns:local="clr-namespace:MonkeyFinder">
7+
<Application.Resources>
8+
<ResourceDictionary>
9+
<ResourceDictionary.MergedDictionaries>
10+
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
11+
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
12+
</ResourceDictionary.MergedDictionaries>
13+
</ResourceDictionary>
14+
</Application.Resources>
15+
</Application>

0 commit comments

Comments
 (0)