You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Conditional compilation in .NET allows different parts of the code to be compiled or omitted based on certain conditions. This is particularly useful in .NET when dealing with code that needs to behave differently on various platforms or under different development environments.
9
+
这些方案并不特定于Avalonia,可以用于任何类型的项目。
9
10
10
-
None of these solutions are specific to Avalonia, and they can be used with any type of projects.
.NET 6 and newer provide a set of APIs to get operating system in runtime - [OperatingSystem](https://learn.microsoft.com/en-us/dotnet/api/system.operatingsystem).
16
+
这个类中常用的一些静态方法包括:
15
17
16
-
Commonly used static methods of this class are:
17
-
| Method | Description |
18
+
| 方法 | 描述 |
18
19
| --- | --- |
19
-
| IsWindows()|Indicates whether the current application is running on Windows.|
20
-
| IsLinux() | Indicates whether the current application is running on Linux.|
21
-
| IsMacOS() | Indicates whether the current application is running on macOS.|
22
-
| IsAndroid() | Indicates whether the current application is running on Android.|
23
-
| IsIOS() | Indicates whether the current application is running on iOS or MacCatalyst.|
24
-
| IsBrowser() | Indicates whether the current application is running as WASM in a browser.|
25
-
| IsOSPlatform(String) | Indicates whether the current application is running on the specified platform.|
20
+
| IsWindows() |指示当前应用程序是否在Windows上运行。|
21
+
| IsLinux() | 指示当前应用程序是否在Linux上运行。|
22
+
| IsMacOS() | 指示当前应用程序是否在macOS上运行。|
23
+
| IsAndroid() | 指示当前应用程序是否在Android上运行。|
24
+
| IsIOS() | 指示当前应用程序是否在iOS或MacCatalyst上运行。|
25
+
| IsBrowser() | 指示当前应用程序是否在浏览器中以WASM形式运行。|
26
+
| IsOSPlatform(String) |指示当前应用程序是否在指定的平台上运行。|
26
27
27
-
These methods do not require any changes in the project structure, and can be used anywhere.
28
-
The disadvantage of using them, it is not possible to separate platform specific APIs in compile time. As otherwise it would require platform specific dependencies to be referenced in a common assembly.
28
+
这些方法不需要对项目结构进行任何更改,并且可以在任何地方使用。
29
+
缺点是无法在编译时分离平台特定的API,这样就需要在公共的程序集中引用平台特定的依赖项。
29
30
30
-
This approach is recommended for simpler scenarios, or when it's desired to keep simple project structure. In the last case,
31
+
这种方法适用于简单的场景,或者希望保持简单的项目结构。在后一种情况下
31
32
32
33
:::note
33
-
It's the only possible approach to write a conditional .NET code for Linux OS. As .NET doesn't have a special Target Framework for Linux.
`DEBUG` compile time constant is a well known one. But it's not really useful with writing platform specific code.
41
-
Depending on the project time, C# compiler might define additional constants per each [OS specific Target Framework](https://learn.microsoft.com/en-us/dotnet/standard/frameworks#net-5-os-specific-tfms) used in the project:
@@ -50,28 +50,27 @@ Depending on the project time, C# compiler might define additional constants per
50
50
| net8.0-android | ANDROID |
51
51
| net8.0-tizen | TIZEN |
52
52
53
-
From this table, we can see couple of notes:
54
-
1.If project doesn't use any OS specific Target Framework, none of these constants will be defined
55
-
2.**There is no constant for LINUX**, as there is no `net8.0-linux`Target Framework as of now. Note, it might be changed in the future versions of .NET.
56
-
3.Additionally, `net8.0-browser`is only available starting with .NET 8 SDK. Other Target Frameworks are supported with .NET 6 or higher.
53
+
从上表中,我们可以注意到几点:
54
+
1.如果项目没有使用任何特定于操作系统的目标Framework,则不会定义这些常量。
55
+
2.**没有针对 LINUX 的常量**,因为目前没有 `net8.0-linux`的目标框架。请注意,这可能会在未来版本的 .NET 中发生变化。
Similar approach can be used to define special code compilation for .NET Framework or .NET Standard projects, if it's required. Visit Microsoft [Cross-platform targeting
60
-
](https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/cross-platform-targeting) documentation for more information.
59
+
类似的方法也可以用于定义 .NET Framework 或 .NET Standard 项目的特殊代码编译,如果需要的话。请访问 Microsoft [跨平台目标](https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/cross-platform-targeting) 文档以获取更多信息。
61
60
:::
62
61
63
-
### Practical example
62
+
### 实际案例
64
63
65
-
Let's imagine, we want to use platform APIs from C# code. It can be Avalonia APIs, or Xamarin APIs, or anything else really.
66
-
First of all, expected Target Frameworks needs to be defined in the project. To keep it simple, we will have three possible target framework - "net8.0" (default), "net8.0-ios" and "net8.0-android" in `.csproj` file:
64
+
假设我们想在 C# 代码中使用平台 API。它可以是 Avalonia API、Xamarin API 或其他任何 API。
And then it's possible to create a method like this:
73
+
然后可以创建如下方法:
75
74
```csharp
76
75
publicenumDeviceOrientation
77
76
{
@@ -98,29 +97,27 @@ public static DeviceOrientation GetOrientation()
98
97
```
99
98
100
99
:::note
101
-
This sample code is referenced from the Microsoft documentation: https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/invoke-platform-code?view=net-maui-8.0#conditional-compilation
Similarly to the previous approach, it is possible to create bootstrap projects per each platform, and keep shared project with main logic and layouts.
108
-
For example, default Avalonia.Xplat template creates solution with following projects:
109
-
110
-
| Project | Target Framework |
107
+
| 项目 | 目标框架 |
111
108
| --- | --- |
112
109
| Project.Shared | net8.0 |
113
110
| Project.Desktop | net8.0 |
114
111
| Project.Android | net8.0-android |
115
112
| Project.iOS | net8.0-ios |
116
113
| Project.Browser | net8.0-browser |
117
114
118
-
Desktop project combines Windows, macOS and Linux. While mobile and browser platforms have their own projects.
119
-
This is default approach for Avalonia projects. If desired, developers can split Desktop project into multiple as well.
120
-
Although, it should be kept in mind, that .NET SDK doesn't have any target framework for Linux yet, so it still would have to use generic `net8.0`target framework.
The OnPlatform markup extension in Avalonia allows developers to specify different values for a property based on the operating system on which the application is running. This is particularly useful for creating cross-platform applications that need to adapt their UI or behavior according to the platform.
Alternatively, you can use constructor syntax to define the default value directly, skipping `Default`keyword. Platform-specific properties still needs to be defined.
In this sample above, `Tag`property has type of `object`, so compiler doesn't have enough information to parse input strings. Without specifying TypeArguments, property will have value of `string`on all platforms. But since we have `TypeArguments` here, compiler will parse them as `Thickness`values.
OnPlatform can also be used in XML syntax for defining property values.
52
+
OnPlatform 也可以在 XML 语法中用于定义属性值:
52
53
53
54
```xml
54
55
<StackPanel>
@@ -58,16 +59,16 @@ OnPlatform can also be used in XML syntax for defining property values.
58
59
</OnPlatform.Default>
59
60
<OnPlatform.iOS>
60
61
<ToggleSwitchContent="Hello iOS" />
61
-
</OnPlatform.Windows>
62
+
</OnPlatform.iOS>
62
63
</OnPlatform>
63
64
</StackPanel>
64
65
```
65
66
66
-
Note, in this sample, `OnPlatform`is a child of `StackPanel`. But in runtime only single actual control will be created (`ToggleButton`or`ToggleSwitch`) and added to the StackPanel.
@@ -77,22 +78,21 @@ Similarly to the previous sample, OnPlatform can be part of complex property set
77
78
</OnPlatform.Default>
78
79
<OnPlatform.iOS>
79
80
<SolidColorBrushColor="Yellow" />
80
-
</OnPlatform.Windows>
81
+
</OnPlatform.iOS>
81
82
</OnPlatform>
82
83
</ResourceDictionary>
83
84
```
84
85
85
-
### XML Combining Syntax
86
+
### XML 组合语法
86
87
87
-
To avoid branches duplication, it is possible to define multiple platforms in a single branch.
88
-
Another useful example would be including platform specific styles:
88
+
为了避免分支重复,可以在单个分支中定义多个平台。另一个有用的示例是包含平台特定的样式:
89
89
90
90
```xml
91
91
<Application.Styles>
92
-
<!--Always included-->
92
+
<!--始终包含-->
93
93
<FluentTheme />
94
94
95
-
<!--Only one branch is executed in runtime-->
95
+
<!--运行时只执行一个分支-->
96
96
<OnPlatform>
97
97
<!-- if (Android || iOS) -->
98
98
<OnOptions="Android, iOS">
@@ -106,17 +106,15 @@ Another useful example would be including platform specific styles:
106
106
</Application.Styles>
107
107
```
108
108
109
-
### Additional details
110
-
111
-
`OnPlatform` markup extension work in a similar way how `switch-case` works in C# code.
112
-
Compiler will generate branches for all possible values, but only single branch will be executed in runtime depending on the condition.
109
+
### 其他细节
113
110
114
-
It's also useful to remember, that if application is build with specific [Runtime Identifier](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog) and with [Trimming Enabled](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options), `OnPlatform` extension will have its branches trimmed only to these that are possible. For example, if `OnPlatform` had branches for `Windows` and `macOS`, but was built for `Windows` only, other branches will be removed. Which also reduces application size.
The `OnFormFactor`markup extension functions similarly to the `OnPlatform` and has the same general syntax. The main difference is that it allows defining values not per platform, but per device form factor, such as Desktop and Mobile.
0 commit comments