# Uno Platform > uid: Uno.Features.AdaptiveTrigger --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/AdaptiveTrigger.md --- uid: Uno.Features.AdaptiveTrigger --- # Using Adaptive Triggers With Uno Platform Applications ## AdaptiveTrigger Class Use the `AdaptiveTrigger` class to trigger a `` target. The target invokes changes in window properties, such as font size or panel orientation. For more information, please refer to Microsoft's documentation on the [AdaptiveTrigger class](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.adaptivetrigger) and the [VisualState class](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.visualstate). ## Differences between Uno and WinUI In a standard WinUI application, the sequential order of the adaptive trigger does not matter. The compiler will execute any `` target regardless of their order. For more information, see [AdaptiveTriggers' order declared in XAML shouldn't matter GitHub issue](https://github.com/unoplatform/uno/issues/2662). In an Uno Platform application, the sequential order of the adaptive trigger does matter. In this instance, the `VisualState` will execute the `Setters` when it finds the first matching occurrence. Subsequent triggers may be ignored if the first matching property remains true for the life of the program. ## Sample XAML Following is an example of three `` blocks. The blocks are non-sequential, ordered from `SmallScreen` to `LargeScreen` to `MediumScreen`. The expected output is to have the font size change as the window size changes. Each `` block has an adaptive trigger with a `MinWindowWidth` property. The property tells the `VisualState` to execute the `VisualState.Setters` whenever the window width is greater or equal to its integer value. Example: ```xml ``` ## Expected Output The above code might generate an unexpected output in an Uno application. `SmallScreen` is listed first in order. Because the property `MinWindowWidth="200"` remains true for the life of the program, the compiler will never execute the `LargeScreen` or `MediumScreen` adaptive triggers. In this instance, the font size never changes. This example demonstrates why developers must consider the order of their adaptive triggers, as the ordering may generate unexpected outcomes. The following demonstrates the same code, but re-written in a sequential order to generate the expected output: ```xml ``` ## Correct Output In the above example, the `VisualState` blocks are sequential, ordered from `LargeScreen` to `MediumScreen` to `SmallScreen`. Because of this, the compiler will execute the first true occurrence in the order written. The `LargeScreen` setter target is triggered when the window width is `>=` 1000 pixels. When this statement becomes false, the `VisualState` executes the next setter target that matches, i.e. the `MediumScreen` block. When the `MediumScreen` adaptive trigger is false, the `VisualState` finally executes the setter target for the `SmallScreen` block. --- # Source: https://raw.githubusercontent.com/unoplatform/uno.extensions/refs/heads/main/doc/Learn/Authentication/AuthenticationOverview.md --- uid: Uno.Extensions.Authentication.Overview --- # Authentication Uno.Extensions.Authentication is designed to make it simple to add authentication to an application. Authenticating a user may be used to restrict access to specific parts of the application, or in order to supply an access token when calling a back-end service. There are two aspects to the Authentication extensions: - Authentication: the process of authenticating the user and acquiring tokens - Authorization: tokens (acquired via authentication) can be queried to control access to parts of the application or supplied to service call so the user can be authorized to access the back-end service ## Installation `Authentication` is provided as an Uno Feature. To enable `Authentication` support in your application, add `Authentication` to the `` property in the Class Library (.csproj) file. In case you are using Msal Authentication add `AuthenticationMsal`, or `AuthenticationOidc` for Oidc Authentication. [!include[existing-app](../includes/existing-app.md)] [!include[single-project](../includes/single-project.md)] For more information about `UnoFeatures` refer to our [Using the Uno.Sdk](xref:Uno.Features.Uno.Sdk) docs. ## IAuthenticationService The `IAuthenticationService` interface defines the methods that an application can call to authenticate the user. ```csharp public interface IAuthenticationService { string[] Providers { get; } ValueTask LoginAsync(IDispatcher? dispatcher, IDictionary? credentials = default, string? provider = null, CancellationToken? cancellationToken = default); ValueTask RefreshAsync(CancellationToken? cancellationToken = default); ValueTask LogoutAsync(IDispatcher? dispatcher, CancellationToken? cancellationToken = default); ValueTask IsAuthenticated(CancellationToken? cancellationToken = default); event EventHandler LoggedOut; } ``` There are any number of different application workflows that require authentication but they typically boil down to using one or more of the `IAuthenticationService` methods. For example: ### Login on launch In this scenario the user is required to be authenticated in order to access the application. This is a workflow that redirects the user to a login prompt if they aren't authenticated when the application is launched. - Launch app - App invokes `IAuthenticationService.RefreshAsync` to refresh any existing tokens (eg retrieve a new Access Token by supplying a Refresh Token to an authentication endpoint). - If `RefreshAsync` returns true, the user is logged in, so navigate to the home page of the application - If `RefreshAsync` returns false, navigate to the login page of the application - On the login page, user enter credentials and clicks Login, the app invokes `IAuthenticationService.LoginAsync` and supplies credentials - If `LoginAsync` returns true, app navigates to home page - The user might decide to logout of the application, which invokes the `IAuthenticationService.LogoutAsync` method, the application then navigates back to the login page. ### User login requested In this scenario the application doesn't require the user to be authenticated unless they want to access certain parts of the application (or there is additional/different information that's available to the user if they've logged in) - Launch app - App invokes `IAuthenticationService.RefreshAsync` to refresh any existing tokens and to determine if the user is authenticated. The user is directed to the home page of the application, either as an unauthenticated or authenticated user (depending on the app, this may show different data). - User attempts to navigate to a part of the application that needs them to be authenticated, or just clicks a sign-in button so they can access the current page as an authenticated user. - App navigates to the login page where the user can enter their credentials. The app then invokes `IAuthenticationService.LoginAsync` to authenticate the user. - If `LoginAsync` returns true, the user is then either navigated to the part of the application they were attempting to access, or back to the view they were on. - The user can logout of the application, which again invokes the `IAuthenticationService.LogoutAsync` method ## Authentication Providers (IAuthenticationProvider) The process of authentication with a given authority is implemented by an authentication provider (i.e. implements IAuthenticationProvider). Multiple providers, and in fact, multiple instances of any provider, can be registered during application startup. For example, an application may want to provide support for authenticating using Facebook, Twitter and Apple - each of these has a different backend service that needs to be connected with. In the application the user selects which registered provider to use by supplying the `provider` argument when invoking the `IAuthenticationService.LoginAsync` method. This argument is optional and is not required if only a single provider has been registered. > [!NOTE] > The `IAuthenticationProvider` implementations are all marked as internal as they should be configured via the extensions methods on the `IHostBuilder` and the builder interface for the corresponding implementation. ### Custom The `CustomAuthenticationProvider` provides a basic implementation of the `IAuthenticationProvider` that requires callback methods to be defined for performing login, refresh and logout actions. Learn [Custom authentication](xref:Uno.Extensions.Authentication.HowToAuthentication) ### MSAL The `MsalAuthenticationProvider` wraps the [MSAL library](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet) from Microsoft into an implementation of `IAuthenticationProvider`. This implementation ignores any credentials passed into the `LoginAsync` method, instead invoking the web based authentication process required to authentication with Microsoft. Learn [Msal authentication](xref:Uno.Extensions.Authentication.HowToMsalAuthentication) ### Oidc The `OidcAuthenticationProvider` wraps support for any [OpenID Connect](https://openid.net/connect/) backend, including [IdentityServer](https://duendesoftware.com/products/identityserver). Learn [Oidc authentication](xref:Uno.Extensions.Authentication.HowToOidcAuthentication) #### Platform-specific behavior When the `OidcAuthenticationProvider` is automatically built, there are platform specific checks invoked internally which occasionally alter behavior during the authentication process: **WebAssembly**: The `OidcAuthenticationProvider` will automatically use the `WebAuthenticationBroker` to obtain redirect URIs during the authentication process. This is done to avoid the need for a redirect to a custom URI scheme, which is not supported in the browser. ### Web The `WebAuthenticationProvider` provides an implementation that displays a web view in order for the user to login. After login, the web view redirects back to the application, along with any tokens. Learn [Web Authentication](xref:Uno.Extensions.Authentication.HowToWebAuthentication) #### Platform-specific behavior Before the `WebAuthenticationProvider` is automatically built, there are platform specific checks invoked internally which occasionally alter behavior during the authentication process: **Windows**: The `AddWeb()` extension method will initialize a `WebAuthenticator` to launch an out-of-process browser. This is done preemptively to support its usage within `WebAuthenticationProvider` during login and logout instead of the `WebAuthenticationBroker` used for other platforms. **Other platforms**: For a description of various subtle differences when displaying a web login prompt on multiple platforms, see [Web Authentication Broker](https://platform.uno/docs/articles/features/web-authentication-broker.html). The broker will only respond to the `PrefersEphemeralWebBrowserSession` setting value in iOS (versions 13.0+), while the other platforms will ignore it. ## Http Handlers Once a user has been authenticated, the tokens are cached and are available for use when invoking service calls. Rather than developers having to access the tokens and manually appending the tokens to the http request, the Authentication extensions includes http handlers which will be inserted into the request pipeline in order to apply the tokens as required. ### Authorization Header The `HeaderHandler` is used to apply the access token to the http request using the `Authorization` header. The default scheme is `Bearer` but this can be override to use a different scheme, such as basic. ### Cookies The `CookieHandler` is used to apply the access token, and/or refresh token, to the http request as cookies. This requires the cookie name for access token and request token to be specified as part of configuring the application. Learn how to use [Cookies](xref:Uno.Extensions.Authentication.HowToCookieAuthorization) to authorize --- # Source: https://github.com/unoplatform/uno/blob/master/CODE_OF_CONDUCT.md # Code of Conduct This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. This code of conduct has been adopted by many other open source communities and we feel it expresses our values well. As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: - The use of sexualized language or imagery - Personal attacks - Trolling or insulting/derogatory comments - Public or private harassment - Publishing other's private information, such as physical or electronic addresses, without explicit permission - Other unethical or unprofessional conduct Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing or otherwise, unacceptable behavior may be reported by contacting a project maintainer at [conduct@platform.uno](mailto:conduct@platform.uno). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality concerning the reporter of an incident. This Code of Conduct is adapted from the Contributor Covenant, version 1.3.0, available from [http://contributor-covenant.org/version/1/3/0/](http://contributor-covenant.org/version/1/3/0/) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/controls/ComboBox.md --- uid: Uno.Controls.ComboBox --- # ComboBox The `ComboBox` is designed to select a value in a set of items. For more information about its usage, see [Combo box and list box Microsoft documentation](https://learn.microsoft.com/windows/apps/design/controls/combo-box). ## Customize the placement of the Drop-Down (UNO-only feature) By default, when opening a `ComboBox`, WinUI aligns its drop-down to keep the selected item at the same location. This means that, if the currently selected value is the last one in the list, the drop-down will appear above the `ComboBox`. If there isn't any selected item, the drop-down will appear centered over the `ComboBox`. On Uno, you can change this behavior using `DefaultDropDownPreferredPlacement` or `DropDownPreferredPlacement`. ### Change the default value for all the `ComboBox` in your application The default placement for all `ComboBox` instances can be changed by setting the feature flag in the startup of your app (`App.cs` or `App.xaml.cs`): ```csharp Uno.UI.FeatureConfiguration.ComboBox.DefaultDropDownPreferredPlacement = DropDownPlacement.Below; ``` ### Change only for a specific `ComboBox` ```xml ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/controls/CommandBar.md --- uid: Uno.Controls.CommandBar --- # CommandBar The `CommandBar` in **Uno** is designed to be used the same way you would use the `CommandBar` on **WinUI**. In most cases, you should refer to the [official `CommandBar` documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.commandbar). This document exists to highlight some of the differences you might encounter when working with the native mode of `CommandBar` on either **iOS** or **Android**. ## Modes The `CommandBar` supports 2 different modes: | Mode | Style | |---------|--------------------------| | Windows | `XamlDefaultCommandBar` | | Native | `NativeDefaultCommandBar`| ### Windows This mode replicates **WinUI**'s `CommandBar`. It is templatable and supports a template that's almost identical to **WinUI**'s default `CommandBar`. ![CommandBar Example - Windows](assets/commandbar/windows/example.png) #### Usage Example ```csharp ``` - > How can I remove the back button title from all pages on iOS? ```xml xmlns:toolkit="using:Uno.UI.Toolkit" ... ``` - > How can I change the back button icon/arrow/chevron in my app? ```xml xmlns:toolkit="using:Uno.UI.Toolkit" ... ``` - > How can I change the color of the back button? ```xml xmlns:toolkit="using:Uno.UI.Toolkit" ... ``` - > Why does my back button display "Back" on iOS? The back button will display "Back" if: - The previous page doesn't have a `CommandBar`. - The previous page's `CommandBar` doesn't have a `Content` of type `string`. - The previous page's `CommandBar` doesn't have a `CommandBarExtensions.BackButtonTitle`. - The previous page's `CommandBar` has a title that's too long (more than 140pt). - > Why can't I overlap content over the CommandBar on iOS? The `CommandBar` is not actually part of the `Page` on **iOS**, and you can't overlap content over it like you would on **WinUI** or **Android**. Please refer to the **Placement** section for details. - > Why is my CommandBar going into the status bar on iOS/Android? You must use `VisibleBoundsPadding.PaddingMask="Top"` on the parent control of `CommandBar` to properly support the notch or punch-holes on iOS and Android. ```xml xmlns:toolkit="using:Uno.UI.Toolkit" ... ... ``` - > Why doesn't my CommandBar show a back button? For a `CommandBar` to show a back button, it must first be resolved by `Frame` as soon as it navigates to a `Page`. To ensure that `CommandBar` is available as soon as the navigation starts, make sure it's directly part of a page, and not part of a `DataTemplate` or `ControlTemplate`. - > Why don't my AppBarButton visual states work? You can't customize the `ControlTemplate` of `AppBarButton` when using `CommandBar` in native mode. - > How can I change the foreground of the CommandBarExtensions.Subtitle on Android? You can't currently customize the foreground of the `CommandBarExtensions.Subtitle` on **Android**. - > Why doesn't CommandBarExtensions.Subtitle work on iOS? `CommandBarExtensions.Subtitle` is not currently implemented on iOS. You can replicate the same effect by setting a custom `Content` on `CommandBar`: ```xml ``` - > How can I add a badge to an AppBarButton? You can implement your own badge by setting a custom content on `AppBarButton`: ```xml ``` - > How can I set custom content to an AppBarButton? You can set a custom content to an `AppBarButton` like this: ```xml ``` - > Why does my CommandBar always appear at the top of the page on iOS? You can't place your `CommandBar` anywhere other than at the top of the `Page` on **iOS**. See the **Placement** section for details. - > How can I change the height of my CommandBar? You can't currently change the height of the `CommandBar`. - > How can I remove the 1px line displayed below the CommandBar on iOS? To hide the native 1px *shadow* that's displayed below the `CommandBar` on **iOS**, make its background transparent: ```xml ``` - > How can I add an elevation shadow to the CommandBar on Android? ```xml xmlns:toolkit="using:Uno.UI.Toolkit" ... ``` - > How can I use a Path for the AppBarButton Icon? `AppBarButton` doesn't currently support `PathIcon`. Only `BitmapIcon` with PNGs is supported. Please refer to the **Icon** section. - > Why doesn't CommandBarExtensions.BackButtonTitle change the title of my back button? `CommandBarExtensions.BackButtonTitle` must be set on the page to which the back button navigates to. Please refer to the **BackButtonTitle** section. - > Why doesn't my CommandBarExtensions.NavigationCommand display anything on Android? `CommandBarExtensions.NavigationCommand` only supports `AppBarButton` with `Icon` (not `Content`). Please refer to the **NavigationCommand** section. - > How can I localize CommandBarExtensions.BackButtonTitle? *For attached properties, you need a special syntax in the Name column of a `.resw` file.* Ref: [Microsoft documentation](https://learn.microsoft.com/windows/uwp/app-resources/localize-strings-ui-manifest#refer-to-a-string-resource-identifier-from-xaml). More specifically : ```xml ... ``` And in the `.resw` file, the name would be: `MyCommandBar.[using:Uno.UI.Toolkit]CommandBarExtensions.BackButtonTitle` - > How can I put a ComboBox in my CommandBar? ```xml ``` - > How can I customize the pressed/disabled visual states of my AppBarButton? You can't currently customize the visual states of `AppBarButton` when using `CommandBar` in native mode. - > Why doesn't the disabled state work on my AppBarButton on Android? `AppBarButton` doesn't currently support the disabled state when used with `Content` (of `string`) on **Android**. You can use an `Icon` instead. - > How can I disable the back swipe/gesture on iOS? To disable the back swipe/gesture on **iOS**, you must remove the `CommandBar` or replace the back button with a custom one: ```xml ``` - > How can I display two CommandBars side by side on iOS (i.e., master-detail) `Page` only supports a single `CommandBar` at a time. To display two `CommandBar`s side by side (i.e., master-detail), you should place two `Frame`s side by side and put a `CommandBar` in the `Page` of each `Frame`. - > How can I add a burger menu to the left of my CommandBar? ```xml ``` - > Why doesn't Flyout work on my AppBarButton? `AppBarButton` doesn't currently support `Flyout` when using `CommandBar` in native mode. You can use `MenuFlyout` instead. - > Why can't I change the Foreground of my AppBarButton on Android? `AppBarButton` doesn't currently support `Foreground` when displaying text (using `Content` of `string`). However, you can change the color of all textual `AppBarButton`s globally using **Android** styles: **Colors.xml** ```xml #FFFF0000 ``` **Styles.xml** ```xml @color/red @color/red ``` If you need the button to display a different color to reflect being in a disabled state, you can add a selector in its own file, under res/color, like so: **PrimaryTextColorSelector.xml** ```xml ``` **Styles.xml** ```xml @color/PrimaryTextColorSelector @color/PrimaryTextColorSelector ``` - > How can I customize the font of the CommandBar title/content? You can't currently customize the font of the native `CommandBar` title (set with a `string` on `Content`). Only the color can be changed, using the `Foreground` property. To customize the font of the `CommandBar`'s title, you must set a custom `FrameworkElement` as the `Content` of your `CommandBar`: ```xml ``` - > Why doesn't my CommandBar scroll when placed inside a ScrollViewer on iOS? `CommandBar` can't be placed inside a `ScrollViewer`. It must be anchored to the top of your `Page` at all time. Please refer to the **Placement** section for details. - > How can I change the color of the ripple effect when pressing on AppBarButtons on Android? You can change the color of the ripple effect globally using Android styles: **Colors.xml** ```xml #20444444 #20ffffff ``` **Styles.xml** ```xml @color/ripple_material_dark ``` - > Why doesn't my AppBarToggleButton work? `AppBarToggleButton` is not currently supported. To implement a similar effect, you can bind your `AppBarButton`'s icon to a state using a converter: ```xml ``` - > How can I show an image under my CommandBar? You can show an image under a `CommandBar` by making its background transparent and superposing it over an `Image`: ```xml ``` ![CommandBar Example - iOS - Transparent Background](assets/commandbar/ios/transparent.png) - > What size should my AppBarButton icons be? Please refer to the **Icon** section for details. - > Why does my back button icon change when swiping back on iOS? This can happen when navigating between two pages with `CommandBar`s using different `CommandBarExtensions.BackButtonIcon`s. To avoid this issue, please make sure that all `CommandBar`s use the same `CommandBarExtensions.BackButtonIcon` by using a style: ```xml ``` If the issue still occurs, make sure that both pages have a `CommandBar`. If you don't want your page to display a `CommandBar`, you can simply collapse it: ```xml ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno.extensions/refs/heads/main/doc/Learn/Configuration/ConfigurationOverview.md --- uid: Uno.Extensions.Configuration.Overview --- # Configuration `Uno.Extensions.Configuration` provides a uniform way to read or write configuration data from a number of distinct sources. The implementation of `IOptions` from [Microsoft.Extensions.Options](https://learn.microsoft.com/dotnet/api/microsoft.extensions.options) allows for [read-only](https://learn.microsoft.com/dotnet/core/extensions/configuration#concepts-and-abstractions) access to values organized into **configuration sections**. The [writable configuration](xref:Uno.Extensions.Configuration.HowToWritableConfiguration) pattern supports the ability to update configuration values at runtime. This feature uses [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) for any configuration related work. For more documentation on configuration, read the references listed at the bottom. ## Installation > [!NOTE] > If you already have `Extensions` in ``, then `Configuration` is already installed, as its dependencies are included with the `Extensions` feature. `Configuration` is provided as an Uno Feature. To enable `Configuration` support in your application, add `Configuration` to the `` property in the Class Library (.csproj) file. [!include[existing-app](../includes/existing-app.md)] [!include[single-project](../includes/single-project.md)] For more information about `UnoFeatures` refer to our [Using the Uno.Sdk](xref:Uno.Features.Uno.Sdk) docs. ## Using Configuration The `IConfiguration` interface is registered as a service when the `UseConfiguration()` extension method is used. ```csharp protected override void OnLaunched(LaunchActivatedEventArgs e) { var appBuilder = this.CreateBuilder(e) .Configure( host => host .UseConfiguration( /* ... */) ); Host = appBuilder.Build(); ... } ``` `IConfiguration` is then available to be accessed by any class instantiated by the dependency injection (DI) container: ```csharp public class MyService : IMyService { private readonly IConfiguration configuration; public MyService(IConfiguration configuration) { this.configuration = configuration; } ... } ``` ## App settings file sources To use `appsettings.json` file packaged as **EmbeddedResource** in the application: ```csharp private IHost Host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs e) { var appBuilder = this.CreateBuilder(e) .Configure( host => host .UseConfiguration( builder => builder .EmbeddedSource() ) ); Host = appBuilder.Build(); ... } ``` The recommended approach to specifying a configuration file source, especially when targeting Web Assembly (WASM), is to register it as an **EmbeddedResource** as described above. Configuration data read from embedded resources has the benefit of being available to the application immediately upon startup. However, it is still possible to package the file source as **Content** instead: ```csharp private IHost Host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs e) { // NOT RECOMMENDED FOR WEB ASSEMBLY var appBuilder = this.CreateBuilder(e) .Configure( host => host .UseConfiguration( builder => builder .ContentSource() ) ); Host = appBuilder.Build(); ... } ``` Both `EmbeddedSource` and `ContentSource` methods will also create settings files that are specific to the current environment by default, `appsettings..json` (eg `appsettings.development.json`). This can be disabled by setting the `includeEnvironmentSettings` argument to `false` (default value is `true`): ```csharp private IHost Host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs e) { var appBuilder = this.CreateBuilder(e) .Configure( host => host .UseConfiguration( builder => builder .EmbeddedSource(includeEnvironmentSettings: false) ) ); Host = appBuilder.Build(); } ``` > [!TIP] > It is recommended to ensure all configuration information is read before creation of the `IHost` instance by only using `EmbeddedSource`. This will allow configuration to determine which services are created. ## Sections Map configuration section to class and register with dependency injection (DI): ```csharp protected override void OnLaunched(LaunchActivatedEventArgs e) { var appBuilder = this.CreateBuilder(e) .Configure( host => host .UseConfiguration( builder => builder.EmbeddedSource() .Section() ) ); ... } ``` This can be accessed from any class created by the DI container: ```csharp public class MainViewModel : ObservableObject { private readonly IOptions customConfig; public MainViewModel(IOptions customConfig) { this.customConfig = customConfig; } } ``` ## Updating configuration values at runtime The **writable configuration** feature enables the ability to update configuration values at runtime. This pattern may also be referred to as the _settings pattern_ in certain documentation. With the `UseConfiguration()` extension method, `IWritableOptions` is registered as a service. The recommended approach when specifying a set of settings for this feature is to use **configuration sections**. Registering a configuration section for writable configuration does not require it to exist in any source. The section will be created if it does not exist. ```csharp protected override void OnLaunched(LaunchActivatedEventArgs e) { var appBuilder = this.CreateBuilder(e) .Configure( host => host .UseConfiguration(builder => builder .EmbeddedSource() .Section() ) ); ... } ``` `DiagnosticSettings` can be defined as a record: ```csharp public record DiagnosticSettings(bool HasBeenLaunched); ``` Modify a setting value by calling `Update()` on the injected `IWritableOptions` instance: ```csharp public MainViewModel(IWritableOptions debug) { debug.Update(debugSetting => debugSetting with { HasBeenLaunched = true } ); } ``` ## References - [Using IConfiguration](https://learn.microsoft.com/aspnet/core/fundamentals/configuration) - [Microsoft.Extensions.Options](https://learn.microsoft.com/dotnet/api/microsoft.extensions.options) - [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/controls/DatePicker.md --- uid: Uno.Controls.DatePicker --- # DatePicker ## Summary `DatePicker` is used to select a specific date. ## Managed vs. native implementation On iOS and Android the `DatePicker` by default displays using the native time picker UI. If you prefer consistent UI across all targets, you can switch to the managed implementation by setting the `UseNativeStyle` property: ```xml ``` To include the `not_win` XAML namespace on your page follow the instructions for [Platform-specific XAML](../platform-specific-xaml.md). --- # Source: https://raw.githubusercontent.com/unoplatform/uno.extensions/refs/heads/main/doc/Learn/DependencyInjection/DependencyInjectionOverview.md --- uid: Uno.Extensions.DependencyInjection.Overview --- # Dependency Injection Apps built using hosting can leverage dependency injection (DI) to register services and make them available to app dependencies. This pattern enables apps to follow sound design principles, such as [SOLID](https://en.wikipedia.org/wiki/SOLID) and [Inversion of Control](https://en.wikipedia.org/wiki/Inversion_of_control). While the host builder implements standard functionality from the [Microsoft.Extensions.DependencyInjection](https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection) library, it also provides additional features to improve the developer experience. ## Registering Services Services are registered with the host using the `ConfigureServices` method on the `IHostBuilder`. The following snippet shows how to register a service with the host: ```csharp private IHost Host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs e) { var appBuilder = this.CreateBuilder(args) .Configure(host => { host .ConfigureServices((context, services) => { services.AddSingleton(); }) }); Host = appBuilder.Build(); ... } ``` Before the `IHost` instance is created, the `ConfigureServices` method is called to register services with the host. The `ConfigureServices` method is called from the lambda expression passed into the `Configure` method. `ConfigureServices` itself takes two parameters: a `HostBuilderContext` and an `IServiceCollection`. The `HostBuilderContext` provides access to the host's configuration and environment. The `IServiceCollection` is used to register services with the host. ## Resolving Services The recommended way to resolve services is to use constructor injection. The following snippet shows how to resolve a service from the host: ```csharp public class SimpleViewModel : ObservableObject { public SimpleViewModel(ISimpleService service) { Service = service; } public ISimpleService Service { get; } } ``` Services can also be resolved from an `IHost` instance: ```csharp var service = Host.Services.GetService(); ``` ## Service Lifetimes Services can be registered with the host using different lifetimes. The following table shows the different service lifetimes: | Lifetime | Description | |----------|-------------| | `Transient` | A new instance of the service is created each time it is requested. | | `Scoped` | A single instance of the service is created per scope. | | `Singleton` | A single instance of the service is created for the lifetime of the host. | Typically, services are registered with the `Singleton` lifetime. ## Named Services Uno.Extensions provides a way to register multiple services of the same type with different names. This is useful in scenarios where multiple implementations of the same service are configured differently in an implementation factory and the correct implementation needs to be resolved at runtime. The following snippet shows how to register a named service with the host: ```csharp private IHost Host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs e) { var appBuilder = this.CreateBuilder(args) .Configure(host => { host .ConfigureServices((context, services) => { services.AddNamedSingleton("SimpleNamedServiceOne"); services.AddNamedSingleton("SimpleNamedServiceTwo"); }) }); Host = appBuilder.Build(); ... } ``` Services can be resolved by name using the `GetNamedService` extension method: ```csharp var service = Host.Services.GetNamedService("SimpleNamedServiceOne"); ``` ## Service Implementation Factories Uno.Extensions provides a way to register services using a factory method. This is useful in scenarios where the service implementation is not known until runtime. The following snippet shows how to register a service with the host using a factory method: ```csharp private IHost Host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs e) { var appBuilder = this.CreateBuilder(args) .Configure(host => { host .ConfigureServices((context, services) => { services.AddSingleton(serviceProvider => { var configuration = serviceProvider.GetRequiredService(); var simpleService = new SimpleService(); simpleService.Configure(configuration); return simpleService; }); }) }); Host = appBuilder.Build(); ... } ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/ElevatedView.md --- uid: Uno.Features.ElevatedView --- # ElevatedView In many design languages (like [_Material Design_](https://material.io/design)), there's a notion of 'elevation' where a portion of the UI should be presented as being _elevated_ over the rest of the content. In this case, WinUI's native elevation API can't work on all platforms because of technical limitations. To address this problem, Uno provides a control called `ElevatedView`, able to produce a similar elevated effect on all platforms (WinUI, Android, iOS, macOS, WebAssembly, and Skia). This control is very useful for creating cards with both rounded corners and an elevated effect - which could otherwise be challenging to produce on some platforms. ## How to use the `ElevatedView` First you need to add the `toolkit` namespace in your XAML file: ```xml xmlns:toolkit="using:Uno.UI.Toolkit" ``` After that, use the `ElevatedView` to host the content you need to be elevated: ```xml ``` Will produce the following result: ![ElevatedView sample](../Assets/features/elevatedview/elevatedview-sample.png) > **ATTENTION FOR WinUI**: When there is an error resolving the `` on WinUI, the common mistake is to forget to include the `Uno.WinUI` package for all platforms, including WinUI. On WinUI, the only component that the `Uno.WinUI` package adds is the Toolkit. ## Settings You can set the following properties: * `Elevation`: numeric number representing the level of the elevation effect. Typical values are between 5 and 30. The default is `0` - no elevation. * `ShadowColor`: By default, the shadow will be `Black`, but you can set any other value. You can reduce the shadow effect by using the alpha channel. * `Background`: The default is `null`, which does not show a shadow. You'll need to specify a color to avoid having a shadow below a transparent surface if the stretching does not match the child. * `CornerRadius`: Use it to create rounded corner effects. The shadow will follow them. ## Particularities * Make sure to _give room_ for the shadow in the layout (eg. by setting a `Margin` on the `ElevatedView`). Some platforms like macOS may clip the shadow otherwise. For the same reason, avoid wrapping the `` directly in a `` because it's designed to clip its content. --- # Source: https://raw.githubusercontent.com/unoplatform/uno.extensions/refs/heads/main/doc/ExtensionsOverview.md --- uid: Uno.Extensions.Overview --- # Get to a fully functional project in minutes Uno.Extensions is a series of NuGet packages designed to encapsulate common functions when building multi-platform mobile, desktop, and web applications using Uno Platform. Thoughtfully designed components and features retain easy extensibility and customization while providing a solid foundation for your application. The Uno.Extensions follows the Microsoft.Extensions model that creates a host environment where you can register additional dependencies. The registered dependencies are then available throughout the application via the Services (`IServiceProvider`) property on the `IHost` instance. ## Learn about Uno.Extensions features Alongside Uno, the app template references a lineup of battle-tested packages providing key features. The resources below are available to help you get started with them in your project. |Feature|Description| |---|---| |[Authentication](xref:Uno.Extensions.Authentication.HowToAuthentication)|The Uno.Extensions.Authentication package provides authentication services.| |[Configuration](xref:Uno.Extensions.Configuration.HowToConfiguration)|The Uno.Extensions.Configuration package provides a way to configure an application based on a list of name-value pairs.| |[Dependency injection](xref:Uno.Extensions.DependencyInjection.HowToDependencyInjection)|The Uno.Extensions.DependencyInjection package provides a simple and lightweight dependency injection system for .NET.| |[Http](xref:Uno.Extensions.Http.Overview)|The Uno.Extensions.Http package provides configuration for native Http handlers and registration of endpoints.| |[Localization](xref:Uno.Extensions.Localization.HowToUseLocalization)|The Uno.Extensions.Localization package provides access to localizable resources.| |[Logging](xref:Uno.Extensions.Logging.UseLogging)|The Uno.Extensions.Logging package provides a way to log messages to a variety of output targets.| |[Navigation](xref:Uno.Extensions.Navigation.HowToNavigateBetweenPages)|The Uno.Extensions.Navigation package provides a routing framework for navigation.| |[Reactive](xref:Uno.Extensions.Reactive.General)|The Uno.Extensions.Reactive package provides a development framework for reactive applications.| |[Serialization](xref:Uno.Extensions.Serialization.Overview)|The Uno.Extensions.Serialization package provides helpers for JSON serialization.| |[Validation](xref:Uno.Extensions.Validation.Overview)|The Uno.Extensions.Validation package provides support for data validation.| > [!TIP] > To view more detailed information about the specific APIs leveraged in each topic, expand the Reference section in the navigation pane. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/controls/Flyout.md --- uid: Uno.Controls.Flyout --- # Flyout If you want to show a dimmed overlay underneath the flyout, set the `Flyout.LightDismissOverlayMode` property to `On`. If you wish to customize the overlay color, add the following to your top-level `App.Resources`: ```xml ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/controls/Frame.md --- uid: Uno.Controls.Frame --- # Frame > [!TIP] > This article covers Uno-specific information for the `Frame` class. For a full description of the feature and instructions on using it, see [Frame class](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.frame) * Displays Page instances, supports navigation to new pages, and maintains a navigation history to support forward and backward navigation. ## Using Frame with Uno To improve performance during navigation, `Frame` on Android, iOS, and WebAssembly targets operates in different way than in WinUI. Whereas WinUI follows `NavigationCacheMode` property on individual `Page` instances, on iOS and Android we keep the individual page instances in the back stack in memory by default. This way they can be quickly surfaced back to the user during back navigation. This behavior can be controlled using the `FeatureConfiguration.Frame.UseWinUIBehavior` property. This defaults to `true` on Skia targets and to `false` on Android, iOS and WebAssembly. If you set `UseWinUIBehavior` to `true` on Android and iOS, you also need to override the default style for the control. You can do this by explicitly setting the `Style` to `XamlDefaultFrame`: ```xml ``` Or by creating an implicit style based on `XamlDefaultFrame`: ```xml ``` ## Custom fonts in Uno Platform 4.6 or below Uno Platform 4.7 introduces a unified way to include fonts in applications, but if you are still using a previous version of Uno Platform, you can use these directions. ### Custom Fonts on Android Fonts must be placed in the `Assets` folder of the head project, matching the path of the fonts in Windows, and marked as `AndroidAsset`. The format is the same as Windows: ```xml ``` or ```xml ``` ### Custom Fonts on iOS Fonts must be placed in the `Resources/Fonts` folder of the head project, and be marked as `BundleResource` for the build type. Each custom font **must** then be specified in the `info.plist` file as follows: ```xml UIAppFonts Fonts/yourfont.ttf Fonts/yourfont02.ttf Fonts/yourfont03.ttf ``` The format is the same as Windows, as follows: ```xml ``` or ```xml ``` ## Custom Fonts on macOS Fonts must be placed in the `Resources/Fonts` folder of the head project, and be marked as `BundleResource` for the build type. The fonts location path **must** then be specified in the `info.plist` file as follows: ```xml ATSApplicationFontsPath Fonts ``` > [!IMPORTANT] > Please note that unlike iOS, for macOS only the path is specified. There is no need to list each font independently. The format is the same as Windows, as follows: ```xml ``` or ```xml ``` ### Custom fonts on WebAssembly There are 3 ways to use fonts on the WebAssembly platform: 1. Referencing a **font defined in CSS**: Use a font defined using a `@font-face` CSS clause. > [!NOTE] > This was the only available way to define and use a custom font before Uno.UI v4.4. This is useful if the application is using externally referenced CSS as those commonly available on a CDN. 2. Referencing a **font file in application assets**: Use a font file (any web-compatible file format, such as `.ttf`, `.woff`, etc...). This can also be used to reference a font hosted elsewhere using an HTTP address. #### Adding a custom font defined in CSS First, the font needs to be defined in CSS. ```css /* First way: defined locally using data uri */ @font-face { font-family: "RobotoAsBase64"; /* XAML: RobotoAsBase64 */ src: url(data:application/x-font-woff;charset=utf-8;base64,d09GMgABAAA...) format('woff'); } /* Second way: defined locally using external uri targetting the font file */ @font-face { font-family: "Roboto"; /* XAML: CssRoboto */ src: url(/Roboto.woff) format('woff'); } /* Third way: Use an external font definition, optionally hosted on a CDN. */ @import url('http://fonts.cdnfonts.com/css/antikythera'); /* XAML: Antikythera + others available */ ``` Second, you can use it in XAML in this way: ```xml This text should be rendered using the font defined as base64 in CSS. This text should be rendered using the roboto.woff font referenced in CSS. This text should be rendered using the Antikythera font hosted on a CDN. ``` > [!NOTE] > This approach is nice and pretty flexible, but not friendly for multi-targeting. Until Uno.UI v4.4, this was the only way to define custom fonts on this platform. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/customizing-uiapplicationdelegate.md --- uid: Uno.Features.CustomizingUIApplicationDelegate --- # Customizing the `UIApplicationDelegate` on iOS Uno Platform provides the ability to provide custom behavior for `UIApplicationDelegate` on iOS in case of both native- and Skia-based rendering. ## Skia rendering In Skia-based apps, the `App` type no longer derives from `UIApplicationDelegate`. Instead, Uno Platform provides `Uno.UI.Runtime.Skia.AppleUIKit.UnoUIApplicationDelegate`. If you decide to implement your own application lifecycle handling, create a new type that derives from it: ```csharp public class MyApplicationDelegate : Uno.UI.Runtime.Skia.AppleUIKit.UnoUIApplicationDelegate { // Your own code or overrides } ``` You then need to inform Uno Platform to use this custom class instead of the built-in delegate by adjusting the host creation in `Main.iOS.cs`: ```csharp using Uno.UI.Hosting; var host = UnoPlatformHostBuilder.Create() .App(() => new SamplesApp.App()) .UseAppleUIKit(builder => builder.UseUIApplicationDelegate()) .Build(); host.Run(); ``` > [!IMPORTANT] > Make sure to call the `base` methods when you override key application lifecycle methods, so that the internals of Uno Platform are still properly executed. ## Native rendering Your `App` class already derives from `UIApplicationDelegate`. This means you can directly override the UIKit methods this class provides: ```csharp public App : Application { // Existing code in App.xaml.cs public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) { // Your custom handling return base.FinishedLaunching(application, launchOptions); } } ``` > [!IMPORTANT] > Make sure to call the `base` methods when you override key application lifecycle methods, so that the internals of Uno Platform are still properly executed. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/debugging-inspect-visual-tree.md --- uid: Uno.Contributing.InspectVisualTree --- # Inspecting the runtime visual tree of an Uno app Often the first step in debugging a UI bug is to scrutinize the application's visual tree. The visual tree is derived from the app's layout defined in XAML, but there's not a straightforward 1-to-1 mapping from XAML to runtime visual tree, due to templating, view manipulation in code, etc. Also, by definition if you're getting a UI bug then there's a discrepancy between what you expect based on the XAML and code and the behavior you're actually observing. Don't live in suspense – check the visual tree! Tools for inspecting the visual tree differ by platform. ## UWP UWP has by far the easiest and most convenient experience for debugging the visual tree. The small black toolbar at the top center of your app during debugging enable buttons to go to the Live Visual Tree view, directly select a visual element for inspection, and show layouting decorations. The complement to the Live Visual Tree is the Live Property Explorer, which allows you to inspect current values for any property of a view, and even change some of them on the fly. ![UWP Live Visual Tree](assets/debugging-inspect-visual-tree/UWP-Live-Visual-Tree.jpg) ## Android There are a couple of options for viewing the visual tree of an Uno app running on Android. One approach is to use [Android Studio](https://developer.android.com/studio). You can then attach the debugger to your running process and take a snapshot with the [Layout Inspector](https://developer.android.com/studio/debug/layout-inspector), which allows you to select different elements visually, see their properties, see the whole visual tree, etc. ![Android Studio Layout Inspector](assets/debugging-inspect-visual-tree/Android-Layout-Inspector.jpg) The other approach is to use the [Stetho package](https://www.nuget.org/packages/nventive.Stetho.Xamarin). It integrates into your app with a few lines of code, and then allows you to inspect the visual tree in Chrome. One nice feature is it allows you to press any element on the device's screen to locate it in the visual tree. Unfortunately neither of these approaches give you an easy way to inspect properties defined on UIElement, FrameworkElement, and other managed types. You can however look at native properties to obtain information like layout size, opacity, etc. ## iOS In principle it's possible to use Xcode's 'Debug View Hierarchy' feature on any iOS app, including Uno apps. The steps are the following: 1. Launch Xcode 2. Create a dummy iOS app (or open an existing one) - you won't actually run this app. 3. Run the app whose layout you wish to inspect. 4. Set the device or simulator you're using as the active device in the upper toolbar. 5. Select Debug -> Attach to Process -> [name of the app] 6. Once the debugger has successfully attached, select Debug -> View Debugging -> Capture View Hierarchy. In practice, Xcode is somewhat temperamental, and this approach may fail for some apps. It's recommended to fall back on the breakpoint-based inspection method described below. ## Web For an Uno.WASM app you can simply use the layout inspection tools built into whatever browser you're using. For example, for Chrome, open the 'Developer tools' panel (`F12`) and select the 'Elements' tab, or just right-click any element in the visual tree and choose 'Inspect.' ![DOM tree in Chrome](assets/debugging-inspect-visual-tree/WASM-DOM-Elements.jpg) You can configure Uno to annotate the DOM with the values of common XAML properties. Just add the following somewhere in your app's entry point (eg the constructor of `App.cs` or `App.xaml.cs`): ```csharp #if DEBUG && __WASM__ // Annotate generated DOM elements with x:Name Uno.UI.FeatureConfiguration.UIElement.AssignDOMXamlName = true; // Annotate generated DOM elements with commonly-used XAML properties (height/width, alignment etc) Uno.UI.FeatureConfiguration.UIElement.AssignDOMXamlProperties = true; #endif ``` **Note:** for performance reasons, if a _release build_ of Uno.UI is used, `AssignDOMXamlProperties` will only display the values of properties as they were when the element was loaded - that is, they may be stale in some cases. If a _debug build_ of Uno.UI is used, this limitation is lifted and the DOM annotation will reflect the most up-to-date values. ## Retrieving the visual tree through code or at a breakpoint (Android/iOS/WebAssembly/macOS) It's common enough when debugging Uno to be at a breakpoint and want to quickly know exactly where the view is in the visual tree, that we added a helper method. If you're using a debug build of Uno, this is directly available on UIElement as the `public string ShowLocalVisualTree(int fromHeight)` method (for ease of use in the watch window). If you're using the release version of Uno, the same method is available as an extension in UIKit.UIViewExtensions for iOS or Uno.UI.ViewExtensions for Android. The method returns the visual tree from a certain 'height' above the target element as an indented string. So if you call ShowLocalVisualTree(2), you'll get the visual subtree from the target element's grandparent down. If you call ShowLocalVisualTree(100), you'll almost certainly get the entire visual tree starting from the root element. The original target is picked out with an asterisk (*) so you can find it. ![ShowLocalVisualTree() on iOS](assets/debugging-inspect-visual-tree/iOS-ShowLocalVisualTree.jpg) Similarly to the `ShowLocalVisualTree` method, there is also the `TreeGraph` method that produces a tree with more details suited for troubleshooting visual/layout issue: ```csharp using Uno.UI.Extensions; ... private void DebugVT(object sender, RoutedEventArgs e) { var tree = this.TreeGraph(); } // <-- add a breakpoint here ``` ![TreeGraph](assets/debugging-inspect-visual-tree/tree-graph.png) The advantage of this over `ShowLocalVisualTree` is the ability to customize the amount of details, as it has an overload that takes in a `Func` to describe the visual tree node: > [!NOTE] > For more examples of control details, check out these source files: > > - [`DebugVTNode\GetDetails()` method in Toolkit](https://github.com/unoplatform/uno.toolkit.ui/blob/main/src/Uno.Toolkit.UI/Helpers/VisualTreeHelperEx.cs) > - [`DescribeVTNode\GetDetails()` method in Uno](https://github.com/unoplatform/uno/blob/master/src/Uno.UI/Extensions/ViewExtensions.visual-tree.cs) ```csharp var tree = this.TreeGraph(Describe); ... private static string Describe(object x) { if (x is null) return ""; return new StringBuilder() .Append(x.GetType().Name) .Append((x as FrameworkElement)?.Name is string { Length: > 0 } xname ? $"#{xname}" : string.Empty) .Append(GetPropertiesDescriptionSafe()) .ToString(); string? GetPropertiesDescriptionSafe() { try { return string.Join(", ", DescribeDetails(x)) is { Length: > 0 } propertiesDescription ? $" // {propertiesDescription}" : null; } catch (Exception e) { return $"// threw {e.GetType().Name}: {e.Message}"; } } } private static IEnumerable DescribeDetails(object x) { // add details pertinent to your debug session: if (x is FrameworkElement fe) { yield return $"Actual={fe.ActualWidth:0.#}x{fe.ActualHeight:0.#}"; yield return $"Constraints=[{fe.MinWidth:0.#},{fe.Width:0.#},{fe.MaxWidth:0.#}]x[{fe.MinHeight:0.#},{fe.Height:0.#},{fe.MaxHeight:0.#}]"; yield return $"HV={fe.HorizontalAlignment}/{fe.VerticalAlignment}"; } if (x is ScrollViewer sv) { yield return $"Offset={sv.HorizontalOffset:0.#},{sv.VerticalOffset:0.#}"; yield return $"Viewport={sv.ViewportWidth:0.#}x{sv.ViewportHeight:0.#}"; yield return $"Extent={sv.ExtentWidth:0.#}x{sv.ExtentHeight:0.#}"; } if (x is ListViewItem lvi) { yield return $"Index={ItemsControl.ItemsControlFromItemContainer(lvi)?.IndexFromContainer(lvi) ?? -1}"; } } ``` ### Retrieving the visual tree of a flyout/popup You can add a slight delay before dumping the visual tree, giving you time to open the flyout: ```csharp private async void DebugVT(object sender, RoutedEventArgs e) { // ample time to click on the flyout await Task.Delay(5000); // grab the popup's root for tree-graphing var root = VisualTreeHelper.GetOpenPopupsForXamlRoot(XamlRoot).FirstOrDefault()?.Child; var tree2 = root?.TreeGraph(); } // <-- add a breakpoint here ``` This same technique is also useful for when you need the visual tree at certain specific moments, like during mouse-hover, pressed states of some control. ## Tips for interpreting runtime view information - Look for view types defined in the app's namespace to 'orient yourself' in the visual tree. - Expect to see more views in the materialized tree than just those defined by XAML. Some are added by default control templates, some are platform-specific, some may be created by code-behind... --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/debugging-templates.md --- uid: Uno.Contributing.DebuggingTemplates --- # Debugging Uno Platform Solution templates The uno platform project contains multiple types of templates: - `dotnet new` templates - Visual Studio (2022/2026) Extensions templates (vsix) Some of the templates are reusing the same sources. For example the full solution template is defined in the vsix project, and building the `dotnet new` template creates a transformed version of the vsix template. ## dotnet new templates `dotnet new` new templates use the dotnet/templating engine, and are located in the `src/SolutionTemplate/Uno.ProjectTemplates.Dotnet` folder. To make modifications to those templates and test the result: - In Visual Studio, open the solution using the [Uno.UI-SolutionTemplates.slnf](building-uno-ui.md) filter - Right click on the `Uno.ProjectTemplates.Dotnet` project, select `Pack` - This will create a `Uno.ProjectTemplates.Dotnet.255.255.255.255.nupkg` file - Install this file using `dotnet new -i C:\[your_path]\bin\Debug\Uno.ProjectTemplates.Dotnet.255.255.255.255.nupkg` - In another temporary folder, create a new application using the updated templates with `dotnet new unoapp -o MyTestUnoApp01` Ensure that the application runs properly by building it in Visual Studio and running it on all targets. Once you're done with debugging the templates, you can go back to the official templates with: ```dotnetcli dotnet new -i Uno.ProjectTemplates.Dotnet ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/debugging-troubleshooting.md --- uid: Uno.Debugging.Troubleshooting --- # Debugging Troubleshooting This section covers common issues along with simple workarounds to resolve them. If you're hitting roadblocks, you might find a solution here! ## Issue: Breakpoint Misfires on a Line with Multiple Statements **Problem:** When setting a breakpoint on a line with multiple statements, such as: ```csharp int x = 1; int y = 2; ``` or ```csharp public object MyObject { get => _myObject; set => _myObject = value; } ``` On **Mobile (Android and iOS)** or **WebAssembly (WASM)**, Mono might only hit the first or last statement due to how it handles sequence points. This makes debugging on such lines unreliable. **Workaround:** To ensure proper breakpoint hits, split each statement onto its own line: ```csharp int x = 1; int y = 2; ``` ```csharp public object MyObject { get => _myObject; set => _myObject = value; } ``` Now, Mono will correctly hit each breakpoint as expected. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/debugging-uno-ui.md --- uid: Uno.Contributing.DebuggingUno --- # Debugging Uno.UI > [!NOTE] > [Find instructions for building the Uno.UI solution here.](xref:Uno.Contributing.BuildingUno) ## Debugging Uno.UI samples To debug the **SamplesApp** in the Uno.UI solution, which includes an extensive set of samples and test cases for the controls supported by Uno.UI, as well as non-UI features: 1. Clone the repo, and ensure using a short target path, e.g. _D:\uno_ etc. > [!NOTE] > This is required to avoid path length limitations in the .NET framework being used by Visual Studio. 2. Open the solution filter in Visual Studio for the target platform you wish to run on, [as detailed here](xref:Uno.Contributing.BuildingUno). 3. Set `SamplesApp.[TargetPlatform]` as the selected Startup Project. 4. Launch the samples app from Visual Studio. See [this article](working-with-the-samples-apps.md) for more information on working with the SamplesApp and authoring new samples. ## Debugging Uno in another application It is also possible to debug Uno.UI code in an application outside the Uno.UI solution. The Uno.UI build process has an opt-in mechanism to overwrite the contents of the NuGet cache, causing the application to use your local build of Uno. > [!NOTE] > This will **overwrite your local NuGet cache**. This is useful when debugging a problem that can't easily be reproduced outside the context of the app where it was discovered. It can even speed up your development loop when working on a new feature or fixing a bug with a standalone repro, because a small 'Hello World' app builds considerably faster than the full SamplesApp. First, update `global.json` of the app you will be debugging to instead use a `-dev.xxx` version: ```diff { // To update the version of Uno please update the version of the Uno.Sdk here. See https://aka.platform.uno/upgrade-uno-packages for more information. "msbuild-sdks": { - "Uno.Sdk": "6.1.23" + "Uno.Sdk": "6.2.0-dev.59" }, ``` The versions of Uno.Sdk are listed on [NuGet.org](https://www.nuget.org/packages/Uno.Sdk/). Typically, you want to use the latest one, in order to match the most recent commit on the `master` branch of uno. Once `global.json` has been updated, restore your app's solution: ```dotnetcli dotnet restore ``` Next, determine the _`$(UnoNugetOverrideVersion)` value_ for your selected `-dev.xxx` version: 1. View the specified `Uno.Sdk` package version on NuGet.org, e.g. 1. Select the **README** tab. 1. On the **README** tab, determine the value of the `UnoVersion*` property. For the Uno.Sdk 6.2.0-dev.59 NuGet package, the `UnoVersion*` property is `6.2.0-dev.171`. This is the `$(UnoNugetOverrideVersion)` value. Then, here are the steps to use a local build of Uno.UI in another application: 1. Configure the Uno.UI solution to build for the target platform you wish to debug, [as detailed here](xref:Uno.Contributing.BuildingUno). 1. Close any instances of Visual Studio with the Uno.UI solution opened. 1. Open the solution containing the application you wish to debug to ensure the package is restored and cached. 1. Prepare the application 1. Make a copy of `src/crosstargeting_override.props.sample` and name it as `src/crosstargeting_override.props`. 1. In `src/crosstargeting_override.props`, uncomment the line `` and set the `$(UnoNugetOverrideVersion)` value to the value determined in the previous section, e.g. `6.2.0-dev.171`. You want to use the `UnoVersion*` version here. _Do not mix it up with `Uno.Sdk` version_. 1. Open the appropriate Uno.UI solution filter and build the following: - For iOS/Android native, you can right-click on the `Uno.UI` project - For WebAssembly/native, you can right-click on the `Uno.UI.Runtime.WebAssembly` project - For Skia, you can right-click on the corresponding `Uno.UI.Runtime.Skia.[Win32|X11|macOS|iOS|Android|Wpf]` project. To debug Uno.UI code in the application, follow these steps (using `FrameworkElement.MeasureOverride()` as an example): 1. Open [`FrameworkElement.cs`](https://github.com/unoplatform/uno/blob/master/src/Uno.UI/UI/Xaml/FrameworkElement.cs) in the Uno.UI solution. 2. Right-click on the `FrameworkElement.cs` tab header in Visual Studio and choose 'Copy Full Path'. 3. Switch to the Visual Studio instance where your application is open. 4. In your application solution, choose File->Open->File... or simply `Ctrl+O`, paste the path to `FrameworkElement.cs` into the file open dialog, and open `FrameworkElement.cs` in the application solution. 5. Put a breakpoint in the `MeasureOverride()` method. 6. Launch the application. 7. You should hit the breakpoint, opening the `FrameworkElement.cs` file, and be able to see local variable values, etc. 8. To revert to the original Uno.UI version from NuGet, simply navigate to the NuGet cache folder (`%USERPROFILE%\.nuget\packages`) and delete the `Uno.UI` folder within it. You may need to close Visual Studio first. The original version will be automatically restored the next time the application builds. ### Tips about the NuGet version override process - Be aware that setting `UnoNugetOverrideVersion` will **overwrite your local NuGet cache** for the nominated Uno.UI version. Any applications that you build locally will use your local build if they depend on that Uno.UI version. - Building for Android requires the API level to match the version you specified in `UnoTargetFrameworkOverride`. A common issue is that the app being debugged uses Android 10.0, and `Uno.UI` is built using Android 11.0. You can change the API level in the debugged project's build properties. - The NuGet override process only works on already installed versions. The best way to ensure that the override is successful is to build the debugged application once before overriding the Uno.UI version the app uses. - Make sure to close the application that uses the overridden nuget package, to avoid locked files issues on Windows. - Verify that your updated files are actually used. View [diagnostic logs](https://learn.microsoft.com/en-us/visualstudio/msbuild/obtaining-build-logs-with-msbuild?view=vs-2022), search for the assembly that you are modifying, and verify that it contains the updated `$(UnoNugetOverrideVersion)` value in the path, e.g. that the `@(RuntimeCopyLocalItems)` item group contains `%USERPROFILE%\.nuget\packages\uno.winrt\6.2.0-dev.171\lib\net9.0-android30.0\Uno.UI.Dispatching.dll` (Windows) or `$HOME/.nuget/packages/uno.winrt/6.2.0-dev.171/lib/net9.0-android30.0/Uno.UI.Dispatching.dll` (Linux, macOS). ### Troubleshooting It may happen that the package cache for the version you're debugging is corrupted, and the override is not working as intended. If this is the case: - In your debugged app, install another package version you've never debugged with - Make sure to build the app once to populate the NuGet cache - Rebuild the Uno.UI project (or **Uno.UI.WebAssembly**/**Uno.UI.Runtime.Skia.\***) to replace the binaries with your debug versions - Rebuild your app and debug it again ## Microsoft Source Link support Uno.UI supports [SourceLink](https://github.com/dotnet/sourcelink/) and it now possible to step into Uno.UI without downloading the repository. Make sure **Enable source link support** check box is checked in **Tools** / **Options** / **Debugging** / **General** properties page. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/debugging-wasm.md --- uid: Uno.Development.DebuggingWasm --- # Using the WebAssembly C# Debugger There are two ways to debug a WebAssembly application: - Using Visual Studio integrated debugger (preferred) - Using the browser's debugger ## Using Visual Studio Here's what you need to do to debug an Uno Platform application in Visual Studio (2022 17.3+ or later): - Install the latest [Uno Platform Visual Studio templates](./get-started-vs-2022.md#install-the-solution-templates) - Have Chrome or Edge (Chromium based) - In the NuGet Package Manager, update `Uno.Wasm.Bootstrap` and `Uno.Wasm.Bootstrap.DevServer` 8.0.0 or later - Ensure that `true` is set in your csproj. It is automatically set [when using the Uno.SDK](xref:Uno.Features.Uno.Sdk). - Ensure that in the `Properties/launchSettings.json` file, the following like below each `launchBrowser` line: ```json "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", ``` Then you can start debugging with the VS debugger toolbar: - Select **MyApp (WebAssembly IIS Express)** or your application name as the debugging target - Select **Chrome** or **Microsoft Edge** as the Web Browser - Press F5 or _Debug_ > _Start Debugging_ You should now be able to set breakpoints or do step-by-step debugging of your code. ### Tips for debugging in visual studio - Some debugger features may not have yet been implemented by the .NET and Visual Studio team. You can take a look at the [dotnet/runtime](https://github.com/dotnet/runtime) repository for more details. - If the breaking does not hit, make sure that the `inspectUri` lines have been added to the `Properties/launchSettings.json` file. - Methods with only invocations to generated code (e.g. control constructors with only "InitializeComponent" in it) may not allow placing breakpoints. Add some explicit code in the scope to place breakpoints. ## Using the browser debugger To debug your application: - Make the `net9.0-browserwasm` active debugging target framework (right-click **set as startup** in Solution Explorer) - Ensure that `true` is set in your csproj. It is automatically set [when using the Uno.SDK](xref:Uno.Features.Uno.Sdk). - In the debugging toolbar: - Select **MyApp (WebAssembly IIS Express)** as the debugging target - Select **Chrome** or **Microsoft Edge** as the Web Browser - Make sure script debugging is disabled
![IIS express settings](Assets/quick-start/wasm-debugging-iis-express.png) - Start the debugging session using CtrlF5 or _Debug_ > _Start Without Debugging_ from the menu, (F5 will work, but the debugging experience won't be in Visual Studio) - Once your application has started, press AltShiftD (in Chrome, on your application's tab) - A new tab will open with the debugger or instructions to activate it ![Debugger - New tab with instructions to activate it](Assets/quick-start/wasm-debugger-step-01.png) - You will now get the Chrome DevTools to open listing all the .NET loaded assemblies on the Sources tab:
![Debugger - Chrome DevTools listing all the .NET loaded assemblies on the Sources tab](Assets/quick-start/wasm-debugger-step-02.png) - You may need to refresh the original tab if you want to debug the entry point (Main) of your application.
![Debugger - The smaller refresh button location in the preview section of the Chrome DevTools](Assets/quick-start/wasm-debugger-step-03.png) > ### Tips for debugging in Chrome > > - You need to launch a new instance of Chrome with right parameters. If Chrome is your main browser > and you don't want to restart it, install another version of Chrome (_Chrome Side-by-Side_). > You may simply install _Chrome Beta_ or _Chrome Canary_ and use them instead. > - Sometimes, you may have a problem removing a breakpoint from code (it's crashing the debugger). > You can remove them in the _Breakpoints list_ instead. > - Once _IIS Express_ is launched, no need to press CtrlF5 again: you simply need to rebuild your > _WASM_ head and refresh it in the browser. > - **To refresh an app**, you should use the debugger tab and press the _refresh_ button in the content. > - **If you have multiple monitors**, you can detach the _debugger tab_ and put it on another window. > - For breakpoints to work properly, you should not open the debugger tools (F12) in the app's tab. > - If you are **debugging a library which is publishing SourceLinks**, you must disable it or you'll > always see the SourceLink code in the debugger. SourceLink should be activated only on Release build. > - When debugging in Chrome, Ctrl+O brings up a file-search field. That way it's a lot easier to find .cs files versus searching through the whole folder hierarchy. --- # Source: https://raw.githubusercontent.com/unoplatform/figma-docs/refs/heads/main/get-started/design-to-code.md --- uid: Uno.Figma.GetStarted.DesignToCode --- # Design to Code This section will guide you through the process of generating UI code (XAML or C# Markup) from a Figma document using the [Uno Platform Figma Plugin](https://aka.platform.uno/uno-figma-plugin). > [!IMPORTANT] > Is it required to have completed the [Setup](setup.md) section before starting this one. ## Start with a clean copy of the Uno Material Toolkit document 1. Must be in a copy of the _Uno Material Toolkit_ document. If not, follow the [Setup](setup.md) section to create a new copy. 2. Navigate to _Example App_ Figma page ![Navigate to Example App page](assets/navigate-example-app-page.png) 3. Locate the _01. Login_ frame, right-click on it and launch the _Uno Platform (Figma to C# or XAML)_ plugin ![Launching the plugin by right-clicking on a frame](assets/launch-plugin-right-click.png) ... the plugin should launch in the side panel or a module window. > [!NOTE] > This step assumes the plugin has been closed. If already opened, just select the _01. Login_ frame and continue to the next step. 4. Click the _Refresh_ button to see the selected page in the plugin previewer ![Previewing the Login page in the plugin](assets/plugin-render-login.png) 5. Switch to the _Export_ tab, where the generated XAML is displayed ![Switching to the Export tab](assets/export-xaml-tab.png) 6. Click the _Copy_ button to copy the generated XAML to the clipboard. Alternatively, you can also select the XAML and copy it manually. > [!NOTE] > This simple tutorial generates XAML code, but it is also possible to generate C# markup instead. > Click here for more information: [Overview of C# Markup in Uno Platform](xref:Uno.Extensions.Markup.Overview). ## Next step This tutorial has shown you how to generate code from a Figma document using the Uno Platform Figma Plugin. The next step is to use that generated code in an app by following the [Create an App](create-an-app.md) guide. The code generated in this section will be used in this next section. ## See also * [Setup](setup.md) - This section explains how to setup your environment to use the plugin. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/dev-server.md --- uid: Uno.DevServer --- # Dev Server The Dev Server is the local development companion that enables productive inner-loop features in Uno Platform, such as Hot Reload, design-time updates, and IDE integration. It runs as a lightweight HTTP process and maintains a bidirectional channel with the IDE and the running application. ## Overview - Provides a transport between the IDE and the running application to exchange development-time messages - Powers Hot Reload and Hot Design experiences by delivering code and XAML updates - Starts automatically and stays out of the way; you usually do not have to configure it ## Prerequisites - Requires .NET SDK, [same version as uno](xref:Uno.Development.NetVersionSupport) - Works in Debug builds, where connection information is embedded so the app can reach the Dev Server ## When and how the Dev Server starts > [!NOTE] > The Dev Server starts only when Uno Platform packages are referenced by your project(s). > > [!NOTE] > The Dev Server won't start until NuGet package restore has completed successfully (a failed or pending restore prevents startup). 1. Open the solution: the IDE reserves a free TCP port and writes it to each project's .csproj.user file under the UnoRemoteControlPort property. 2. Build/run in Debug: the app is built with the Dev Server connection information. 3. Launch the app (Debug): the app connects back to the Dev Server. 4. Develop: the IDE and app exchange development-time messages (e.g., Hot Reload updates). ## Command-line (advanced usage for specific scenarios) You can manage the Dev Server from the command line using the dotnet tool `Uno.DevServer` (command: uno-devserver): - `uno-devserver start`: Start the Dev Server for the current solution directory - `uno-devserver stop`: Stop the Dev Server attached to the current directory - `uno-devserver list`: List running Dev Server instances - `uno-devserver cleanup`: Terminate stale Dev Server processes - `uno-devserver login`: Open the Uno Platform settings application - `--mcp-app`: Run an MCP proxy mode for integration with MCP-based tooling - `--port | -p `: Optional port value for MCP proxy mode - `--mcp-wait-tools-list`: Wait for the upstream Uno App tools to become available before responding to clients. Use this when working with MCP agents that do not react to `tool_list_changed` (for example, Codex or Claude Code). - `--force-roots-fallback`: Skip the MCP `roots` handshake and expose the `uno_app_set_roots` tool so agents that cannot send workspace roots can still initialize (required for Google Antigravity). - `--force-generate-tool-cache`: Immediately request the Uno App tool list once the Dev Server is online and persist it to the local cache. Use this to prime CI environments or agents that expect a tools cache before they can call `list_tools`. - `--solution-dir `: Explicit solution directory Uno.DevServer should monitor. Useful when starting the DevServer manually (e.g., CI agents) or when priming tools via `--force-generate-tool-cache`. Defaults to the current working directory when omitted. ## Hot Reload The Dev Server enables Hot Reload for a faster inner loop: - C# Hot Reload for managed code changes - XAML and resource updates without restarting the app - Asset updates in supported scenarios ## Security - Uses a random local port, making it hard to guess - Intended for local development only and relies on your local network security - Do not expose the Dev Server to untrusted networks > [!IMPORTANT] > The Dev Server is a development-time facility. It is not required nor recommended for production deployments. ## Troubleshooting ### [**Common issues**](#tab/common-issues) - The TCP port number used by the app to connect back to the IDE is located in the property of the [ProjectName].csproj.user file. If the port number does not match with the one found in the Uno Platform - Hot Reload output window, restart your IDE. - If the Dev Server does not start, ensure NuGet restore has completed successfully and Uno Platform packages are referenced by your project(s). ### [**Visual Studio**](#tab/vswints) - The Output window in Visual Studio includes an output category named `Uno Platform`. Diagnostic messages from the Uno Platform VS extension appear there. To enable logging, set MSBuild project build output verbosity to at least "Normal" (above "Minimal"). These changes should take effect immediately without a restart; if you do not see additional logs, try restarting Visual Studio. For more details on build log verbosity, refer to the [official Visual Studio documentation](https://learn.microsoft.com/en-us/visualstudio/ide/how-to-view-save-and-configure-build-log-files?view=vs-2022#to-change-the-amount-of-information-included-in-the-build-log). If you need to share logs when opening an issue on the GitHub [Uno Platform repository](https://github.com/unoplatform/uno), set verbosity to **Diagnostic** to provide the most detailed logs for investigation. **Steps to change MSBuild output verbosity:** 1. Open **Tools > Options > Projects and Solutions > Build and Run**, then set **MSBuild output verbosity** to **Diagnostic** or the required level. ![MSBuild output verbosity drop-down](Assets/features/hotreload/vs-msbuild-output-verbosity.png) 2. Restart Visual Studio, re-open your solution, and wait a few seconds. 3. Go to **View > Output**. 4. In the Output window, select `Uno Platform` from the drop-down. ![Uno Platform output drop-down](Assets/features/hotreload/vs-uno-platform-logs.png) ### [**Visual Studio Code**](#tab/vscodets) - The Output window in Visual Studio Code includes an output category named `Uno Platform` in its drop-down menu. Diagnostic messages from the Uno Platform VS Code extension appear there. **Steps to see the `Uno Platform` output:** 1. In the status bar at the bottom left of VS Code, ensure `NameOfYourProject.csproj` is selected (by default `NameOfYourProject.sln` is selected). ![.csproj selection in Visual Studio Code](Assets/features/hotreload/vscode-csproj-selection.png) 2. Wait a few seconds. 3. Go to **View > Output**. 4. In the Output window, select `Uno Platform` from the drop-down. ![`Uno Platform` output drop-down](Assets/features/hotreload/vs-code-uno-platform-hr-output.png) ### [**Rider**](#tab/riderts) - The Output window in Rider includes an output category named `Uno Platform` in its sidebar. Diagnostic messages from the Uno Platform Rider plugin appear there. **Steps to see the Uno Platform output:** 1. In the sidebar at the bottom left of Rider, click on the Uno Platform logo. ![Uno Platform output logo](Assets/features/hotreload/rider-uno-platform-output.png) 2. In the Output window, select **LEVEL: Trace** from the drop-down. ![Level output drop-down](Assets/features/hotreload/rider-output-level-trace.png) --- --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/dialogs.md --- uid: Uno.Features.Dialogs --- # Dialogs > [!TIP] > This article covers Uno-specific information for dialog controls in Uno Platform. For a full description of the feature and instructions on using it, see [Dialog controls | Microsoft Learn](https://learn.microsoft.com/windows/apps/design/controls/dialogs-and-flyouts/dialogs). * The `Microsoft.UI.Xaml.Controls.ContentDialog` class provides a XAML-based and highly customizable user dialog. * The `Windows.UI.Popups.MessageDialog` represents a legacy dialog which provides less control over UI. ## Using `ContentDialog` The recommended way to display user dialogs is via the `Microsoft.UI.Xaml.Controls.ContentDialog` class. ```csharp ContentDialog noWifiDialog = new ContentDialog { Title = "No WiFi connection", Content = "Check your connection and try again.", CloseButtonText = "OK" }; // Make sure to set the XamlRoot! noWifiDialog.XamlRoot = anyLoadedControl.XamlRoot; ContentDialogResult result = await noWifiDialog.ShowAsync(); ``` It is crucial to set the `XamlRoot` property before calling `ShowAsync`. This way the dialog will become associated with the visual tree. `XamlRoot` can be retrieved from any loaded control in your window (e.g. a `Button`, your `Page`, etc.). > [!WARNING] > Only one ContentDialog can be open per thread at a time. Attempting to open two ContentDialogs will throw an exception, even if they are trying to open in separate AppWindows. ### Opening a `ContentDialog` from a Model/ViewModel When you want to open a `ContentDialog` from a Model or ViewModel, you can pass the `XamlRoot` from the view to the model or view model by creating a service (e.g., `IXamlRootProvider`) that is initialized at the start of the app with the XamlRoot of the main window. Here is a more detailed example of how to display a `ContentDialog` with result handling: ```csharp private async Task DisplayDeleteFileDialog() { ContentDialog deleteFileDialog = new ContentDialog { Title = "Delete file permanently?", Content = "If you delete this file, you won't be able to recover it. Do you want to delete it?", PrimaryButtonText = "Delete", CloseButtonText = "Cancel" }; deleteFileDialog.XamlRoot = anyLoadedControl.XamlRoot; ContentDialogResult result = await deleteFileDialog.ShowAsync(); // Delete the file if the user clicked the primary button. // Otherwise, do nothing. if (result == ContentDialogResult.Primary) { // Delete the file. } else { // The user clicked the CloseButton, pressed ESC, Gamepad B, or the system back button. // Do nothing. } } ``` ### [MVVM](#tab/mvvm) If you are using the MVVM pattern, you can use the `AsyncRelayCommand` from the Uno Platform to bind the command to the dialog display method. Here is an example of how to bind the command to the dialog display method in the ViewModel: ```csharp public MainViewModel() { DisplayDeleteFileDialogCommand = new AsyncRelayCommand(DisplayDeleteFileDialog); } // ... public ICommand DisplayDeleteFileDialogCommand { get; } private async Task DisplayDeleteFileDialog() { // ... } ``` ### [MVUX](#tab/mvux) If you are using the MVUX pattern, you don't need to specify the Command. Instead, you can directly call the dialog display method in your view, it is generated automatically in `BindableModel`: ```csharp public async Task DisplayDeleteFileDialogCommand() { // ... } ``` --- To bind the command to a button in your view, you can use the following code snippets: ### [XAML](#tab/xaml) ```xml ``` ![Material - Button lightweight styling](assets/material-lightweight-styling-anatomy.png) Lightweight Styling allows for fine-grained control over the look of your UI components across all visual states. All interactive controls have multiple states, such as **PointerOver** (mouse is hovered over), **Pressed** (control is pressed on), and **Disabled** (control is not interactable). These states are appended onto the endings of the resource keys: ButtonForeground*PointerOver*, ButtonForeground*Pressed*, and ButtonForeground*Disabled*. Combined with these, the `CheckBox` and `RadioButton` controls also have **Checked** and **Unchecked** states. This means that it is possible to customize the appearance of your Uno Material-styled controls across any visual state without the need to redefine the style. As an example, the XAML below defines three Buttons, all using FilledButtonStyle from Uno Material: 1. A Default Button with no changes 2. A Button with several brush resources overridden for the **Normal** visual state 3. A Button that overrides resources that are used with FilledButtonStyle's **PointerOver** visual state ```xml ``` With this XAML, we are given the following visual result, notice the third Button has a new `BorderThickness` applied and takes on different colors while in the **PointerOver** state. ![Material - Button lightweight styling](assets/material-button-pointerover-lightweight-styling.png) ## C# Markup All Lightweight Styling resource keys can also be used in C# Markup through a collection of static helper classes available in the [Uno.Themes.WinUI.Markup](https://www.nuget.org/packages/Uno.Themes.WinUI.Markup/) NuGet package. The following code shows how to override several `FilledButton` resources in C# from the previous XAML example above. Notice that the `Button` is still using the `FilledButtonStyle` from Uno Material, but the resources are being overridden. ```csharp // basic filled button new Button() .Style(Theme.Button.Styles.Filled) .Content("Default Button Style"), // filled button with overridden colors new Button() .Style(Theme.Button.Styles.Filled) .Resources(config => config .Add(Theme.Button.Resources.BorderThickness, 2) .Add(Theme.Button.Resources.Filled.Foreground.Default, new SolidColorBrush(Colors.DarkGreen)) .Add(Theme.Button.Resources.Filled.Background.Default, new SolidColorBrush(Colors.LightGreen)) .Add(Theme.Button.Resources.Filled.BorderBrush.Default, new SolidColorBrush(Colors.DarkGreen)) ) .Content("Overridden Button Style"), // filled button with overridden colors for PointerOver state new Button() .Style(Theme.Button.Styles.Filled) .Resources(config => config .Add(Theme.Button.Resources.BorderThickness, 2) .Add(Theme.Button.Resources.Filled.Foreground.PointerOver, new SolidColorBrush(Colors.DarkRed)) .Add(Theme.Button.Resources.Filled.Background.PointerOver, new SolidColorBrush(Colors.LightPink)) .Add(Theme.Button.Resources.Filled.BorderBrush.PointerOver, new SolidColorBrush(Colors.DarkRed)) ) .Content("Overridden Button Style (PointerOver)") ``` ### Resource Key Pattern The general pattern used for mapping the Lightweight Styling resource keys to C# Markup is as follows: `Theme.{control}.Resources.{?:variant}.{member-path}.{?:visual-state}` | Name Part | Description | |----------------|--------------------------------------------------------------------------------------------------------------------------------------------------| | `control` | Name of the control type (Button, TextBox, CheckBox, etc.) | | `variant` | **(Optional) Defaults to `Default`** Certain styles have multiple variants. Ex: For Button we have variants such as: Outlined, Text, Filled | | `member-path` | The property or the nested property to assign value to. (Foreground, Background, Placeholder.Foreground, etc.) | | `visual-state` | **(Optional) Defaults to `Default`** Specifies which `VisualState` that this resource will be applied to (PointerOver, Checked, Disabled, etc.) | For example, the following resource keys are used with `FilledButtonStyle`, `HyperlinkButtonStyle`, and `CheckBoxStyle` from Uno Material: #### Filled Button - `Theme.Button.Resources.Filled.Foreground.Default` - `Theme.Button.Resources.Filled.Foreground.Pressed` - `Theme.Button.Resources.Filled.Foreground.PointerOver` #### HyperlinkButton (Default) - `Theme.HyperlinkButton.Resources.Default.Foreground.Default` - `Theme.HyperlinkButton.Resources.Default.Foreground.Pressed` - `Theme.HyperlinkButton.Resources.Default.Foreground.PointerOver` #### CheckBox (Default) - `Theme.CheckBox.Resources.Default.Foreground.Checked` - `Theme.CheckBox.Resources.Default.Foreground.CheckedPressed` - `Theme.CheckBox.Resources.Default.Foreground.CheckedPointerOver` All C# Markup-friendly Lightweight Styling resource keys can be found in [Uno.Themes GitHub repository](https://github.com/unoplatform/Uno.Themes/tree/master/src/library/Uno.Themes.WinUI.Markup/Theme) ## Resource Keys For more information about the lightweight styling resource keys used in each control, check out the following links: - [Button](styles/Button.md) - [CalendarDatePicker](styles/CalendarDatePicker.md) - [CheckBox](styles/CheckBox.md) - [ComboBox](styles/ComboBox.md) - [DatePicker](styles/DatePicker.md) - [FloatingActionButton](styles/FloatingActionButton.md) - [HyperlinkButton](styles/HyperlinkButton.md) - [NavigationView](styles/NavigationView.md) - [PasswordBox](styles/PasswordBox.md) - [PipsPager](styles/PipsPager.md) - [ProgressBar](styles/ProgressBar.md) - [ProgressRing](styles/ProgressRing.md) - [RadioButton](styles/RadioButton.md) - [RatingControl](styles/RatingControl.md) - [Slider](styles/Slider.md) - [TextBlock](styles/TextBlock.md) - [TextBox](styles/TextBox.md) - [ToggleButton](styles/ToggleButton.md) - [ToggleSwitch](styles/ToggleSwitch.md) ## Toolkit Toolkit also has controls that allow lightweight styling, check out [Lightweight Styling in Uno.Toolkit](xref:Toolkit.LightweightStyling). ### Further Reading [Lightweight Styling (Windows Dev Docs)](https://learn.microsoft.com/windows/apps/design/style/xaml-styles#lightweight-styling) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/listviewbase-internals.md --- uid: Uno.Contributing.ListViewBase --- # ListViewBase internals for contributors This document describes the internal operations of Uno's `ListViewBase` implementation(s) in detail, aimed at contributors. Before reading it, you should first read the documentation of [ListViewBase aimed at Uno app developers](../controls/ListViewBase.md), which covers the high-level differences between Uno's implementation and UWP's implementation. ## Introduction `ListViewBase` is the base class of `ListView` and `GridView`. The remainder of the article will refer to 'ListView', the more commonly used of the two derived controls, for ease of reading, but most of the information is applicable to `GridView` as well since a large part of the implementation is shared. `ListView` is a specialized type of [`ItemsControl`](https://learn.microsoft.com/uwp/api/windows.ui.xaml.controls.itemscontrol) designed for showing large numbers of items. `ListView` is by default *virtualized*, meaning that it only materializes view containers for those items which are visible or about to be visible within the scroll viewport. When items disappear from view, their containers are *recycled* and reused for newly appearing views. Correctly-functioning virtualization is the key to good scroll performance. Other important features of `ListView`: - selection, including multiple selection - support for 'observable' collections, allowing items to be inserted and deleted without completely resetting the state of the list, and (on some platforms) with an animation of the item being added or removed - item groups (with optional 'sticky' group headers) - drag and drop to reorder items in the list ## Platform-specific implementations of `ListView` On Android and iOS, `ListView` uses a platform-specific implementation that maps the XAML API to an inner instance of the native list control on each platform, being [RecyclerView](https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView) and [UICollectionView](https://developer.apple.com/documentation/uikit/uicollectionview) respectively. Using the native list control brings the advantage of getting advanced features like item animations 'for free', along with the disadvantage of added maintenance burden, the possibility of platform-specific differences in behavior, and the additional complexity of having non-`FrameworkElement` views in the visual tree. Other platforms (WebAssembly, Skia, and macOS at the time of writing) use a purely managed implementation of `ListView`. This implementation is closer to WinUI in its comportment, for example, it actually uses the items panel (`ItemsStackPanel`) to host items. However, it's not a direct port of the WinUI control. The managed ListView implementation is newer and lacks some features that are supported by the Android and iOS ListViews (and of course WinUI); the feature gap is tracked by [this issue](https://github.com/unoplatform/uno/issues/234). ### Jargon `ListView` can scroll either vertically or horizontally, and the layouting logic is written as much as possible to reuse the same code for both orientations. Accordingly, certain terms are used throughout the code to avoid using orientation-specific terms like 'width' and 'height'. (These usages are probably unique to the Uno codebase.) The main terms are the following: - Extent: Size along the dimension parallel to scrolling. The equivalent of 'Height' if scrolling is vertical, or 'Width' otherwise. - Breadth: Size along the dimension orthogonal to scrolling. The equivalent of 'Width' if scrolling is vertical, or 'Height' otherwise. - Start: The edge of the element nearest to the top of the content panel, ie 'Top' or 'Left' depending whether scrolling is vertical or horizontal. - End: The edge of the element nearest to the bottom of the content panel, ie 'Bottom' or 'Right' depending whether scrolling is vertical or horizontal. - Leading: When scrolling, the edge that is coming into view. ie, if the scrolling forward in a vertical orientation, the bottom edge. - Trailing: When scrolling, the edge that is disappearing from view. ### Android and iOS ListViews in detail Although the Android and iOS implementations are quite different, they share some high-level similarities. Both platforms expose a `NativeListViewBase` class, which inherits from the native list view for the platform. Architecturally, the Android and iOS implementations share a similar high-level 'division of labor', reflecting the underlying platform API. Aside from the view type itself, both implementations implement a class, `VirtualizingPanelLayout`, whose responsibility is to determine what items are visible, what size they should take, and how they should be positioned within the list. Additionally, both Android and iOS implement an 'adapter' or 'source' class with the responsibility of materializing item containers for a given list index and binding them to the appropriate item from the items source. (As an aside, this division of labor has no equivalent in `ListView`, but a somewhat similar approach is taken by WinUI's newer [`ItemsRepeater`](https://learn.microsoft.com/windows/winui/api/microsoft.ui.xaml.controls.itemsrepeater) control, also available in Uno.) [This diagram](../controls/ListViewBase.md#difference-in-the-visual-tree) shows how the `NativeListViewBase` view is incorporated into the visual tree, and the resulting difference from WinUI. The key differences are: - the scrolling container is the `NativeListViewBase` itself, not the `ScrollViewer`. Thus, the `ItemsPresenter` is **outside** the scrollable region. Additionally, there's no ScrollContentPresenter; instead, there's a ListViewBaseScrollContentPresenter. (It was implemented this way back when ScrollContentPresenter inherited directly from the native scroll container.) - the `ItemsStackPanel` (or `ItemsWrapGrid`) is not actually present in the visual tree. These items' panels are created, and their configured values (eg, `Orientation`) are used to set the behavior of the list, but they are not actually loaded into the visual hierarchy or measured and arranged. They just act as a facade for the native layouter. - the Header and Footer, if present, are managed by the native list on Android and iOS, whereas on WinUI, they're outside the ItemsStackPanel/ItemsWrapGrid. Much of the time, these are implementation details that are invisible to the end user. In certain cases, they can have a visible impact. They're useful to be aware of when working on `ListView` bugs. #### Android `NativeListViewBase` implements Android's [`RecyclerView`](https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView). The available customization points of `RecyclerView` are heavily utilized to support all the features exposed by the XAML `ListView` contract. The most important class is `VirtualizingPanelLayout`, which inherits from `RecyclerView.LayoutManager`, and is responsible for determining which views to create for a given scroll position, and where they should go. The 'life cycle' of view creation and positioning of the `ListView` largely takes place during the measure and arrange phases, and when scrolling. A summary follows: ##### Layouting 'life cycle' summary 1. List is measured. 1. Android framework calls `VirtualizingPanelLayout.OnMeasure()`, which calls `VirtualizingPanelLayout.UpdateLayout()`. 1. `UpdateLayout()` => `ScrapLayout()`. `ScrapLayout()` performs a 'lightweight detach operation' on all views and adds them to the `Recycler's` 'scrap'. This allows the size and position of views to be recalculated if need be, but is very cheap (compared to removing and re-adding views in the normal Android way, which kills performance if done frequently). 1. `UpdateLayout()` => `FillLayout()`. `FillLayout()` takes a direction, either Forward or Backward, and fills in unmaterialized items in that direction. The next item to add is always determined *relative to existing materialized items*, and it is added *if there is available viewport space in the designated direction*. To take a concrete example: the viewport is 320 pixels high; individual item containers are 80 pixels high; the list is currently scrolled to an offset of 100 pixels. Item containers for positions 0, 1, 2, 3 are currently materialized; their bounds in y are (-100, -20), (-20, 60), (60, 140), and (140, 220), relative to the viewport. `FillLayout()` would determine that the next unmaterialized item is 4. It would also see that `220 < 320`, and therefore space is available to add the item - this occurs within `TryCreateLine()`. Item 4 will be added at (220, 300). The list would then try to add item 5 at (300, 380), and succeed because `300 < 320`. It will then try to add item 6, and fail, because `380 > 320` (that is, item 6 is still entirely out of the viewport), at which point the loop terminates. 1. `UpdateLayout()` => `UnfillLayout()`. `UnfillLayout()` takes a direction, and trims materialized item containers that are not visible starting from the **opposite** direction. So to take the example above: `UnfillLayout()` would start with item 0, and see that it lies entirely outside the viewport (`-20 < 0`), so it would dematerialize it, returning it to the recycler to be reused. It would then consider item 1, see that it is partially visible (`60 > 0`), and terminate at that point. `UnfillLayout()` is particularly important during scrolling (see below). 2. List is arranged. 1. Android framework => `VirtualizingPanelLayout.OnLayoutChildren()` => `VirtualizingPanelLayout.UpdateLayout()`. 2. `UpdateLayout()` does *not* call `ScrapLayout()` from within the arrange pass. This is because item dimensions should not have changed since the measure. It does however call `FillLayout()` and `UnfillLayout()` again. This is because the dimensions available to the list itself *might* be different from the ones it was measured with. 3. List is scrolled. 1. Android framework => `VirtualizingPanelLayout.ScrollVerticallyBy()` (or `ScrollHorizontallyBy()`). 1. `ScrollVerticallyBy()` => `ScrollBy()`. 1. `ScrollBy()` => `ScrollByInner()`. `ScrollByInner()` essentially moves the viewport 'window' according to the supplied offset, and calls `FillLayout()` and `UnfillLayout()` to add the views visible within that window and remove the ones not visible within it. For large scrolls, `ScrollBy()` will `ScrollByInner()` multiple times with increasingly larger offsets: the purpose of this is to have `FillLayout()` not add multiple views in a single call, because that uses the pool of recycled views inefficiently and will cause new views to be created unnecessarily, which in turn degrades performance. At some point the end of the items will be reached, meaning for large requested scrolls, it may not actually be possible to scroll as far as requested. Consequently, `ScrollBy()` returns the actual offset that was possible to scroll. 1. `ScrollBy()` => `OffsetChildrenVertical()` (or `OffsetChildrenHorizontal()`). The base native method is what actually adjusts the offset of the children relative to the `NativeListViewBase`, which produces the impression that they're being scrolled. Uno-side state which depends on the scroll offset is also updated here. #### iOS On iOS, `NativeListViewBase` inherits from the `UICollectionView` native control. `UICollectionView` is special in that it expects to be given dimensions and positions for the item containers in the list **before** those containers have been materialized. This poses a challenge, because if the individual containers have not been materialized, then they have not been data-bound, and depending on the specific item template, the bound data may change the measured size. (Eg, for data-bound text wrapped to multiple lines, panel elements `Visibility={Binding SomeVMProperty}` ... etc.) The measuring logic for iOS' `ListView` makes an initial guess for the size of each item based on the dimensions of the unbound `ItemTemplate`. Then, once the container for the item is actually materialized and bound, `UICollectionView` offers a chance to update the measured dimensions for the item, via the method `UICollectionViewCell.PreferredLayoutAttributesFittingAttributes()`. This method is implemented by the `ListViewBaseInternalContainer` derived type. This approach to supporting dynamic item container sizes works for the most part, but can be brittle and throws up a number of edge cases. ##### Layouting 'life cycle' summary 1. Upon measure, `VirtualizingPanelLayout.SizeThatFits()` is called, and in turn calls `PrepareLayoutIfNeeded()`. (`SizeThatFits()` is called from Uno's layouting code. `SizeThatFits()` is an overridden virtual method that's defined in UIKit, but it's mostly not used by UIKit itself.) `PrepareLayoutIfNeeded()` determines the `DirtyState` of the list. A `DirtyState` of `None` indicates that the existing internal layout state is still valid. `NeedsRelayout` indicates that the layout should be completely rebuilt, which may be the case if the available size changed, or if `InvalidateLayout()` was called. Other `DirtyState` values indicate more specific reasons for updating the layout state. 2. If `PrepareLayoutIfNeeded()` determines that a layout rebuild is required, it calls `PrepareLayoutInternal()`. `PrepareLayoutInternal()` calculates the sizes and positions of every item in the list, as well as non-item elements like header, footer, and group headers. Note that during measure, these sizes and values are not actually persisted (governed by the `createLayoutInfo` parameter), just used to calculate the total dimensions of the list contents. 3. On arrange, `UICollectionView` calls the `VirtualizingPanelLayout.PrepareLayout()` method, which also calls `PrepareLayoutIfNeeded()`=>`PrepareLayoutInternal()`. This time, `PrepareLayoutInternal()` will persist the calculated sizes and offsets of the items, as `UICollectionViewLayoutAttributes` objects. 4. `UICollectionView` calls `VirtualizingPanelLayout.LayoutAttributesForElementsInRect()` with the current viewport bounds, to determine what elements should be shown. `LayoutAttributesForElementsInRect()` checks the cached layout attributes, and returns all those that intersect with the passed viewport bounds. 5. For each element returned by `LayoutAttributesForElementsInRect()`, `UICollectionView` materializes a container by calling `ListViewBaseSource.GetCell()`. `GetCell()` returns a `ListViewBaseInternalContainer`, which has a `ListViewItem` (or a `ContentControl` in the case of a header, footer, or group header element) in its visual subtree. 6. For each container, `UICollectionView` calls `ListViewBaseInternalContainer.PreferredLayoutAttributesFittingAttributes()`. Here we are able to actually measure the data-bound item, and determine the final size it needs. If the size differs from the un-data-bound size, we: 1. Return updated layout attributes from the method; 2. Update the cached layout attributes for that item, for future use; 3. Update the positions of subsequent items in the cached layout info, since if an item is larger/smaller than initially estimated, the offsets of the remaining items must be modified accordingly. 7. Whenever the list is scrolled, `UICollectionView` will call `LayoutAttributesForElementsInRect()` with the new visible viewport. Steps 5. and 6. will occur for each newly-visible item. ### Android and iOS internal classes | Uno class | Android base class | iOS base class | Description | | --- | --- | --- | --- | | NativeListViewBase | AndroidX.RecyclerView.Widget.RecyclerView | UIKit.UICollectionView | Native list view, parent of item views. | | VirtualizingPanelLayout† | RecyclerView.LayoutManager | UIKit.UICollectionViewLayout | Tells NativeListViewBase how to lay out its items. Bridge for ItemsStackPanel/ItemsWrapGrid. | | NativeListViewBaseAdapter(Android), ListViewBaseSource(iOS) | RecyclerView.Adapter | UIKit.UICollectionViewSource | Handles creation and binding of item views. | ListViewBaseInternalContainer | - | UICollectionViewCell | Implements the native container type - one is created for every `ListViewItem`/`GridViewItem` | | ScrollingViewCache | RecyclerView.ViewCacheExtension | - | Additional virtualization handling on Android which optimizes scroll performance. | † `VirtualizingPanelLayout` is the base class of `ItemsStackPanelLayout` and `ItemsWrapGridLayout`. The derived classes implement the item positioning logic for the corresponding items panel. ### Managed ListView in detail On WASM, Skia, and macOS, `ListViewBase` uses a shared implementation that's dubbed 'managed' because it doesn't rely upon an external native control. The visible implementation details of the managed `ListView` are much closer to WinUI. Specifically: - the items panel is a 'real' panel which hosts the ListViewItems as its children. The size of the panel reflects the estimated total size based on the number of items, as determined by the list. - the `ScrollViewer` in the ListView's control template is a 'real' `ScrollViewer`, ie, it is in fact responsible for scrolling. The internals of the managed `ListView` were originally implemented independently of the WinUI source, but have been gradually converging on the internals of WinUI. Consistent with the other platforms, the managed `ListView` delegates layouting to a class called `VirtualizingPanelLayout`. Item container management is delegated to `VirtualizingPanelGenerator` (similar in responsibility to `NativeListViewBaseAdapter` (Android) and `ListViewBaseSource` (iOS)). #### Layouting 'life cycle' summary 1. On measure, `ItemsStackPanel.MeasureOverride()` directly calls `VirtualizingPanelLayout.MeasureOverride()`. 2. `VirtualizingPanelLayout.MeasureOverride()` 'scraps' the existing layout. The 'scrap' concept is borrowed from Android: existing containers are returned to the item generator, but marked as able to be reused without rebinding during the current pass, if they are still needed (which will often be the case). 3. `VirtualizingPanelLayout.MeasureOverride()` => `UpdateLayout()`. `UpdateLayout()` calls `UnfillLayout()` and `FillLayout()`, which respectively dematerialize containers that are no longer visible within the current viewport and materialize containers for newly visible items. 4. `FillLayout()` calls `CreateLine()` for every missing 'line', which in turn calls `AddView()` for the view(s) in the line. `AddView()` measures the view, adds it to the panel, and stores its planned `Bounds` (size and offset) in `VirtualizationInformation` attached to the view. 5. `MeasureOverride()` returns an estimate of the panel size, based on the current extent of materialized items, the number of unmaterialized items, and the best guess of their size. (This estimate is potentially inaccurate, in the case that the unmaterialized items have a different data-bound size or use a template with a different size; this is a fundamental limitation of the `ListView` that's also present on WinUI.) 6. `ArrangeOverride()` calls `ArrangeElements()` which arranges each child view according to its stored Bounds, adjusted for the actual arranged size of the panel itself and also the parent `ScrollViewer`. 7. The panel listens to the `ViewChanged` event of its parent `ScrollViewer`. `VirtualizingPanelLayout.OnScrollChanged()` calls `UpdateLayout()`, in small increments to ensure that vanished views are recycled at the same rate as appearing views are materialized. `OnScrollChanged()` then calls `ArrangeElements()` to ensure newly-added views are arranged. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/localization.md --- uid: Uno.Tutorials.Localization --- # How to localize text resources This guide will walk you through the necessary steps to localize an Uno Platform application. > [!TIP] > The complete source code that goes along with this guide is available in the [unoplatform/Uno.Samples](https://github.com/unoplatform/Uno.Samples) GitHub repository - [Localization](https://github.com/unoplatform/Uno.Samples/tree/master/UI/LocalizationSamples/Localization) > > [!TIP] > For a step-by-step guide to installing the prerequisites for your preferred IDE and environment, consult the [Get Started guide](../get-started.md). ## Step-by-step instructions 1. Create a new Uno Platform application, following the instructions in [Get Started guide](../get-started.md). 1. Modify the content of `MainPage`: - In `MainPage.xaml`, replace the content of the page: ```xml ``` > Note: > > - The [`x:Name`](https://learn.microsoft.com/windows/uwp/xaml-platform/x-name-attribute) is used to make the element accessible from the code-behind with that same name. > - The [`x:Uid`](https://learn.microsoft.com/windows/uwp/xaml-platform/x-uid-directive) is used for localization. To localize a property, you need to add a string resource in each resource file using its `x:Uid` followed by a dot (`.`) and then the property name. eg: `MainPage_IntroText.Text` More on this in the resource steps that follow. - In `MainPage.xaml.cs`, add an `Page.Loaded` handler to change the text for `CodeBehindText`: ```csharp public MainPage() { this.InitializeComponent(); this.Loaded += (s, e) => CodeBehindText.Text = Windows.ApplicationModel.Resources.ResourceLoader .GetForViewIndependentUse() .GetString("MainPage_CodeBehindString"); } ``` 1. Create a new resource file for localization in French in the `UnoLocalization.Shared` project: 1. Add a new folder `fr` under the `Strings` folder by: Right-click on `Strings` > Add > New Folder 1. Add a new resource file `Resources.resw` under the `fr` folder by: Right-click on `fr` > Add > New Item ... > Visual C# > Xaml > Resources File 1. Add the localization strings for both English and French: Open both `Strings\en\Resources.resw` and `Strings\fr\Resources.resw`, and add these: |Name|Value in `en\Resources.resw`|Value in `fr\Resources.resw`| |-|-|-| |MainPage_IntroText.Text|`Hello Uno`|`Bonjour Uno`| |MainPage_CodeBehindString|`String from code-behind`|`Texte provenant du code-behind`| > [!NOTE] > Make sure to hit Ctrl+S for both files, to save the changes. > > [!IMPORTANT] > The `ResourceLoader` will search for resources in the current language, then the default language. The default language is defined by the MSBuild property `DefaultLanguage`, which defaults to `en`. 1. You can now try to run the app. The "Hello World" text should be replaced with "Hello Uno", or "Bonjour Uno" if the targeted environment is on French culture. Now, if you change the language of the targeted PC or the mobile device AND restart the app, that text should also change accordingly. You can also set the starting culture to see the result, without having to modify the system language: - `App.cs` or `App.xaml.cs`: ```csharp public App() { InitializeLogging(); ChangeStartingLanguage(); this.InitializeComponent(); this.Suspending += OnSuspending; } private void ChangeStartingLanguage() { var culture = new System.Globalization.CultureInfo("fr"); Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = culture.TwoLetterISOLanguageName; } ``` 1. For WinUI 3 projects - As an unpackaged WinUI 3 app doesn't contain a package.appxmanifest file, no further action is needed after adding the appropriate resources to the project. - If you are working with a packaged WinUI 3 app, open the .wapproj's `package.appxmanifest` in a text editor and locate the following section: ```xml ``` Replace it with elements for each of your supported languages. For example: ```xml ``` ## Get the complete code See the completed sample on GitHub: [LocalizationSamples/Localization](https://github.com/unoplatform/Uno.Samples/tree/master/UI/LocalizationSamples/Localization) ## Additional Resources [Globalization and localization](https://learn.microsoft.com/windows/uwp/design/globalizing/globalizing-portal) ## Help! I'm having trouble [!include[getting-help](../includes/getting-help.md)] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/logging.md --- uid: Uno.Development.Logging --- # Logging Virtually every production level application should utilize some form of logging. During development, especially when developing WASM applications where using a debugger can be more challenging, diagnostic logs can be invaluable for identifying issues. Once in production, capturing information about critical failures can be invaluable. > [!IMPORTANT] > If you created your app using the **Recommended** preset, please refer to our [**Uno.Extensions.Logging** documentation](xref:Uno.Extensions.Logging.Overview) instead. > > For more information about the difference between the **Blank** and **Recommended** presets, please see the [Preset selection](xref:Uno.GettingStarted.UsingWizard#preset-selection) section of our Solution Template documentation. ## Logging in Uno Platform The Uno platform makes use of the Microsoft logging NuGet packages to provide comprehensive logging support. ### Configuring logging The standard Uno template configures logging in the **App.xaml.cs** file. 1. Add the [`Uno.UI.Adapter.Microsoft.Extensions.Logging`](https://www.nuget.org/packages/Uno.UI.Adapter.Microsoft.Extensions.Logging/) NuGet package to your platform projects. 1. In the iOS project, add the [`Uno.Extensions.Logging.OSLog`](https://www.nuget.org/packages/Uno.Extensions.Logging.OSLog/) NuGet package to your platform projects. 1. In the WebAssembly project, add the [`Uno.Extensions.Logging.WebAssembly.Console`](https://www.nuget.org/packages/Uno.Extensions.Logging.WebAssembly.Console/) NuGet package to your platform projects. 1. Open the **App.xaml.cs** file. 1. Locate the **App** constructor and note that logging is configured first: ```csharp public App() { InitializeLogging(); ``` Notice that Uno provides a logger factory implementation. 1. Locate the **InitializeLogging** method and review the code: > [!IMPORTANT] > The `InitializeLogging()` method is wrapped in a `#if DEBUG` preprocessor directive. This means **logging is only enabled in DEBUG builds by default**. If you need logging in Release builds, you'll need to remove or modify the `#if DEBUG` condition, keeping in mind the performance implications mentioned in the code comments. ```csharp private static void InitializeLogging() { #if DEBUG // Logging is disabled by default for release builds, as it incurs a significant // initialization cost from Microsoft.Extensions.Logging setup. If startup performance // is a concern for your application, keep this disabled. If you're running on web or // desktop targets, you can use url or command line parameters to enable it yourself. // // For more performance documentation: https://platform.uno/docs/articles/Uno-UI-Performance.html var factory = LoggerFactory.Create(builder => { #if __WASM__ builder.AddProvider(new global::Uno.Extensions.Logging.WebAssembly.WebAssemblyConsoleLoggerProvider()); #elif __IOS__ || __TVOS__ builder.AddProvider(new global::Uno.Extensions.Logging.OSLogLoggerProvider()); builder.AddConsole(); #elif NETFX_CORE builder.AddDebug(); #else builder.AddConsole(); #endif // Exclude logs below this level builder.SetMinimumLevel(LogLevel.Information); // Default filters for Uno Platform namespaces builder.AddFilter("Uno", LogLevel.Warning); builder.AddFilter("Windows", LogLevel.Warning); builder.AddFilter("Microsoft", LogLevel.Warning); // Generic Xaml events // builder.AddFilter("Windows.UI.Xaml", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.VisualStateGroup", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.StateTriggerBase", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.UIElement", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.FrameworkElement", LogLevel.Trace ); // Layouter specific messages // builder.AddFilter("Windows.UI.Xaml.Controls", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.Controls.Layouter", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.Controls.Panel", LogLevel.Debug ); // builder.AddFilter("Windows.Storage", LogLevel.Debug ); // Binding related messages // builder.AddFilter("Windows.UI.Xaml.Data", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.Data", LogLevel.Debug ); // Binder memory references tracking // builder.AddFilter("Uno.UI.DataBinding.BinderReferenceHolder", LogLevel.Debug ); // RemoteControl and HotReload related // builder.AddFilter("Uno.UI.RemoteControl", LogLevel.Information); // Debug JS interop // builder.AddFilter("Uno.Foundation.WebAssemblyRuntime", LogLevel.Debug ); }); global::Uno.Extensions.LogExtensionPoint.AmbientLoggerFactory = factory; #if HAS_UNO global::Uno.UI.Adapter.Microsoft.Extensions.Logging.LoggingAdapter.Initialize(); #endif #endif // DEBUG } ``` Notice that the logging levels of various categories can be added and configured. > [!NOTE] > Notice that console logging is configured by default with `.AddConsole();` for most platforms. However, this **does not** log output to the Visual Studio console when running a WinUI app. For WinUI apps (the `NETFX_CORE` platform in the code above), logging is configured with `builder.AddDebug();` instead, which outputs to the Visual Studio Debug window. ### Uno logging extensions The Uno platform also provides an extension that simplifies the use of logging by making it simple to retrieve a reference to the logger. 1. In order to add logging to a class, add the following using statements namespaces: ```csharp using Microsoft.Extensions.Logging; using Uno.Extensions; ``` 1. In order to write output to a log, the **Log** extension method is available on an object instance, which then exposes the operations available from **Microsoft.Extensions.Logging.LoggerExtensions**. Here is an example on how to write error and information level messages: ```csharp if (discoveryClient.IsError) { this.Log().LogError(discoveryClient.Error); throw new Exception(discoveryClient.Error); } this.Log().LogInformation($"UserInfoEndpoint: {discoveryClient.UserInfoEndpoint}"); ``` > [!TIP] > To learn more about the logging capabilities, review the Microsoft logging reference materials here: > > * [Logging in .NET](https://learn.microsoft.com/dotnet/core/extensions/logging) ## Log output for not implemented member usage By default, when a member is invoked at runtime that's not implemented by Uno (ie, marked with the `[NotImplemented]` attribute), an error message is logged. > [!IMPORTANT] > This feature flag must be set before the `base.InitializeComponent()` call within the `App.xaml.cs` constructor. The logging behavior can be configured using feature flags: * By default, a message is only logged on the first usage of a given member. To log every time the member is invoked: ```csharp Uno.UI.FeatureConfiguration.ApiInformation.AlwaysLogNotImplementedMessages = true; ``` * By default the message is logged as an error. To change the logging level: ```csharp Uno.UI.FeatureConfiguration.ApiInformation.NotImplementedLogLevel = LogLevel.Debug; // Raise not implemented usages as Debug messages ``` This can be used to suppress the not implemented output, if it's not useful. ## iOS Specifics ### Logging with OSLogLoggerProvider The OSLogProvider will log to the device's syslog, and is visible on macOS using the **Monitor** app when selecting the device. Note that by default, debug and info messages are not visible and must be enabled on the **Monitor** app in the **Action** Menu, with the **Include Info/Debug Messages**. ### OptionsMonitor issues ```Unhandled Exception: System.InvalidOperationException: A suitable constructor for type 'Microsoft.Extensions.Options.OptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor. ``` If you are getting the above exception when running on iOS and the Linker Behavior is set to "Link All" it is likely that the IL linker is removing some logging classes. See [Linking Xamarin.iOS Apps](https://learn.microsoft.com/xamarin/ios/deploy-test/linker?tabs=macos) One option is to use `linkskip` file to exclude the assemblies causing issues. Add the following to your `mtouch` arguments: ```console --linkskip=Uno.Extensions.Logging.OSLog --linkskip=Microsoft.Extensions.Options ``` The other option is to add a [custom linker definition file](https://learn.microsoft.com/xamarin/cross-platform/deploy-test/linker) ```xml ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/magnetometer.md --- uid: Uno.Features.Magnetometer --- # Magnetometer > [!TIP] > This article covers Uno-specific information for Magnetometer. For a full description of the feature and instructions on using it, see [Magnetometer Class](https://learn.microsoft.com/uwp/api/windows.devices.sensors.magnetometer). * The `Windows.Devices.Sensors.Magnetometer` class allows measuring magnetic force affecting the device. ## Supported features | Feature | Windows | Android | iOS | Web (WASM) | macOS | Linux (Skia) | Win 7 (Skia) | |---------------|-------|-------|-------|-------|-------|-------|-| | `GetDefault` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | `ReadingChanged` | ✔ | ✔ | ✔ | ✔ | ✖ | ✖| ✖ | | `ReportInterval` | ✔ | ✔ | ✔ | ✔ | ✖ | ✖ | ✖ | ## Using Magnetometer with Uno * The `GetDefault` method is available on all targets and will return `null` on those which do not support `Magnetometer` or devices which do not have such sensor. * Ensure to unsubscribe from the `ReadingChanged` event when you no longer need the readings, so that the sensor is no longer active to avoid unnecessary battery consumption. * `ReportInterval` property on WASM is currently not supported directly. Uno uses an approximation in the form of raising the `ReadingChanged` event, only when enough time has passed since the last report. The event is raised a bit more often to make sure the gap caused by the filter is not too large, but this is in-line with the behavior of Windows' `Magnetometer`. * `DirectionalAccuracy` is not reported on iOS, so it will always return `Unknown`. ## Example ### Capturing sensor readings ```csharp var magnetometer = Magnetometer.GetDefault(); magnetometer.ReadingChanged += Magnetometer_ReadingChanged; private async void Magnetometer_ReadingChanged(Magnetometer sender, MagnetometerReadingChangedEventArgs args) { // If you want to update the UI in some way, ensure the Dispatcher is used, // as the ReadingChanged event handler does not run on the UI thread. await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { MagneticFieldX = args.Reading.MagneticFieldX; MagneticFieldY = args.Reading.MagneticFieldY; MagneticFieldZ = args.Reading.MagneticFieldZ; DirectionalAccuracy = args.Reading.DirectionalAccuracy; Timestamp = args.Reading.Timestamp.ToString("R"); }); } ``` ### Unsubscribing from the readings ```csharp magnetometer.ReadingChanged -= Magnetometer_ReadingChanged; ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/controls/map-control-support.md --- uid: Uno.Controls.MapControl --- # MapControl The `MapControl` is a control that allows you to display maps in your app. Currently, Uno supports `MapControl` on iOS and Android. ## Architecture Although `MapControl` is defined in `Uno.UI`, to function, it requires an additional package to be installed, `Uno.UI.Maps`, which supplies the actual implementation. This is done to avoid imposing an unnecessary dependency on applications that don't use maps, and also to allow alternative map providers (eg, Google Maps on iOS) to be easily supported in the future. The current implementation uses the native UIKit Map for iOS and the Google Play Services Map control for Android. ## How to use MapControl in an Uno Platform app 1. Install the [Uno.WinUI.Maps NuGet package](https://www.nuget.org/packages/Uno.WinUI.Maps/) in the Android and/or iOS head projects of your app. 1. Add the `MapResources` resource dictionary to `Application.Resources` in your `App.xaml` file: ```xml ``` 1. (Windows and Android) Obtain an API key for your app, following the instructions below. 1. (Android) Configure permissions in the manifest, following the instructions below. 1. Add `MapControl` to your app (``). ## Sample XAML Here's a complete sample: ```xml ``` The above code will display Page with a Map Control and a slider that will be used to change the ZoomLevel. ## Platform support | Feature | Android | iOS | Wasm | | ------------------------------------------|:-------:|:---:|:----:| | Display a map | X | X | | | Display a path | | X | | | Customize pushpins with icon | | | | | Fully template pushpins | | | | | Show user's location on map | | | | | Toggle native Locate-Me button visibility | | | | | Toggle native Compass button visibility | | | | ## Usage ## Get API key for the map component To use the map component, you will need an API key for Windows and Android. Here are the steps to retrieve it. ### Windows For the detailed procedure for Windows, see [Request a maps authentication key ](https://learn.microsoft.com/windows/uwp/maps-and-location/authentication-key) documentation. + Go to + Login to your account or register if you don't have one + Go to MyAccount -> Keys + Click on create a new key + Enter the following information: + Application name + Application URL (optional) + Key type + Application type + Hit *Create* and get the key The key will be set as the value for the parameter *MapServiceToken* for the MapControl object. ### Android + Create a project in the Google Developers Console. + Enable Map Service. In case this is your first time using the Google Maps API you will need to enable it before using it. 1. Go to 2. Login with a Google account 3. Click on "Enable APIs and Services" 4. Select "Maps SDK for Android" and click on Enable + Generate an API key. 1. If you are coming from step-2 just navigate back until you are again in the dashboard, otherwise, go to and login with a Google account. 2. Go to the Credentials section on the left-hand side menu 3. Click on "Create Credentials", then "API key" 4. Copy the key generated as this will be the one we will use later in the application **Note:** For apps in production we suggest restricting the keys to be used only by your Android app. This is possible by using the SHA-1 fingerprint of your app. *For a detailed procedure on how to retrieve the SHA-1 fingerprint for your Android application, please follow this link: * ## Configure your application + For **Android** 1. Add the following to AndroidManifest.xml: ```xml ``` 2. Add the API key to `AssemblyInfo.cs`. ```csharp [assembly: MetaData("com.google.android.maps.v2.API_KEY", Value = "YOUR_API_KEY")] ``` Replace the text YOUR_API_KEY with the key generated in previous step. Note: Since this key might vary depending on the platform and environment we suggest using a constant class where the key could be retrieved from. 3. Add the relevant permissions to `AssemblyInfo.cs`. For example, if you wish to access the user location ```csharp [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)] [assembly: UsesPermission("com.myapp.permission.MAPS_RECEIVE")] [assembly: Permission(Name = "com.myapp.permission.MAPS_RECEIVE", ProtectionLevel = Android.Content.PM.Protection.Signature)] ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno.themes/refs/heads/master/doc/material-colors.md --- uid: Uno.Themes.Material.Colors --- # Material Colors and Brushes ## Colors | Key | LightValue | DarkValue | |------------------------------|------------|-----------| | `PrimaryColor` | `#5946D2` | `#C7BFFF` | | `PrimaryInverseColor` | `#C8BFFF` | `#2A009F` | | `OnPrimaryColor` | `#FFFFFF` | `#2A009F` | | `PrimaryContainerColor` | `#E5DEFF` | `#4129BA` | | `OnPrimaryContainerColor` | `#170065` | `#E4DFFF` | | `PrimaryVariantDarkColor` | `#0021C1` | `#4128BA` | | `PrimaryVariantLightColor` | `#9679FF` | `#C8BFFF` | | `SecondaryColor` | `#6B4EA2` | `#CDC2DC` | | `OnSecondaryColor` | `#FFFFFF` | `#332D41` | | `SecondaryContainerColor` | `#EBDDFF` | `#433C52` | | `OnSecondaryContainerColor` | `#220555` | `#EDDFFF` | | `SecondaryVariantDarkColor` | `#3B2574` | `#441F8A` | | `SecondaryVariantLightColor` | `#9B7BD5` | `#EBE6F1` | | `TertiaryColor` | `#0061A4` | `#9FCAFF` | | `OnTertiaryColor` | `#FFFFFF` | `#003258` | | `TertiaryContainerColor` | `#CFE4FF` | `#00497D` | | `OnTertiaryContainerColor` | `#001D36` | `#D1E4FF` | | `ErrorColor` | `#B3261E` | `#FFB4AB` | | `OnErrorColor` | `#FFFFFF` | `#690005` | | `ErrorContainerColor` | `#F9DEDC` | `#93000A` | | `OnErrorContainerColor` | `#410E0B` | `#FFDAD6` | | `BackgroundColor` | `#FCFBFF` | `#1C1B1F` | | `OnBackgroundColor` | `#1C1B1F` | `#E5E1E6` | | `SurfaceColor` | `#FFFFFF` | `#302D37` | | `OnSurfaceColor` | `#1C1B1F` | `#E6E1E5` | | `SurfaceVariantColor` | `#F2EFF5` | `#47464F` | | `OnSurfaceVariantColor` | `#8A8494` | `#C9C5D0` | | `SurfaceInverseColor` | `#313033` | `#E6E1E5` | | `OnSurfaceInverseColor` | `#F4EFF4` | `#1C1B1F` | | `SurfaceTintColor` | `#5946D2` | `#C7BFFF` | | `OutlineColor` | `#79747E` | `#928F99` | | `OutlineVariantColor` | `#C9C5D0` | `#57545D` | | `ShadowColor` | `#000000` | `#000000` | ## Opacities | Key | Value | |-----------------|-------| | HoverOpacity | 0.08 | | FocusedOpacity | 0.12 | | PressedOpacity | 0.12 | | DraggedOpacity | 0.16 | | SelectedOpacity | 0.08 | | MediumOpacity | 0.64 | | LowOpacity | 0.32 | | DisabledOpacity | 0.12 | ## Brushes | Key | Color | Opacity | |------------------------------------|------------------------------|-------------------| | PrimaryBrush | `PrimaryColor` | 1 | | PrimaryHoverBrush | `PrimaryColor` | `HoverOpacity` | | PrimaryFocusedBrush | `PrimaryColor` | `FocusedOpacity` | | PrimaryPressedBrush | `PrimaryColor` | `PressedOpacity` | | PrimaryDraggedBrush | `PrimaryColor` | `DraggedOpacity` | | PrimarySelectedBrush | `PrimaryColor` | `SelectedOpacity` | | PrimaryMediumBrush | `PrimaryColor` | `MediumOpacity` | | PrimaryLowBrush | `PrimaryColor` | `LowOpacity` | | PrimaryDisabledBrush | `PrimaryColor` | `DisabledOpacity` | | PrimaryInverseBrush | `PrimaryInverseColor` | 1 | | PrimaryInverseHoverBrush | `PrimaryInverseColor` | `HoverOpacity` | | PrimaryInverseFocusedBrush | `PrimaryInverseColor` | `FocusedOpacity` | | PrimaryInversePressedBrush | `PrimaryInverseColor` | `PressedOpacity` | | PrimaryInverseDraggedBrush | `PrimaryInverseColor` | `DraggedOpacity` | | PrimaryInverseSelectedBrush | `PrimaryInverseColor` | `SelectedOpacity` | | PrimaryInverseMediumBrush | `PrimaryInverseColor` | `MediumOpacity` | | PrimaryInverseLowBrush | `PrimaryInverseColor` | `LowOpacity` | | PrimaryInverseDisabledBrush | `PrimaryInverseColor` | `DisabledOpacity` | | OnPrimaryBrush | `OnPrimaryColor` | 1 | | OnPrimaryHoverBrush | `OnPrimaryColor` | `HoverOpacity` | | OnPrimaryFocusedBrush | `OnPrimaryColor` | `FocusedOpacity` | | OnPrimaryPressedBrush | `OnPrimaryColor` | `PressedOpacity` | | OnPrimaryDraggedBrush | `OnPrimaryColor` | `DraggedOpacity` | | OnPrimarySelectedBrush | `OnPrimaryColor` | `SelectedOpacity` | | OnPrimaryMediumBrush | `OnPrimaryColor` | `MediumOpacity` | | OnPrimaryLowBrush | `OnPrimaryColor` | `LowOpacity` | | OnPrimaryDisabledBrush | `OnPrimaryColor` | `DisabledOpacity` | | PrimaryContainerBrush | `PrimaryContainerColor` | 1 | | PrimaryContainerHoverBrush | `PrimaryContainerColor` | `HoverOpacity` | | PrimaryContainerFocusedBrush | `PrimaryContainerColor` | `FocusedOpacity` | | PrimaryContainerPressedBrush | `PrimaryContainerColor` | `PressedOpacity` | | PrimaryContainerDraggedBrush | `PrimaryContainerColor` | `DraggedOpacity` | | PrimaryContainerSelectedBrush | `PrimaryContainerColor` | `SelectedOpacity` | | PrimaryContainerMediumBrush | `PrimaryContainerColor` | `MediumOpacity` | | PrimaryContainerLowBrush | `PrimaryContainerColor` | `LowOpacity` | | PrimaryContainerDisabledBrush | `PrimaryContainerColor` | `DisabledOpacity` | | OnPrimaryContainerBrush | `OnPrimaryContainerColor` | 1 | | OnPrimaryContainerHoverBrush | `OnPrimaryContainerColor` | `HoverOpacity` | | OnPrimaryContainerFocusedBrush | `OnPrimaryContainerColor` | `FocusedOpacity` | | OnPrimaryContainerPressedBrush | `OnPrimaryContainerColor` | `PressedOpacity` | | OnPrimaryContainerDraggedBrush | `OnPrimaryContainerColor` | `DraggedOpacity` | | OnPrimaryContainerSelectedBrush | `OnPrimaryContainerColor` | `SelectedOpacity` | | OnPrimaryContainerMediumBrush | `OnPrimaryContainerColor` | `MediumOpacity` | | OnPrimaryContainerLowBrush | `OnPrimaryContainerColor` | `LowOpacity` | | OnPrimaryContainerDisabledBrush | `OnPrimaryContainerColor` | `DisabledOpacity` | | PrimaryVariantLightBrush | `PrimaryVariantLightColor` | 1 | | PrimaryVariantLightHoverBrush | `PrimaryVariantLightColor` | `HoverOpacity` | | PrimaryVariantLightFocusedBrush | `PrimaryVariantLightColor` | `FocusedOpacity` | | PrimaryVariantLightPressedBrush | `PrimaryVariantLightColor` | `PressedOpacity` | | PrimaryVariantLightDraggedBrush | `PrimaryVariantLightColor` | `DraggedOpacity` | | PrimaryVariantLightSelectedBrush | `PrimaryVariantLightColor` | `SelectedOpacity` | | PrimaryVariantLightMediumBrush | `PrimaryVariantLightColor` | `MediumOpacity` | | PrimaryVariantLightLowBrush | `PrimaryVariantLightColor` | `LowOpacity` | | PrimaryVariantLightDisabledBrush | `PrimaryVariantLightColor` | `DisabledOpacity` | | PrimaryVariantDarkBrush | `PrimaryVariantDarkColor` | 1 | | PrimaryVariantDarkHoverBrush | `PrimaryVariantDarkColor` | `HoverOpacity` | | PrimaryVariantDarkFocusedBrush | `PrimaryVariantDarkColor` | `FocusedOpacity` | | PrimaryVariantDarkPressedBrush | `PrimaryVariantDarkColor` | `PressedOpacity` | | PrimaryVariantDarkDraggedBrush | `PrimaryVariantDarkColor` | `DraggedOpacity` | | PrimaryVariantDarkSelectedBrush | `PrimaryVariantDarkColor` | `SelectedOpacity` | | PrimaryVariantDarkMediumBrush | `PrimaryVariantDarkColor` | `MediumOpacity` | | PrimaryVariantDarkLowBrush | `PrimaryVariantDarkColor` | `LowOpacity` | | PrimaryVariantDarkDisabledBrush | `PrimaryVariantDarkColor` | `DisabledOpacity` | | SecondaryBrush | `SecondaryColor` | 1 | | SecondaryHoverBrush | `SecondaryColor` | `HoverOpacity` | | SecondaryFocusedBrush | `SecondaryColor` | `FocusedOpacity` | | SecondaryPressedBrush | `SecondaryColor` | `PressedOpacity` | | SecondaryDraggedBrush | `SecondaryColor` | `DraggedOpacity` | | SecondarySelectedBrush | `SecondaryColor` | `SelectedOpacity` | | SecondaryMediumBrush | `SecondaryColor` | `MediumOpacity` | | SecondaryLowBrush | `SecondaryColor` | `LowOpacity` | | SecondaryDisabledBrush | `SecondaryColor` | `DisabledOpacity` | | OnSecondaryBrush | `OnSecondaryColor` | 1 | | OnSecondaryHoverBrush | `OnSecondaryColor` | `HoverOpacity` | | OnSecondaryFocusedBrush | `OnSecondaryColor` | `FocusedOpacity` | | OnSecondaryPressedBrush | `OnSecondaryColor` | `PressedOpacity` | | OnSecondaryDraggedBrush | `OnSecondaryColor` | `DraggedOpacity` | | OnSecondarySelectedBrush | `OnSecondaryColor` | `SelectedOpacity` | | OnSecondaryMediumBrush | `OnSecondaryColor` | `MediumOpacity` | | OnSecondaryLowBrush | `OnSecondaryColor` | `LowOpacity` | | OnSecondaryDisabledBrush | `OnSecondaryColor` | `DisabledOpacity` | | SecondaryContainerBrush | `SecondaryContainerColor` | 1 | | SecondaryContainerHoverBrush | `SecondaryContainerColor` | `HoverOpacity` | | SecondaryContainerFocusedBrush | `SecondaryContainerColor` | `FocusedOpacity` | | SecondaryContainerPressedBrush | `SecondaryContainerColor` | `PressedOpacity` | | SecondaryContainerDraggedBrush | `SecondaryContainerColor` | `DraggedOpacity` | | SecondaryContainerSelectedBrush | `SecondaryContainerColor` | `SelectedOpacity` | | SecondaryContainerMediumBrush | `SecondaryContainerColor` | `MediumOpacity` | | SecondaryContainerLowBrush | `SecondaryContainerColor` | `LowOpacity` | | SecondaryContainerDisabledBrush | `SecondaryContainerColor` | `DisabledOpacity` | | OnSecondaryContainerBrush | `OnSecondaryContainerColor` | 1 | | OnSecondaryContainerHoverBrush | `OnSecondaryContainerColor` | `HoverOpacity` | | OnSecondaryContainerFocusedBrush | `OnSecondaryContainerColor` | `FocusedOpacity` | | OnSecondaryContainerPressedBrush | `OnSecondaryContainerColor` | `PressedOpacity` | | OnSecondaryContainerDraggedBrush | `OnSecondaryContainerColor` | `DraggedOpacity` | | OnSecondaryContainerSelectedBrush | `OnSecondaryContainerColor` | `SelectedOpacity` | | OnSecondaryContainerMediumBrush | `OnSecondaryContainerColor` | `MediumOpacity` | | OnSecondaryContainerLowBrush | `OnSecondaryContainerColor` | `LowOpacity` | | OnSecondaryContainerDisabledBrush | `OnSecondaryContainerColor` | `DisabledOpacity` | | SecondaryVariantLightBrush | `SecondaryVariantLightColor` | 1 | | SecondaryVariantLightHoverBrush | `SecondaryVariantLightColor` | `HoverOpacity` | | SecondaryVariantLightFocusedBrush | `SecondaryVariantLightColor` | `FocusedOpacity` | | SecondaryVariantLightPressedBrush | `SecondaryVariantLightColor` | `PressedOpacity` | | SecondaryVariantLightDraggedBrush | `SecondaryVariantLightColor` | `DraggedOpacity` | | SecondaryVariantLightSelectedBrush | `SecondaryVariantLightColor` | `SelectedOpacity` | | SecondaryVariantLightMediumBrush | `SecondaryVariantLightColor` | `MediumOpacity` | | SecondaryVariantLightLowBrush | `SecondaryVariantLightColor` | `LowOpacity` | | SecondaryVariantLightDisabledBrush | `SecondaryVariantLightColor` | `DisabledOpacity` | | SecondaryVariantDarkBrush | `SecondaryVariantDarkColor` | 1 | | SecondaryVariantDarkHoverBrush | `SecondaryVariantDarkColor` | `HoverOpacity` | | SecondaryVariantDarkFocusedBrush | `SecondaryVariantDarkColor` | `FocusedOpacity` | | SecondaryVariantDarkPressedBrush | `SecondaryVariantDarkColor` | `PressedOpacity` | | SecondaryVariantDarkDraggedBrush | `SecondaryVariantDarkColor` | `DraggedOpacity` | | SecondaryVariantDarkSelectedBrush | `SecondaryVariantDarkColor` | `SelectedOpacity` | | SecondaryVariantDarkMediumBrush | `SecondaryVariantDarkColor` | `MediumOpacity` | | SecondaryVariantDarkLowBrush | `SecondaryVariantDarkColor` | `LowOpacity` | | SecondaryVariantDarkDisabledBrush | `SecondaryVariantDarkColor` | `DisabledOpacity` | | TertiaryBrush | `TertiaryColor` | 1 | | TertiaryHoverBrush | `TertiaryColor` | `HoverOpacity` | | TertiaryFocusedBrush | `TertiaryColor` | `FocusedOpacity` | | TertiaryPressedBrush | `TertiaryColor` | `PressedOpacity` | | TertiaryDraggedBrush | `TertiaryColor` | `DraggedOpacity` | | TertiarySelectedBrush | `TertiaryColor` | `SelectedOpacity` | | TertiaryMediumBrush | `TertiaryColor` | `MediumOpacity` | | TertiaryLowBrush | `TertiaryColor` | `LowOpacity` | | TertiaryDisabledBrush | `TertiaryColor` | `DisabledOpacity` | | OnTertiaryBrush | `OnTertiaryColor` | 1 | | OnTertiaryHoverBrush | `OnTertiaryColor` | `HoverOpacity` | | OnTertiaryFocusedBrush | `OnTertiaryColor` | `FocusedOpacity` | | OnTertiaryPressedBrush | `OnTertiaryColor` | `PressedOpacity` | | OnTertiaryDraggedBrush | `OnTertiaryColor` | `DraggedOpacity` | | OnTertiarySelectedBrush | `OnTertiaryColor` | `SelectedOpacity` | | OnTertiaryMediumBrush | `OnTertiaryColor` | `MediumOpacity` | | OnTertiaryLowBrush | `OnTertiaryColor` | `LowOpacity` | | OnTertiaryDisabledBrush | `OnTertiaryColor` | `DisabledOpacity` | | TertiaryContainerBrush | `TertiaryContainerColor` | 1 | | TertiaryContainerHoverBrush | `TertiaryContainerColor` | `HoverOpacity` | | TertiaryContainerFocusedBrush | `TertiaryContainerColor` | `FocusedOpacity` | | TertiaryContainerPressedBrush | `TertiaryContainerColor` | `PressedOpacity` | | TertiaryContainerDraggedBrush | `TertiaryContainerColor` | `DraggedOpacity` | | TertiaryContainerSelectedBrush | `TertiaryContainerColor` | `SelectedOpacity` | | TertiaryContainerMediumBrush | `TertiaryContainerColor` | `MediumOpacity` | | TertiaryContainerLowBrush | `TertiaryContainerColor` | `LowOpacity` | | TertiaryContainerDisabledBrush | `TertiaryContainerColor` | `DisabledOpacity` | | OnTertiaryContainerBrush | `OnTertiaryContainerColor` | 1 | | OnTertiaryContainerHoverBrush | `OnTertiaryContainerColor` | `HoverOpacity` | | OnTertiaryContainerFocusedBrush | `OnTertiaryContainerColor` | `FocusedOpacity` | | OnTertiaryContainerPressedBrush | `OnTertiaryContainerColor` | `PressedOpacity` | | OnTertiaryContainerDraggedBrush | `OnTertiaryContainerColor` | `DraggedOpacity` | | OnTertiaryContainerSelectedBrush | `OnTertiaryContainerColor` | `SelectedOpacity` | | OnTertiaryContainerMediumBrush | `OnTertiaryContainerColor` | `MediumOpacity` | | OnTertiaryContainerLowBrush | `OnTertiaryContainerColor` | `LowOpacity` | | OnTertiaryContainerDisabledBrush | `OnTertiaryContainerColor` | `DisabledOpacity` | | ErrorBrush | `ErrorColor` | 1 | | ErrorHoverBrush | `ErrorColor` | `HoverOpacity` | | ErrorFocusedBrush | `ErrorColor` | `FocusedOpacity` | | ErrorPressedBrush | `ErrorColor` | `PressedOpacity` | | ErrorDraggedBrush | `ErrorColor` | `DraggedOpacity` | | ErrorSelectedBrush | `ErrorColor` | `SelectedOpacity` | | ErrorMediumBrush | `ErrorColor` | `MediumOpacity` | | ErrorLowBrush | `ErrorColor` | `LowOpacity` | | ErrorDisabledBrush | `ErrorColor` | `DisabledOpacity` | | OnErrorBrush | `OnErrorColor` | 1 | | OnErrorHoverBrush | `OnErrorColor` | `HoverOpacity` | | OnErrorFocusedBrush | `OnErrorColor` | `FocusedOpacity` | | OnErrorPressedBrush | `OnErrorColor` | `PressedOpacity` | | OnErrorDraggedBrush | `OnErrorColor` | `DraggedOpacity` | | OnErrorSelectedBrush | `OnErrorColor` | `SelectedOpacity` | | OnErrorMediumBrush | `OnErrorColor` | `MediumOpacity` | | OnErrorLowBrush | `OnErrorColor` | `LowOpacity` | | OnErrorDisabledBrush | `OnErrorColor` | `DisabledOpacity` | | ErrorContainerBrush | `ErrorContainerColor` | 1 | | ErrorContainerHoverBrush | `ErrorContainerColor` | `HoverOpacity` | | ErrorContainerFocusedBrush | `ErrorContainerColor` | `FocusedOpacity` | | ErrorContainerPressedBrush | `ErrorContainerColor` | `PressedOpacity` | | ErrorContainerDraggedBrush | `ErrorContainerColor` | `DraggedOpacity` | | ErrorContainerSelectedBrush | `ErrorContainerColor` | `SelectedOpacity` | | ErrorContainerMediumBrush | `ErrorContainerColor` | `MediumOpacity` | | ErrorContainerLowBrush | `ErrorContainerColor` | `LowOpacity` | | ErrorContainerDisabledBrush | `ErrorContainerColor` | `DisabledOpacity` | | OnErrorContainerBrush | `OnErrorContainerColor` | 1 | | OnErrorContainerHoverBrush | `OnErrorContainerColor` | `HoverOpacity` | | OnErrorContainerFocusedBrush | `OnErrorContainerColor` | `FocusedOpacity` | | OnErrorContainerPressedBrush | `OnErrorContainerColor` | `PressedOpacity` | | OnErrorContainerDraggedBrush | `OnErrorContainerColor` | `DraggedOpacity` | | OnErrorContainerSelectedBrush | `OnErrorContainerColor` | `SelectedOpacity` | | OnErrorContainerMediumBrush | `OnErrorContainerColor` | `MediumOpacity` | | OnErrorContainerLowBrush | `OnErrorContainerColor` | `LowOpacity` | | OnErrorContainerDisabledBrush | `OnErrorContainerColor` | `DisabledOpacity` | | BackgroundBrush | `BackgroundColor` | 1 | | BackgroundHoverBrush | `BackgroundColor` | `HoverOpacity` | | BackgroundFocusedBrush | `BackgroundColor` | `FocusedOpacity` | | BackgroundPressedBrush | `BackgroundColor` | `PressedOpacity` | | BackgroundDraggedBrush | `BackgroundColor` | `DraggedOpacity` | | BackgroundSelectedBrush | `BackgroundColor` | `SelectedOpacity` | | BackgroundMediumBrush | `BackgroundColor` | `MediumOpacity` | | BackgroundLowBrush | `BackgroundColor` | `LowOpacity` | | BackgroundDisabledBrush | `BackgroundColor` | `DisabledOpacity` | | OnBackgroundBrush | `OnBackgroundColor` | 1 | | OnBackgroundHoverBrush | `OnBackgroundColor` | `HoverOpacity` | | OnBackgroundFocusedBrush | `OnBackgroundColor` | `FocusedOpacity` | | OnBackgroundPressedBrush | `OnBackgroundColor` | `PressedOpacity` | | OnBackgroundDraggedBrush | `OnBackgroundColor` | `DraggedOpacity` | | OnBackgroundSelectedBrush | `OnBackgroundColor` | `SelectedOpacity` | | OnBackgroundMediumBrush | `OnBackgroundColor` | `MediumOpacity` | | OnBackgroundLowBrush | `OnBackgroundColor` | `LowOpacity` | | OnBackgroundDisabledBrush | `OnBackgroundColor` | `DisabledOpacity` | | SurfaceBrush | `SurfaceColor` | 1 | | SurfaceHoverBrush | `SurfaceColor` | `HoverOpacity` | | SurfaceFocusedBrush | `SurfaceColor` | `FocusedOpacity` | | SurfacePressedBrush | `SurfaceColor` | `PressedOpacity` | | SurfaceDraggedBrush | `SurfaceColor` | `DraggedOpacity` | | SurfaceSelectedBrush | `SurfaceColor` | `SelectedOpacity` | | SurfaceMediumBrush | `SurfaceColor` | `MediumOpacity` | | SurfaceLowBrush | `SurfaceColor` | `LowOpacity` | | SurfaceDisabledBrush | `SurfaceColor` | `DisabledOpacity` | | OnSurfaceBrush | `OnSurfaceColor` | 1 | | OnSurfaceHoverBrush | `OnSurfaceColor` | `HoverOpacity` | | OnSurfaceFocusedBrush | `OnSurfaceColor` | `FocusedOpacity` | | OnSurfacePressedBrush | `OnSurfaceColor` | `PressedOpacity` | | OnSurfaceDraggedBrush | `OnSurfaceColor` | `DraggedOpacity` | | OnSurfaceSelectedBrush | `OnSurfaceColor` | `SelectedOpacity` | | OnSurfaceMediumBrush | `OnSurfaceColor` | `MediumOpacity` | | OnSurfaceLowBrush | `OnSurfaceColor` | `DisabledOpacity` | | OnSurfaceDisabledBrush | `OnSurfaceColor` | `DisabledOpacity` | | SurfaceVariantBrush | `SurfaceVariantColor` | 1 | | SurfaceVariantHoverBrush | `SurfaceVariantColor` | `HoverOpacity` | | SurfaceVariantFocusedBrush | `SurfaceVariantColor` | `FocusedOpacity` | | SurfaceVariantPressedBrush | `SurfaceVariantColor` | `PressedOpacity` | | SurfaceVariantDraggedBrush | `SurfaceVariantColor` | `DraggedOpacity` | | SurfaceVariantSelectedBrush | `SurfaceVariantColor` | `SelectedOpacity` | | SurfaceVariantMediumBrush | `SurfaceVariantColor` | `MediumOpacity` | | SurfaceVariantLowBrush | `SurfaceVariantColor` | `LowOpacity` | | SurfaceVariantDisabledBrush | `SurfaceVariantColor` | `DisabledOpacity` | | OnSurfaceVariantBrush | `OnSurfaceVariantColor` | 1 | | OnSurfaceVariantHoverBrush | `OnSurfaceVariantColor` | `HoverOpacity` | | OnSurfaceVariantFocusedBrush | `OnSurfaceVariantColor` | `FocusedOpacity` | | OnSurfaceVariantPressedBrush | `OnSurfaceVariantColor` | `PressedOpacity` | | OnSurfaceVariantDraggedBrush | `OnSurfaceVariantColor` | `DraggedOpacity` | | OnSurfaceVariantSelectedBrush | `OnSurfaceVariantColor` | `SelectedOpacity` | | OnSurfaceVariantMediumBrush | `OnSurfaceVariantColor` | `MediumOpacity` | | OnSurfaceVariantLowBrush | `OnSurfaceVariantColor` | `LowOpacity` | | OnSurfaceVariantDisabledBrush | `OnSurfaceVariantColor` | `DisabledOpacity` | | SurfaceInverseBrush | `SurfaceInverseColor` | 1 | | SurfaceInverseHoverBrush | `SurfaceInverseColor` | `HoverOpacity` | | SurfaceInverseFocusedBrush | `SurfaceInverseColor` | `FocusedOpacity` | | SurfaceInversePressedBrush | `SurfaceInverseColor` | `PressedOpacity` | | SurfaceInverseDraggedBrush | `SurfaceInverseColor` | `DraggedOpacity` | | SurfaceInverseSelectedBrush | `SurfaceInverseColor` | `SelectedOpacity` | | SurfaceInverseMediumBrush | `SurfaceInverseColor` | `MediumOpacity` | | SurfaceInverseLowBrush | `SurfaceInverseColor` | `LowOpacity` | | SurfaceInverseDisabledBrush | `SurfaceInverseColor` | `DisabledOpacity` | | OnSurfaceInverseBrush | `OnSurfaceInverseColor` | 1 | | OnSurfaceInverseHoverBrush | `OnSurfaceInverseColor` | `HoverOpacity` | | OnSurfaceInverseFocusedBrush | `OnSurfaceInverseColor` | `FocusedOpacity` | | OnSurfaceInversePressedBrush | `OnSurfaceInverseColor` | `PressedOpacity` | | OnSurfaceInverseDraggedBrush | `OnSurfaceInverseColor` | `DraggedOpacity` | | OnSurfaceInverseSelectedBrush | `OnSurfaceInverseColor` | `SelectedOpacity` | | OnSurfaceInverseMediumBrush | `OnSurfaceInverseColor` | `MediumOpacity` | | OnSurfaceInverseLowBrush | `OnSurfaceInverseColor` | `LowOpacity` | | OnSurfaceInverseDisabledBrush | `OnSurfaceInverseColor` | `DisabledOpacity` | | OutlineBrush | `OutlineColor` | 1 | | OutlineHoverBrush | `OutlineColor` | `HoverOpacity` | | OutlineFocusedBrush | `OutlineColor` | `FocusedOpacity` | | OutlinePressedBrush | `OutlineColor` | `PressedOpacity` | | OutlineDraggedBrush | `OutlineColor` | `DraggedOpacity` | | OutlineSelectedBrush | `OutlineColor` | `SelectedOpacity` | | OutlineMediumBrush | `OutlineColor` | `MediumOpacity` | | OutlineLowBrush | `OutlineColor` | `LowOpacity` | | OutlineDisabledBrush | `OutlineColor` | `DisabledOpacity` | | OutlineVariantBrush | `OutlineVariantColor` | 1 | | OutlineVariantHoverBrush | `OutlineVariantColor` | `HoverOpacity` | | OutlineVariantFocusedBrush | `OutlineVariantColor` | `FocusedOpacity` | | OutlineVariantPressedBrush | `OutlineVariantColor` | `PressedOpacity` | | OutlineVariantDraggedBrush | `OutlineVariantColor` | `DraggedOpacity` | | OutlineVariantSelectedBrush | `OutlineVariantColor` | `SelectedOpacity` | | OutlineVariantMediumBrush | `OutlineVariantColor` | `MediumOpacity` | | OutlineVariantLowBrush | `OutlineVariantColor` | `LowOpacity` | | OutlineVariantDisabledBrush | `OutlineVariantColor` | `DisabledOpacity` | | SurfaceTintBrush | `SurfaceTintColor` | 1 | --- # Source: https://raw.githubusercontent.com/unoplatform/uno.themes/refs/heads/master/doc/material-dsp.md --- uid: Uno.Themes.Material.DSP --- # Using the DSP Tooling in Uno.Material ## Introduction Is it possible to automate the creation of the Material Design color palette? Yes, it is. Uno.Material provides a tooling to generate the color palette from the official Material Design color palette. This tooling is available in the [Uno.Dsp.Cli](https://nuget.org/packages/Uno.Dsp.Cli) and [Uno.Dsp.Tasks](https://nuget.org/packages/Uno.Dsp.Tasks) NuGet packages. The following instructions will cover the Uno.Dsp.Tasks version, which is more automatic. > [!NOTE] > Make sure you are referencing the generated XAML file in your > application's `App.xaml` file, as shown in the following example: > > ```xml > ColorOverrideSource="ms-appx:///PROJECT_NAME/Styles/Application/MaterialColorsOverride.xaml" /> > ``` > > More details [In the _Manual Color Overrides_ section of the Getting Started page](xref:Uno.Themes.Material.GetStarted) ## The Uno.Dsp.Tasks NuGet package This package will be automatically present in the project after [creating a new Uno Platform project](https://aka.platform.uno/get-started) specifying the _Material_ theme. It is also possible to add it manually to an existing Uno Platform project by adding the following line to the _PackageReference_ section of the _csproj_ file: * Add a nuget package reference: ```xml ``` * The package is already present when you select _Material_ theme during project creation: ![Selection of Material theme when creating a project using the Uno Template Wizard](assets/material-theme-selection-wizard.png) It is possible to configure the import process. The _UnoDspImportColors_ item found in the _csproj_ file has a number of attributes we can set: | Attribute | Description | Default Value | |------------------|---------------------------------|-------------------------| | `Include` | Style files to input | | | `Generator`* | Type of generator to use | `Xaml` | | `OutputPath`** | Path to use for the output | Input file directory | \* The possible values for `Generator` are `Xaml` or `Csharp`. \*\* If `Include` is a glob (eg: \*.json), `OutputPath` should be a directory. ```xml ``` ## Generating a custom color palette and exporting it as a JSON file 1. Navigate to the [Material Theme Builder](https://aka.platform.uno/uno-material-themebuilder) and select the colors you want to use for your application. 2. When you are done customizing, open the **Export** section located at the top rightmost of the screen. ![material-theme-export-section](assets/material-theme-export-section.png) 3. In the **Export** section, locate the _Export_ button and pick the _Material Theme (JSON)_ format. ![material-theme-export-button](assets/material-theme-export-button.png) ![material-theme-export-json](assets/material-theme-export-json.png) 4. Save the file to your computer. 5. Replace the `ColorPaletteOverride.json` file in the `Styles` folder of your application project with the one you just downloaded. 6. Build your application. The `ColorPaletteOverride.xaml` file will be automatically updated with the colors present in the JSON file. ## More flexibility Using `Uno.Dsp.Tasks` will generate the file at each build, potentially overriding any changes you made to it. If you want to keep it that way, you can remove the `ColorPaletteOverride.json` file from the `Styles` folder so it won't get overwritten. Alternatively, you can use the [Uno.Dsp.Cli](https://nuget.org/packages/Uno.Dsp.Cli) package to generate the file from the command line. This tool allows you to generate the file only when desired rather than during every build. > [!NOTE] > Although the **Material Theme Builder Tool** doesn't export **Material Tokens (DSP)** packages anymore, to import DSP packages just follow the same steps described previously and save the downloaded DSP zip file as `ColorPaletteOverride.zip` in the `Styles` folder of your application project. > In that case, make sure to delete the `material-theme.json` file from `Styles` folder before building your application, to avoid conflicts. --- # Source: https://raw.githubusercontent.com/unoplatform/uno.toolkit.ui/refs/heads/main/doc/material-getting-started.md # Source: https://raw.githubusercontent.com/unoplatform/uno.themes/refs/heads/master/doc/material-getting-started.md # Source: https://raw.githubusercontent.com/unoplatform/uno.toolkit.ui/refs/heads/main/doc/material-getting-started.md --- uid: Toolkit.GettingStarted.Material --- # Uno Material Toolkit Library

Material Toolkit Design System

The Uno Material Toolkit provides a set of resources and styles based on [Material Design guidelines](https://m3.material.io/) for the controls included in the base [Uno Toolkit library](xref:Toolkit.GettingStarted) ## Getting Started Initialization of the Material Toolkit resources is handled by the specialized `MaterialToolkitTheme` ResourceDictionary. ### `MaterialToolkitTheme` > [!NOTE] > The `MaterialToolkitTheme` class also handles the required initialization of the Uno Material resources. Therefore, there is no need to initialize `MaterialTheme` within the `App.xaml` #### Constructors | Constructor | Description | |---------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------| | `MaterialToolkitTheme()` | Initializes a new instance of the `MaterialToolkitTheme` resource dictionary. | | `MaterialToolkitTheme(ResourceDictionary? colorOverride, ResourceDictionary? fontOverride)` | Initializes a new instance of the `MaterialToolkitTheme` resource dictionary and applies the given overrides | #### Properties | Property | Type | Description | |-----------------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `ColorOverrideSource` | `string` | (Optional) Gets or sets a Uniform Resource Identifier that provides the source location of a ResourceDictionary containing overrides for the default Uno.Material Color resources | | `FontOverrideSource` | `string` | (Optional) Gets or sets a Uniform Resource Identifier that provides the source location of a ResourceDictionary containing overrides for the default Uno.Material FontFamily resources | ## Installation > [!NOTE] > Make sure to setup your environment first by [following our instructions](xref:Uno.GetStarted.vs2022). ### Creating a new project with the Uno Material Toolkit #### [**Wizard**](#tab/wizard) 1. Follow the steps in the [Getting Started with Visual Studio](xref:Uno.GettingStarted.CreateAnApp.VS2022#create-the-app) instructions to launch the Uno Platform Template Wizard. 2. Select `Material` under the `Theme` section. ![Material selection in the Uno Platform Template Wizard](assets/material-toolkit-wizard-theme.png) 3. Select `Toolkit` under the `Features` section. ![Toolkit selection in the Uno Platform Template Wizard](assets/material-toolkit-wizard-feature.png) #### [**CLI**](#tab/cli) 1. Install the [`dotnet new` CLI templates](xref:Uno.GetStarted.dotnet-new) with: ```bash dotnet new install Uno.Templates ``` 2. Create a new application with: ```bash dotnet new unoapp -o MaterialToolkitApp -toolkit -theme material ``` --- ### Installing Uno Material Toolkit in an existing project Depending on the type of project template that the Uno Platform application was created with, follow the instructions below to install the Uno Material Toolkit. #### [**Single Project Template**](#tab/singleproj) 1. Edit your project file (`PROJECT_NAME.csproj`) and add `Toolkit` and `Material` to the list of `UnoFeatures`: ```xml Toolkit;Material ``` 2. Initialize `MaterialToolkitTheme` in the `App.xaml`: ```xml ``` #### [**Multi-Head Project Template (Legacy)**](#tab/multihead) 1. In the Solution Explorer panel, right-click on your app's **App Code Library** project (`PROJECT_NAME.csproj`) and select `Manage NuGet Packages...` 2. Install the [`Uno.Toolkit.WinUI.Material`](https://www.nuget.org/packages/Uno.Toolkit.WinUI.Material) 3. Add the `MaterialToolkitTheme` to `AppResources.xaml`: ```xml ``` #### [**Shared Project (.shproj) Template (Legacy)**](#tab/shproj) 1. In the Solution Explorer panel, right-click on your solution name and select `Manage NuGet Packages for Solution ...`. Choose either: - The [`Uno.Toolkit.UI.Material`](https://www.nuget.org/packages/Uno.Toolkit.UI.Material/) package when targetting Xamarin/UWP - The [`Uno.Toolkit.WinUI.Material`](https://www.nuget.org/packages/Uno.Toolkit.WinUI.Material) package when targetting net6.0+/WinUI 2. Select the following projects for installation: - `PROJECT_NAME.Wasm.csproj` - `PROJECT_NAME.Mobile.csproj` (or `PROJECT_NAME.iOS.csproj`, `PROJECT_NAME.Droid.csproj`, and `PROJECT_NAME.macOS.csproj` if you have an existing project) - `PROJECT_NAME.Skia.Gtk.csproj` - `PROJECT_NAME.Skia.WPF.csproj` - `PROJECT_NAME.Windows.csproj` (or `PROJECT_NAME.UWP.csproj` for existing projects) 3. Add the following resources inside `App.xaml`: ```xml ``` --- ## Customization With `MaterialToolkitTheme`, you do not need to explicitly initialize `ToolkitResources`, `MaterialTheme`, `MaterialColors`, or `MaterialFonts`. This means that all resource overrides should go through `MaterialToolkitTheme` itself. There are two properties on `MaterialToolkitTheme` that you can set within your `App.xaml`. ### Customize Colors Follow the [Uno Material Customization guide](xref:Uno.Themes.Material.GetStarted#customization) to create a `ColorPaletteOverride.xaml` file and add it to your application project. In `App.xaml`, use the `ColorOverrideSource` property on `MaterialToolkitTheme`: ```xml ``` ### Customize Fonts Follow the [Uno Material Customization guide](xref:Uno.Themes.Material.GetStarted#customization) to create a `FontOverride.xaml` file and add it to your application project. In `App.xaml`, use the `FontOverrideSource` property on `MaterialToolkitTheme`: ```xml ``` ## Using C# Markup The Uno Material Toolkit library also has support for C# Markup through a [Uno.Toolkit.WinUI.Material.Markup](https://www.nuget.org/packages/Uno.Toolkit.WinUI.Material.Markup) NuGet Package. To get started with the Uno Material Toolkit in your C# Markup application, add the `Uno.Toolkit.WinUI.Material.Markup` NuGet package to your application project. Then, add the following code to your `App.xaml.cs`: ```csharp using Uno.Toolkit.UI.Material.Markup; this.Build(r => r.UseMaterialToolkit( //optional new Styles.ColorPaletteOverride(), //optional new Styles.MaterialFontsOverride() )); ``` > [!NOTE] > The [Uno.Toolkit.WinUI.Material.Markup](https://www.nuget.org/packages/Uno.Toolkit.WinUI.Material.Markup) NuGet package includes the base [Uno Toolkit Markup package](https://www.nuget.org/packages/Uno.Toolkit.WinUI.Markup) as a dependency. Therefore, there is no need to add the `Uno.Toolkit.WinUI.Markup` package separately. Furthermore, the `UseMaterialToolkit` extension method also initializes the base Uno Toolkit library, so there is no need to call the `UseToolkit` extension method in your `App.xaml.cs`. ## Additional Resources - [Uno Platform Material Toolkit Sample App](https://aka.platform.uno/unomaterialtoolkit-sampleapp) - [Uno Platform Material Toolkit Figma File](https://aka.platform.uno/uno-figma-material-toolkit) - [Official Material Design 3 Guidelines](https://m3.material.io/components) - [Official Material Design 3 Theme Builder](https://m3.material.io/theme-builder) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-apps.md --- uid: Uno.Development.MigratingApps --- # Migrating a WinUI/UWP-only application codebase to an Uno Platform application This article describes how to migrate a C# and XAML application targeting only WinUI/UWP to one targeting multiple platforms using Uno Platform. The final application codebase will share 99% of the same code as the original, but the solution structure will be different. It assumes you're using Visual Studio for Windows, but the steps are similar if you're using VS Code or another IDE. The basic principle is to create an empty Uno Platform app with the same name as your WinUI/UWP-only app and to copy the contents of the old app into the main project of the new app. After you've migrated the files and dependencies, the general [migration guidance article](migrating-guidance.md) will take you through the final steps to adjust your code to be Uno-compatible. ## Prerequisites Follow the instructions to [set up your development environment for Uno Platform with Visual Studio for Windows](xref:Uno.GetStarted.vs2022). You can also use another IDE such as [VS Code](xref:Uno.GetStarted.vscode), however some steps may be slightly different. ## Migrating files to the Uno solution structure Note: these steps will **destructively modify** your existing WinUI/UWP-only solution. Make sure you have a copy in source control or in a backup folder. 1. In order to reuse the name of the existing WinUI/UWP project, we want to first rename it and its containing folder. (If you don't want to reuse the name, you can skip this step.) i. First, rename the project itself within the solution by right-clicking on the project and choosing 'Rename'. For example, if the project is called `BugTracker`, we can rename it to `BugTracker_OLD`. ii. Next the folder containing the project must be renamed (assuming it still has the default name from when the project was originally created). Navigate to the folder containing the project. (Eg, by right-clicking on the project in Visual Studio and choosing 'Open Folder in File Explorer'.) Close your Visual Studio instance. Rename the folder, so that the project path becomes `./BugTracker_OLD/BugTracker_OLD.csproj`. iii. Finally, before reopening Visual Studio, open the `.sln` file with your favorite text editor. Locate the line referencing your project, and update it to the new path. It should look something like: ```sln Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BugTracker_OLD", "BugTracker_OLD\BugTracker_OLD.csproj", "{92E4C60C-336D-4DFB-B08D-80489617C1F2}" ``` 1. Open the solution. Right-click on the solution and choose 'Add > New Project'. Search for the 'Uno Platform App' template. Enter the desired name (eg `BugTracker` in our fictional example). Hit 'Create'. You should now have a project named `BugTracker`. 1. Delete `MainPage.xaml` from the new project - you will replace these with your existing files. 1. Replace `App.cs` contents with everything from your existing `App.xaml.cs` except the `InitializeComponent` call in the constructor. 1. Transfer all code files (C# and XAML) and assets from your old WinUI/UWP-only project to the new project. *Note: you can safely delete 'head' projects for platforms that you're sure you don't want to target.* ## Adding dependencies If your old WinUI/UWP app project had dependencies, you will have to add those dependencies to each new target platform project you wish to support. These include: - .NET Standard projects within the solution: you should be able to add these as dependencies to any target platform project without difficulties. - WinUI/UWP projects within the solution: these will have to be modified to be cross-platform class libraries - follow the instructions in [Migrating Libraries](migrating-libraries.md). - external dependencies: [see information here](migrating-before-you-start.md) on finding equivalent dependencies for NuGet packages and framework libraries. ## Migrating app configuration For WinUI/UWP, the `Package.appxmanifest` file can be copied directly from your old WinUI/UWP project to the new one in the `Platforms` folder. For other platforms, you will need to manually set the app name, capabilities, and other packaging information. ## Adjusting code for Uno compatibility [See the next section](migrating-guidance.md) for adjustments to make to get your code compiling on Uno. ## What if my existing app targets WinUI 3? The basic idea is the same, however, you'll use the [`dotnet new` templates](xref:Uno.GetStarted.dotnet-new) to create a WinUI 3-compatible Uno Platform app, into which you can transfer files and dependencies in a similar manner. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-before-you-start.md --- uid: Uno.Development.MigratingBeforeYouStart --- # Migrating WinUI/UWP-only code - Checklist Before you start migrating a WinUI/UWP-only application or library to be Uno compatible, it's a good idea to assess the degree of effort involved in getting the port fully functional. Depending on the code in question, it may be as easy as copying the files, or it may involve significant extra effort. The key questions to ask are: - what framework APIs is the code using? - what third-party dependencies does the code rely upon? - what general .NET functionality is used that may not be supported on specific platforms? ## Controls and framework APIs The controls supported by Uno and those currently unsupported are [listed here](implemented-views.md). You can see supported non-UI APIs under the 'Features and Controls' section of the docs. Note that API coverage varies by the target platform. Once you migrate your code to Uno, unsupported API usages will be highlighted with a warning by Uno's included Roslyn analyzer. ## Third-party dependencies Look at the NuGet packages referenced by the code. For each package, ask: - is it supported on each platform you wish to target? - if not, is there an acceptable alternative? Third-party dependencies typically fall into one of a few categories: ### Platform-independent Fully platform-independent dependencies will typically be packaged as .NET Standard binaries. They should be compatible with any target. ### Platform-dependent These include dependencies that may be calling platform-specific functionality (eg push notifications), or that may depend on unmanaged binaries that must be separately compiled for each platform. You can check if there is a version of the package for your target platform by visiting the package page on nuget.org and opening the 'Dependencies' expander. Typically you'll see `UAP 10.0.x` listed as a target. If you want to target Android and iOS with Uno, you should check that `MonoAndroid` and `Xamarin.iOS` are listed as supported targets. If you want to target macOS, check that `Xamarin.Mac` is listed. Unfortunately, it's less easy to check if a platform-dependent package supports WebAssembly or Linux. Uno builds .NETStandard binaries for these targets, but the fact that a .NETStandard version exists for any given dependency doesn't guarantee that it will function as expected on those platforms, if platform-specific APIs are involved. You'll generally have to do some additional research. ### Depends on WinUI/UWP Libraries that depend on WinUI/UWP itself, such as the [Windows Community Toolkit](https://learn.microsoft.com/windows/communitytoolkit/), must be recompiled against Uno Platform in order to be used. A number of popular WinUI/UWP libraries have already been retargeted to Uno; a partial list is given in the [Uno features section](https://github.com/unoplatform/Uno#uno-features). ## .NET runtime features On certain target platforms, support for some .NET functionality is limited or unavailable. ### iOS .NET code must be Ahead-Of-Time (AOT) compiled to run on iOS, as a fundamental platform limitation. As a result, certain APIs that require runtime code generation (eg `System.Reflection.Emit`) will not work. This includes code that uses the `dynamic` keyword. See the [Xamarin.iOS documentation](https://learn.microsoft.com/xamarin/ios/internals/limitations) for more details. ### WASM Currently, WebAssembly code in the browser executes on a single thread (much like JavaScript code in the browser). This limitation is expected to be lifted in the future, but for now, code that expects additional threads to be available may not function as expected. [This issue](https://github.com/unoplatform/uno/issues/2302) tracks support for multi-threading on WebAssembly in Uno Platform. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-from-net7-to-net8.md --- uid: Uno.Development.MigratingFromNet7ToNet8 --- # How to upgrade from .NET 7 to .NET 8 Migrating from .NET 7 to .NET 8 is a generally straightforward process. You may find below some specific adjustments to make to your projects and libraries when upgrading. To upgrade to .NET 8: - First, read [What's New in .NET 8](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-8) - Install [Visual Studio 17.8](https://visualstudio.microsoft.com/vs/) or later and run [uno.check](xref:UnoCheck.UsingUnoCheck) to install .NET 8. - Change all your target framework (TFM) references from `net7.0` to `net8.0`, and `net7.0-*` to `net8.0-*`. If you are using a TFM like net7.0-ios13.6, be sure to match the shipping version of that platform or just remove the platform version (i.e. 13.6). - Delete your bin and obj folders ## Migrating Shared Class Libraries from net7.0 to net8.0 If you are building on windows and experience the compilation error NETSDK1083 when retargeting your library from net7.0 to net8.0, add the following to the `csproj`: ```xml win-x86;win-x64;win-arm64 ``` You may also need to add to your `.Windows.csproj`: ```xml true ``` ## Upgrading the IL Linker for WebAssembly If you're using the [XAML Resource Trimming feature](xref:Uno.Features.ResourcesTrimming), you'll need to upgrade or add the following package to your `.Wasm.csproj`: ```xml ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-from-net8-to-net9.md --- uid: Uno.Development.MigratingFromNet8ToNet9 --- # How to upgrade from .NET 8 to .NET 9 Migrating from .NET 8 to .NET 9 is a generally straightforward process. You may find below some specific adjustments to make to your projects and libraries when upgrading. To upgrade to .NET 9: - First, read [What's New in .NET 9](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-9/overview) - Install/Update the IDE of your choice: - [Visual Studio](https://visualstudio.microsoft.com/vs/) - minimal version **2022 17.13** or later - [Visual Studio Code](https://code.visualstudio.com/) - minimal version **1.94** or later with the related [**C# Dev Kit**](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) stable version - [JetBrains Rider](https://www.jetbrains.com/rider/) - minimal version **2024.3** or later - Run [uno.check](xref:UnoCheck.UsingUnoCheck) to install .NET 9. - Change all your target framework (TFM) references from `net8.0` to `net9.0`, and `net8.0-*` to `net9.0-*`. - Delete your bin and obj folders ## Considerations for WebAssembly WebAssembly support for .NET 9 has made significant internal changes to use the official .NET SDK. Read the following [documentation for WebAssembly migrations](https://aka.platform.uno/wasm-net9-upgrade). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-from-net9-to-net10.md --- uid: Uno.Development.MigratingFromNet9ToNet10 --- # How to Upgrade from .NET 9 to .NET 10 Migrating from .NET 9 to .NET 10 is a generally straightforward process. Below are some specific adjustments you may need to make to your projects and libraries when upgrading. To upgrade to .NET 10: - First, read [What's New in .NET 10](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/overview). - Use **[.NET 10 RC1](https://devblogs.microsoft.com/dotnet/dotnet-10-rc-1/)** along with: - **Visual Studio** - the latest version of [Visual Studio 2026 Insiders](https://visualstudio.microsoft.com/insiders/), as recommended by Microsoft in their [announcement](https://devblogs.microsoft.com/dotnet/dotnet-10-rc-1/#🚀-get-started). Use version **18.0.0 [11104.47]** or later to ensure compatibility with the [latest stable Uno Platform extension](https://aka.platform.uno/vs-extension-marketplace). - **Visual Studio Code** - the latest version of [Visual Studio Code](https://code.visualstudio.com/Download) and the [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) extension, also recommended by Microsoft in the same [announcement](https://devblogs.microsoft.com/dotnet/dotnet-10-rc-1/#🚀-get-started). - **Rider** - the latest stable version, as .NET 10 support has been available since [Rider 2025.1](https://www.jetbrains.com/rider/whatsnew/2025-1/). - Run the latest stable version of [uno.check](xref:UnoCheck.UsingUnoCheck) with the [`--pre-major` parameter](https://aka.platform.uno/uno-check-pre-major) to install .NET 10. - Uno Platform provides an updated [Visual Studio extension](https://aka.platform.uno/vs-extension-marketplace) in the store that supports Visual Studio 2026 and the new `.slnx` solution format. - Change all your target framework (TFM) references from `net9.0` to `net10.0`, and from `net9.0-*` to `net10.0-*`. - Clean your project by deleting the `bin` and `obj` folders. ## Known Issues For an up-to-date list of **known issues** when using **.NET 10** with Uno Platform, please refer to our [Health Status page](https://aka.platform.uno/health-status). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-from-previous-releases.md --- uid: Uno.Development.MigratingFromPreviousReleases --- # Migrating from Previous Releases of Uno Platform To upgrade to the latest version of Uno Platform, [follow our guide](xref:Uno.Development.UpgradeUnoNuget). ## Uno Platform 6.5 Uno Platform 6.5 does not contain breaking changes that require attention when upgrading > [!NOTE] > Uno App MCP: if using Visual Studio 2022/2026, sometimes the Uno App MCP does not appear in the Visual Studio tools list. See [how to make the App MCP appear in Visual Studio](xref:Uno.UI.CommonIssues.AIAgents#the-app-mcp-does-not-appear-in-visual-studio). ## Uno Platform 6.4 Uno Platform 6.4 contains an Uno.Extensions breaking changes that require attention when upgrading: - Uno.Extensions contains an OidcClient change in namespaces. See [the migration guide](xref:Uno.Extensions.Migration) for details. ### Visual Studio, Visual Studio Code, and Rider When upgrading to Uno Platform 6.4, make sure to update your IDE extension or plugin to the latest stable version to ensure the Uno Platform development tooling connects properly. - [Visual Studio extension](https://aka.platform.uno/vs-extension-marketplace) - [Visual Studio Code extension](https://aka.platform.uno/vscode-extension-marketplace) - [Rider plugin](https://aka.platform.uno/rider-extension-marketplace) ## Uno Platform 6.3 **Uno Platform 6.3** introduces support for **.NET 10 RC1** and removes **.NET 8** targets. ### Visual Studio, Visual Studio Code, and Rider When upgrading to Uno Platform 6.3, make sure to update your IDE extension or plugin to the latest stable version to ensure the Uno Platform development tooling connects properly. - [Visual Studio extension](https://aka.platform.uno/vs-extension-marketplace) - [Visual Studio Code extension](https://aka.platform.uno/vscode-extension-marketplace) - [Rider plugin](https://aka.platform.uno/rider-extension-marketplace) ### .NET 8 Support Removed .NET 8 targets for apps are no longer supported by Uno Platform 6.3. However, NuGet library packages that are built with `net8.0 (and earlier) and Uno 6.0 (and later) continue to be compatible with Uno Platform apps built with .NET 9 and later. While .NET 8 itself remains a Long-Term Support (LTS) release supported until [November 2026](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core), the **.NET MAUI 8** mobile workload reached end of support in [May 2025](https://dotnet.microsoft.com/en-us/platform/support/policy/maui). You can [upgrade your project to .NET 9](xref:Uno.Development.MigratingFromNet8ToNet9) using our migration guide. If you need to stay on .NET 8, you can continue to use **Uno Platform 6.2 or earlier** and plan your migration to .NET 9 or .NET 10 at a later time. ### .NET 10 RC1 **Uno Platform 6.3** is now built with **.NET 10** support, allowing you to upgrade existing projects or create new ones using the project wizard or CLI. A few considerations to keep in mind: - Moving to .NET 10 or upgrading existing projects requires using **.NET 10 RC1** along with: - **Visual Studio** — the latest version of [Visual Studio 2026 Insiders](https://visualstudio.microsoft.com/insiders/), as recommended by Microsoft in their [announcement](https://devblogs.microsoft.com/dotnet/dotnet-10-rc-1/#🚀-get-started). Use version **18.0.0 [11104.47]** or later to ensure compatibility with the [latest stable Uno Platform extension](https://aka.platform.uno/vs-extension-marketplace). - **Visual Studio Code** — the latest version of [Visual Studio Code](https://code.visualstudio.com/Download) and the [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) extension, as also recommended by Microsoft in the same [announcement](https://devblogs.microsoft.com/dotnet/dotnet-10-rc-1/#🚀-get-started). - **Rider** — the latest stable version, as .NET 10 support has been available since [Rider 2025.1](https://www.jetbrains.com/rider/whatsnew/2025-1/). - Uno Platform provides an updated [Visual Studio extension](https://aka.platform.uno/vs-extension-marketplace) that supports **Visual Studio 2026** and the new `.slnx` solution format. - To migrate your project to .NET 10, see our [migration guide](xref:Uno.Development.MigratingFromNet9ToNet10). For an up-to-date list of **known issues** when using **.NET 10** with Uno Platform, please refer to our [Health Status page](https://aka.platform.uno/health-status). ### API Changes for Android Starting with Uno Platform **6.3**, the following methods now throw `NotSupportedException` under **.NET 10** or later: - `Microsoft.UI.Xaml.ApplicationActivity.GetTypeAssemblyFullName(string)` (Android + Native renderer) - `Microsoft.UI.Xaml.ApplicationActivity.GetTypeAssemblyFullName(string)` (Android + Skia renderer) - `Microsoft.UI.Xaml.NativeApplication.GetTypeAssemblyFullName(string)` This change was introduced in [PR #21199](https://github.com/unoplatform/uno/pull/21199) ([commit 4d84ee3](https://github.com/unoplatform/uno/commit/4d84ee31adb3e7ecd3fcbdc248b79fee78211d3e)). Methods with the [`[Java.Interop.ExportAttribute]` custom attribute](https://learn.microsoft.com/dotnet/api/java.interop.exportattribute?view=net-android-34.0) are not supported within certain runtime environments. If your application calls any of the affected methods: - Remove any direct usage of `GetTypeAssemblyFullName`. - Consider removing methods with the `[Export]` custom attribute, as they may not work in certain runtime environments. Consider using managed interop or dependency injection alternatives instead. - If you relied on these APIs for reflection or interop, migrate that logic to managed code executed at runtime. - Rebuild and test your Android and Android+Skia apps with .NET 10 or later to ensure compatibility. These changes prevent runtime exceptions and improve compatibility for builds on Android. ## Uno Platform 6.2 Uno Platform 6.2 does not contain breaking changes that require attention when upgrading. ## Uno Platform 6.1 Uno Platform 6.1 does not contain breaking changes that require attention when upgrading. ## Uno Platform 6.0 Uno Platform 6.0 contains breaking changes required to provide a consistent experience when using the Skia rendering feature, as well as the removal of the UWP API set support and the GTK desktop runtime support. Read additional information about the [migration to Uno Platform 6.0](xref:Uno.Development.MigratingToUno6). ## Uno Platform 5.6 Uno Platform 5.6 contains one breaking change around using `x:Load` to align the behavior to WinUI. ### Lazy loading To align the behavior with WinUI, lazy loading using `x:Load="False"` and `x:DeferLoadStrategy="lazy"` is no longer affected by changes to the visibility of the lazily-loaded element. Previously, binding the `Visibility` property of the lazily-loaded element and then updating the binding source to make the element visible would cause the element to materialize (i.e. load). This is no longer the case. To load the element, add an `x:Name` to the element and call `FindName` with the given name. ## Uno Platform 5.5 Uno Platform 5.5 introduces support for .NET 9 RC2 and requires installation updates for WebAssembly. ### .NET 9 RC2 A few considerations to take into account: - Moving to .NET 9 or upgrading .NET 9 projects now require the use of .NET 9 RC2 and Visual Studio 17.12 Preview 3. - To migrate a project to .NET 9, [read the directions](xref:Uno.Development.MigratingFromNet8ToNet9) from our documentation. ### The EnableHotReload method is deprecated When upgrading to Uno 5.5, in the `App.xaml.cs` file, the `EnableHotReload()` method is deprecated and must be replaced with `UseStudio()` instead. ## Uno Platform 5.4 Uno Platform 5.4 contains breaking changes for Uno.Extensions. ### WinAppSDK 1.6 considerations Uno Platform 5.4 updates to WinAppSDK 1.6 if you are using the [`Uno.SDK`](xref:Uno.Features.Uno.Sdk), which requires a temporary version adjustment until newer versions of the .NET 8 SDKs are released. In your project, you may need to add the following lines (or uncomment them if you kept them from our templates) to get the `net8.0-windowsXX` target to build: ```xml 10.0.19041.38 ``` Additionally, you may also get the following error message: ```text NETSDK1198: A publish profile with the name 'win-AnyCPU.pubxml' was not found in the project. ``` This issue is not yet fixed, but it does not cause any problems during deployment. ### UWP Support for Uno.Extensions The [`Uno.Extensions`](https://aka.platform.uno/uno-extensions) compatibility with legacy UWP apps has been removed. If your app is UWP-based and uses Uno.Extensions, in order to migrate to Uno Platform 5.4, you can keep using [previous releases of Uno.Extensions](https://github.com/unoplatform/uno.extensions/releases), or [migrate your app to WinUI](https://platform.uno/docs/articles/updating-to-winui3.html). All the other features of Uno Platform 5.4 continue to be compatible with both UWP and WinUI apps. ### Updates in Uno.Extensions.Reactive The generated code has changed. Make sure to [review our docs to upgrade](xref:Uno.Extensions.Reactive.Upgrading) to Uno Platform 5.4. ## Uno Platform 5.3 Uno Platform 5.3 contains an improved template and Uno.SDK versioning, new default text font, and Rider support. The support for .NET 7 has been removed, since it was a Standard Term Support (STS) release which [ended in May 2024](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core). You can [upgrade your project to .NET 8](xref:Uno.Development.MigratingFromNet7ToNet8) using our guide. Make sure to [re-run Uno.Check](xref:UnoCheck.UsingUnoCheck) to get all the latest dependencies. ### Visual Studio Update your [Uno Platform extension](https://aka.platform.uno/vs-extension-marketplace) in VS 2022 to 5.3.x or later. Earlier versions may automatically update to an incorrect version of the Uno.SDK. ### Single Project updates Similar to version 5.2, using the new project template is entirely optional and previous project structures are fully supported. If you want to migrate to the new Single Project, you can follow the [Migrating to Single Project](xref:Uno.Development.MigratingToSingleProject) guide. If you are upgrading from an Uno Platform 5.2 project, you can remove the following section from your `Directory.Build.props`: ```xml ... ... ... ... ``` ### Default Text Font Starting from Uno Platform 5.3, the [default text font](xref:Uno.Features.CustomFonts#default-text-font) has been changed to [Open Sans](https://github.com/unoplatform/uno.fonts#open-sans-font) in the templates. This is because Uno.Sdk sets `UnoDefaultFont` MSBuild property to `OpenSans` when it's not set to something else. For more information, see [Custom fonts](xref:Uno.Features.CustomFonts). ### Rider support The new [Uno Platform Rider plugin](https://aka.platform.uno/rider-support) support provides C# and XAML Hot Reload support, and to benefit from this new support, new projects created with Uno Platform 5.3 templates contain a new `.run` folder which provides proper support. If your project was created using an Uno Platform 5.2 or earlier template, you can create a new temporary template with the same name as your current project (e.g. `dotnet new unoapp -o MyExistingProject`), then copy over the `.run` folder in your project. ## Uno Platform 5.2 Uno Platform 5.2 contains a new project template that supports all target frameworks into a single project, based on the Uno.Sdk that was introduced in Uno Platform 5.1. Using this new project template is entirely optional and previous project structures are fully supported. If you want to migrate to the new Single Project, you can follow the [Migrating to 5.2 Single Project](xref:Uno.Development.MigratingToSingleProject) guide. ## Uno Platform 5.1 Uno Platform 5.1 does not contain breaking changes that require attention when upgrading. This version however introduces the MSBuild Uno.SDK, which provides support for smaller project files and better Visual Studio integration. Using the Uno.Sdk is entirely optional and previous project templates are fully supported. If you want to migrate to Uno.Sdk based projects, you can follow the [Migrating Projects to Single Project](xref:Uno.Development.MigratingToSingleProject) guide. ## Uno Platform 5.0 Uno Platform 5.0 contains binary-breaking changes in order to further align our API surface with the Windows App SDK. Most of these changes are binary-breaking changes but do not introduce behavior changes. Additionally, this version: - Adds support for .NET 8 for iOS, Android, Mac Catalyst, and macOS. [Follow this guide](xref:Uno.Development.MigratingFromNet7ToNet8) to upgrade from .NET 7 to .NET 8. - Removes the support for Xamarin.iOS, Xamarin.Android, Xamarin.Mac, and netstandard2.0 for WebAssembly. - .NET 7.0 support for iOS, Android, Mac Catalyst, and macOS remains unchanged. - Updates the base Windows SDK version from 18362 to 19041. Uno Platform 5.0 continues to support both UWP and WinUI API sets. Read about additional information about the [migration to Uno Platform 5.0](xref:Uno.Development.MigratingToUno5). ## Uno Platform 4.10 This release does not require upgrade steps. ## Uno Platform 4.9 This release does not require upgrade steps. ## Uno Platform 4.8 This release does not require upgrade steps. ## Uno Platform 4.7 ### Symbol Fonts Uno Platform 4.7 now brings the Uno Fluent Symbols font implicitly. You can remove: - The `uno-fluentui-assets.ttf` file from all your project heads, - Any reference to `uno-fluentui-assets.ttf` in the `UIAppFonts` sections of the iOS `Info.plist` ### Breaking change with ms-appx:/// resolution Uno Platform 4.7 brings a behavior-breaking change where the library Assets feature introduced in Uno Platform 4.6 required assembly names to be lowercase. If you had an asset in a nuget package or project named "MyProject", you previously had to write `ms-appx:///myproject/MyAsset.txt`. With 4.7, you'll need to write `ms-appx:///MyProject/MyAsset.txt`. ## Uno Platform 4.6 ### Breaking change with Android 13 The introduction of Android 13 led to a breaking change, as some Android members exposed to .NET were removed. You'll need to migrate from `BaseActivity.PrepareOptionsPanel` to `BaseActivity.PreparePanel` instead. ## Uno Platform 4.5 ### ElevatedView The built-in `ElevatedView` control has undergone a visual unification, which means existing apps may experience slightly different shadow visuals, especially on Android, which now supports the full range of colors, including opacity. If you encounter visual discrepancies, please tweak the `Elevation` and `ShadowColor` properties to fit your needs. ## Uno Platform 4.1 ### Android 12 support Uno 4.1 removes the support for the Android SDK 10 and adds support for Android 12. Note that Android 10 versions and below are still supported at runtime, but you'll need Android 11 SDK or later to build an Uno Platform App. You can upgrade to Android 11 or 12 using the `Compile using Android version: (Target Framework)` option in Visual Studio Android project properties. Additionally, here are some specific hints about the migration to Android 12: - If you are building with Android 12 on Azure Devops Hosted Agents (macOS or Windows), you'll need two updates: - Use the JDK 11, using the following step: ```yml - pwsh: | echo "##vso[task.setvariable variable=JAVA_HOME]$(JAVA_HOME_11_X64)" echo "##vso[task.setvariable variable=JavaSdkDirectory]$(JAVA_HOME_11_X64)" displayName: Select JDK 11 ``` - You may need to add the following property to your Android csproj: ```xml true ``` - The AndroidX libraries need to be at specific versions to avoid [an upstream android issue](https://learn.microsoft.com/answers/questions/650236/error-androidattrlstar-not-found-after-upgrading-n.html). The Uno Platform NuGet packages are using those versions automatically, but if you override those packages, make sure to avoid direct or indirect dependencies on `Xamarin.AndroidX.Core(>=1.7.0.1)`. For reference, [view this page](https://github.com/unoplatform/uno/blob/533c5316cbe7537bb2f4a542b46a52b96c75004a/build/Uno.WinUI.nuspec#L66-L69) to get the package versions used by Uno Platform. ## Uno Platform 4.0 Uno 4.0 introduces a set of binary and source-breaking changes required to align with the Windows App SDK 1.0. To migrate your application to Uno 4.0: - Update all `Uno.UI.*` nuget packages to 4.0 - Add a package reference to `Uno.UI.Adapter.Microsoft.Extensions.Logging` to all your project heads (Except `.Desktop` for WinUI projects and `.Windows` for UWP projects) - In your `ConfigureLogging` method, add the following block at the end: ```csharp #if HAS_UNO global::Uno.UI.Adapter.Microsoft.Extensions.Logging.LoggingAdapter.Initialize(); #endif ``` - If you are using `ApiInformation.NotImplementedLogLevel`, use the following code instead: ```csharp global::Uno.UI.FeatureConfiguration.ApiInformation.NotImplementedLogLevel = global::Uno.Foundation.Logging.LogLevel.Debug; // Raise not implemented usages as Debug messages ``` - Many other smaller breaking changes that may have previously forced `#if HAS_UNO` conditionals, such as: - `FrameworkElement.DataContextChanged` signature - `FrameworkElement.Loading` signature - `Popup` is now correctly in the `Primitives` namespace - `FlyoutBase` event signatures - Uno.UI packages no longer depend on `Uno.Core`. If you did depend on types or extensions provided by this package, you can take a direct dependency on it or use one of the sub-packages created to limit the number of transitive dependencies. - The `Uno.UI.DualScreen` package is now renamed as`Uno.UI.Foldable` ## Uno Platform 3.6 ### Optional upgrade for Microsoft.Extension.Logging Uno Platform 3.6 templates provide an updated version of the loggers to allow the use of updated `Microsoft.Extension.Logging.*` logging packages. It is not required for applications to upgrade to these newer loggers, yet those provide additional features, particularly for iOS and WebAssembly. Here's how to upgrade: - For all projects: - Remove references to the `Microsoft.Extensions.Logging.Filter` package - Add a reference to the `Microsoft.Extensions.Logging` package version **5.0.0** - Upgrade the `Microsoft.Extensions.Logging.Console` package to version **5.0.0** - For UWP: - Change the reference from `Microsoft.Extensions.Logging.Console` to `Microsoft.Extensions.Logging.Debug` - For WebAssembly: - Add the following line to the `LinkerConfig.xaml` file: ```xml ``` - Add a reference to `Uno.Extensions.Logging.WebAssembly.Console` version **1.0.1** - For iOS: - Add a reference to `Uno.Extensions.Logging.OSLog` version **1.0.1** - In the `App.xaml.cs` file: - Replace the `ConfigureFilters()` method with the following: ```csharp /// /// Configures global Uno Platform logging /// private static void InitializeLogging() { var factory = LoggerFactory.Create(builder => { #if __WASM__ builder.AddProvider(new global::Uno.Extensions.Logging.WebAssembly.WebAssemblyConsoleLoggerProvider()); #elif __IOS__ || __TVOS__ builder.AddProvider(new global::Uno.Extensions.Logging.OSLogLoggerProvider()); #elif NETFX_CORE builder.AddDebug(); #else builder.AddConsole(); #endif // Exclude logs below this level builder.SetMinimumLevel(LogLevel.Information); // Default filters for Uno Platform namespaces builder.AddFilter("Uno", LogLevel.Warning); builder.AddFilter("Windows", LogLevel.Warning); builder.AddFilter("Microsoft", LogLevel.Warning); // Generic Xaml events // builder.AddFilter("Windows.UI.Xaml", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.VisualStateGroup", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.StateTriggerBase", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.UIElement", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.FrameworkElement", LogLevel.Trace ); // Layouter specific messages // builder.AddFilter("Windows.UI.Xaml.Controls", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.Controls.Layouter", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.Controls.Panel", LogLevel.Debug ); // builder.AddFilter("Windows.Storage", LogLevel.Debug ); // Binding related messages // builder.AddFilter("Windows.UI.Xaml.Data", LogLevel.Debug ); // builder.AddFilter("Windows.UI.Xaml.Data", LogLevel.Debug ); // Binder memory references tracking // builder.AddFilter("Uno.UI.DataBinding.BinderReferenceHolder", LogLevel.Debug ); // RemoteControl and HotReload related // builder.AddFilter("Uno.UI.RemoteControl", LogLevel.Information); // Debug JS interop // builder.AddFilter("Uno.Foundation.WebAssemblyRuntime", LogLevel.Debug ); }); global::Uno.Extensions.LogExtensionPoint.AmbientLoggerFactory = factory; } ``` - In the constructor, remove this call: ```csharp ConfigureFilters(global::Uno.Extensions.LogExtensionPoint.AmbientLoggerFactory); ``` and replace it with: ```csharp InitializeLogging(); ``` Note that there are two new loggers: - `Uno.Extensions.Logging.OSLog` which provides the ability to log the iOS system logs - `Uno.Extensions.Logging.WebAssembly.Console` which provides thread-safe and colored logging to the browser debugger console #### Migrating WebAssembly projects to .NET 5 If your WebAssembly project is using the `netstandard2.0` TargetFramework, migrating to `net5.0` can be done as follows: - Change `netstandard2.0` to `net5.0` - Upgrade `Uno.Wasm.Bootstrap` and `Uno.Wasm.Bootstrap.DevServer` to `2.0.0` or later - Add a reference to the `Microsoft.Windows.Compatibility` package to `5.0.1` You may also want to apply the changes from the section above (logger updates) to benefit from the update to .NET 5. ### Uno Platform 2.x to Uno 3.0 Migrating from Uno 2.x to Uno 3.0 requires a small set of changes in the code and configuration. - **Android 8.0** is not supported anymore. You'll need to update to **Android 9.0** or **10.0**. - For Android, you'll need to update the `Main.cs` file from: ```csharp : base(new App(), javaReference, transfer) ``` to ```csharp : base(() => new App(), javaReference, transfer) ``` - For WebAssembly, in the `YourProject.Wasm.csproj`: - Change `` to `` - Remove `true` - You can remove `__WASM__` in `DefineConstants` - The symbols font has been updated, and the name needs to be updated. For more information, see [this article](uno-fluent-assets.md). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-from-xamarin-to-net6.md --- uid: Uno.Development.MigratingFromXamarinToNet6 --- # How to upgrade from Xamarin to .NET 7 There are two ways to migrate an application to .NET 7. ## The forward looking path using the WinUI/WinApp SDK APIs 1. In a separate folder, create a new application from the templates using [`dotnet new unoapp -o MyApp`](xref:Uno.GetStarted.dotnet-new) (MyApp being of the same name as your existing app), or by using the Visual Studio `Uno Platform App` template 2. Move the `MyApp.Mobile` project folder and include it in your existing solution 3. Make the adjustments to move from the [UWP APIs to the WinUI APIs](xref:Uno.Development.UpdatingToWinUI3) 4. Optionally [convert your legacy Xamarin heads](xref:Uno.Development.UpdatingToWinUI3) to use Uno.WinUI instead of Uno.UI ## Additional considerations Since .NET 7 breaks binary compatibility with Xamarin, most of the existing nuget packages that target `monoandroidXX`, `xamarinios10` and `xamarinmac20` (bindings to native SDKs are a good example) will not work properly and will need an updated version that are compatible with `net7.0-ios`, `net7.0-android`, and `net7.0-maccatalyst`. ## Xamarin Support Policy As defined by [Microsoft support policy](https://dotnet.microsoft.com/platform/support/policy/xamarin) for Xamarin (as of 2022-08-25): > _Xamarin support will end on May 1, 2024 for all Xamarin SDKs. Android 13 and Xcode 14 SDKs (iOS and iPadOS 16, macOS 13) will be the final versions Xamarin will target._ Uno Platform is going provides support for Xamarin (`monoandroid12`, `monoandroid13`, `xamarinios10` and `xamarinmac20`) by that date as well in the Uno 4.x releases. Uno 5.0 and later does not support Xamarin anymore. Note that later on, apps built with these SDK will not be accepted by both [Apple](https://developer.apple.com/support/xcode/) and [Google](https://developer.android.com/google/play/requirements/target-sdk) stores. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-guidance.md --- uid: Uno.Development.MigratingGuidance --- # General guidance for making WinUI/UWP-only code Uno compatible This article explains adjustments that may need to be made to WinUI/UWP-only code for it to run on Uno Platform, be it in an application or a class library. ## Code adjustments ### Add 'partial' to some class definitions Certain class definitions will need to have the [`partial` keyword](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/partial-type) added. This is because Uno [generates additional code at compile-time](./uno-development/uno-internals-overview.md#dependencyobject-implementation-generator) to support them properly. You'll need to do this for: - types that inherit from `FrameworkElement`, directly or indirectly - types that inherit directly from `DependencyObject` Apart from adding `partial`, you don't need to worry about the generated code. You may however get misleading errors from Intellisense until the first time you try to compile the project, because the generated partial classes haven't been added yet. ### Avoid nested classes that inherit from FrameworkElement Classes that inherit from `FrameworkElement` directly or indirectly can't be nested inside another class; it's been observed to cause problems on Xamarin.iOS. If you have any nested `FrameworkElement`-derived classes, you'll need to refactor them to be top-level classes. ### Disambiguate naming collisions with native properties This is relevant if you're targeting Android, iOS, and/or macOS, where Uno views (hence, `FrameworkElement`) [inherit from the native view type](native-views.md). In some cases you may find that a reference to a type from the UWP framework is confused with a native property. The fix in this case is generally to disambiguate by supplying the full namespace of the type. Some common cases: - on iOS, inside a control definition, references to [`Window.Current`](https://learn.microsoft.com/uwp/api/windows.ui.xaml.window.current) will be confused with the [`UIView.Window`](https://learn.microsoft.com/dotnet/api/uikit.uiview.window) property. The fix is to fully qualify this as `Windows.UI.Xaml.Current`. - on Android, inside a control definition, references to the [`TextAlignment` enum](https://learn.microsoft.com/uwp/api/windows.ui.xaml.textalignment) will be confused with the [`View.TextAlignment` property](https://learn.microsoft.com/dotnet/api/android.views.view.textalignment). The fix, again, is to fully qualify the reference as `Windows.UI.Xaml.TextAlignment`. #### What do I do if I have a nested namespace with `Windows` in it? If, for example, your control is defined in the `CoolControls` namespace, and you've also defined a `CoolControls.Windows` namespace, then the above will give a compilation error. You'll need to use the [`global` keyword](https://learn.microsoft.com/dotnet/csharp/language-reference/operators/namespace-alias-qualifier), eg `global::Windows.UI.Xaml.Window.Current`. ## Adjust for unsupported runtime features Not all .NET runtime features are supported on every platform. See [Migrating - Before You Start](migrating-before-you-start.md) for more details. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-libraries.md --- uid: Uno.Development.MigratingLibraries --- # Migrating a WinUI or UWP class library to an Uno Platform class library This article describes how to port a class library for UWP to one that supports multiple target platforms using Uno. It assumes you're using Visual Studio for Windows, but the steps are similar if you're using VS Code or another IDE. ## Prerequisites Follow the instructions to [set up your development environment for Uno Platform](get-started.md). ## Applying Uno Platform project structure Adding Uno Platform support to an existing class library entails changing the contents of the existing `.csproj` file. The easiest way to do that is to create a temporary Uno class library and copy its contents into the existing `.csproj` file. The steps in detail: 1. Open the solution containing the WinUI/UWP-only library you wish to convert. 2. Create an **Uno Platform Library** project in the same solution, and name it `TempUno`. 3. Let's say we want to convert a library called 'CoolControls'. Right-click on the `CoolControls` project, and choose **Unload Project**. 4. Right-click again on `CoolControls`, and choose **Edit CoolControls.csproj**. 5. Right-click on `TempUno`, then **Edit TempUno.csproj**. _(There is no need to unload this type of project)_ 6. Make a temporary copy of the contents of `CoolControls.csproj` (eg in a Notepad window) - you will refer to this when restoring dependencies. 7. Copy the entire contents of `TempUno.csproj` and paste them into `CoolControls.csproj`, overwriting the old contents. 8. Delete the `TempUno` project from your solution. 9. Right-click on `CoolControls`, then choose **Reload Project**. 10. In the **Properties** folder of `CoolControls`, you'll need to remove the `AssemblyVersion` and similar properties as those are now generated by [msbuild using AssemblyInfo properties](https://learn.microsoft.com/dotnet/core/tools/csproj#assemblyinfo-properties). ## Adding dependencies If your class library had additional dependencies, you will need to restore them. See [Migrating - Before You Start](migrating-before-you-start.md) for tips on finding compatible dependency versions for each target. See the [working with Control libraries article](xref:Guide.HowTo.Create-Control-Library) for how to add dependencies to your project. ## Adjusting code for Uno compatibility [See the next section](migrating-guidance.md) for adjustments you may need to make to get your code compiling on Uno. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-to-single-project.md --- uid: Uno.Development.MigratingToSingleProject --- # Migrating Projects to Single Project The Uno Platform 5.2 and later use the [Uno.Sdk](https://www.nuget.org/packages/uno.sdk) which provides a single Uno Project structure and a single location for updating the Uno Platform core packages version in `global.json`. > [!IMPORTANT] > Migrating to the Uno.Sdk and Single Project are not required. Existing projects, 5.1 and earlier, continue to be supported in Uno Platform 5.2 or later. With Uno Platform Single Project, you can optimize your project structure and simplify maintenance while leveraging the power of Uno Platform for cross-platform app development. This guide provides step-by-step instructions and practical tips to ensure a smooth migration process. Let's get started! ## What is the Uno.Sdk The Uno.Sdk is used to abstract the complexity needed to build cross-platform projects, while still ensuring that you have the ability to customize the configuration to your needs. This means that values such as the `SupportedOSPlatformVersion`, which have been in the template's `Directory.Build.props` in previous Uno Platform templates, now have a default value set to the minimum supported by Uno Platform. If you need to be more restrictive for your specific project you can provide your overrides for the platform(s) that you need. ## Project Structure In the Uno Platform Single Project, all platform-specific code is put together in one project. Instead of having separate projects for each platform, everything is organized within a `Platforms` folder. This folder contains sub-folders for each platform your project targets, like Android, iOS, Skia, WebAssembly, and Windows. Each platform folder stores the code and resources needed for that platform, making development easier to manage for multi-platform projects. ## Upgrading an existing project to Single Project The following sections detail how to upgrade an existing project to use a single project with the Uno.Sdk. Those modifications are made in place and **it is strongly recommended to work on a source-controlled environment**. While following this guide, you can compare with a new empty project created using [our Wizard](xref:Uno.GetStarted.Wizard), or using [dotnet new templates](xref:Uno.GetStarted.dotnet-new). ### Migrating to a Single Project Migrating from a 5.1 or earlier template is a matter of merging all the csproj files for all the platforms heads down to one csproj file. We'll take the example of an Uno Platform 5.0 blank app, called `MyApp`, to migrate to Single Project : 1. In a separate folder from your existing app, create a new app using the same name as your app: ```bash dotnet new unoapp -o MyApp --preset=recommended ``` This will allow for taking pieces of the structure with the proper namespaces. If your app was created using the blank template, use `--preset=blank` instead. You can also use the [Live Wizard](xref:Uno.GetStarted.dotnet-new) or the [Visual Studio Wizard](xref:Uno.GettingStarted.CreateAnApp.VS2022) and select the same optional features you used for your app. 1. Next to the solution, create a `global.json` file ```json { "msbuild-sdks": { "Uno.Sdk": "{Current Version of Uno.WinUI/Uno.Sdk}" } } ``` 1. From the empty app created at step one: - Take the contents of the `MyApp.csproj` and copy it over your own `MyApp.csproj` - Take the folder named `Properties` and copy it over your own `MyApp` 1. If you have your own `PackageReference` and `ProjectReference`, make sure to preserve them. 1. From the empty app created at step one, take the `Platforms` folder and copy it over your own `MyApp` folder. 1. In you app's `MyApp.csproj`, create the following block: ```xml ``` This will allow us to place custom project configurations in each of those sections. Use the ones that are relevant to your project targets. 1. From the empty app created at step one, take the `App.xaml` and `App.xaml.cs` and copy those over your own `MyApp` folder. 1. Copy the individual modifications you made to your `AppResources.xaml` and `App.cs` into `App.xaml` and `App.xaml.cs`, respectively. Those can, for instance, be changes made to `OnLaunched`, `InitializeLogging`, or `RegisterRoutes`. 1. For the WebAssembly project, most of the configuration is now included by the `Uno.Sdk`. You can: 1. Move all the files from your `MyApp.Wasm` folder to the `Platforms/WebAssembly` folder, except `MyApp.Wasm.csproj` and the `Properties` folder. 1. Copy the individual configurations, `ProjectReference` and `PackageReference` entries from your `MyApp.Wasm.csproj` to your `MyApp.csproj`, into the appropriate `When` condition block we created above. This can include properties like `WasmShellGenerateAOTProfile` or `WasmShellMonoRuntimeExecutionMode`, depending on your choices. 1. Delete the `MyApp.Wasm` folder 1. For the Mobile project, you can: 1. In your app, move the folders `MyApp.Mobile/Android`, `MyApp.Mobile/iOS` to the `MyApp/Platforms`. 1. Copy the individual configurations, `ProjectReference` and `PackageReference` entries from your `MyApp.Mobile.csproj` to your `MyApp.csproj`, into the appropriate `When` condition block we created above. This can include properties like `ApplicationTitle` or `ApplicationId`, depending on your choices. 1. Delete the `MyApp.Mobile` folder 1. For the Skia.Gtk, Skia.Wpf and Skia.Framebuffer projects, you can: 1. Copy individual modifications made to the `Program.cs` of each platform over to `Platforms/Desktop/Program.cs` 1. Copy the individual configurations, `ProjectReference` and `PackageReference` entries from your `MyApp.Skia.[Gtk|Wpf|Framebuffer].csproj` to your `MyApp.csproj`, into the appropriate `When` condition block we created above. 1. You can also copy the individual modifications made to `app.manifest` and `Package.manifest` to `MyApp`. Those two files are now shared across platforms. 1. Delete the `MyApp.Skia.[Gtk|Wpf|Framebuffer]` folders 1. For the `MyApp.Windows` project, you can: 1. Copy the individual configurations, `ProjectReference` and `PackageReference` entries from your `MyApp.Windows.csproj` to your `MyApp.csproj`, into the appropriate `When` condition block we created above. 1. You can copy the individual modifications made to `app.manifest` and `Package.manifest` to `MyApp`. Those two files are now shared across platforms. 1. For the `MyApp.[Shared|Base]` project, you can: 1. Move the `Icons` and `Splash` folders to the `MyApp/Assets` 1. If you've made modifications to the `base.props` file, you can copy those over to the `MyApp.csproj`, outside the `Choose` section. 1. If you've made individual changes to the `AppHead.xaml` file, copy those over to the `App.xaml` file 1. If you've made individual changes to the `AppHead.xaml.cs` file, copy those over to the `App.xaml.cs` file 1. Delete the `MyApp.[Shared|Base]` folder 1. In All the `.cs` files, replace `AppHead` with `App` 1. Once done, you can remove the `Platforms` folder from your solution explorer, as all other platform heads have been deleted. 1. If you have a `MyApp.Server` project, make sure to change from: ```xml ``` to ```xml ``` 1. From the empty app created at step one, take the `Directory.Build.props` and `Directory.Build.targets` files and copy those over your own root folder. Make sure to copy individual changes made in your file, such as `CSharpVersion` or `Nullable`. 1. From the empty app created at step one, take the `Directory.Packages.props`file and copy it over to your own root folder. All of the NuGet packages can be removed from this file, as the Uno.SDK provides those automatically. 1. In all the projects files, replace `$(DotnetVersion)` with `net9.0` 1. Remove the `solution-config.props.sample` file. This part is now handled by Uno Platform automatically. At this point, your solution can be compiled using a single project and Uno Platform 5.2. For a guide through using the new single project, head over to [our getting started](xref:Uno.GetStarted). ## Wrapping up Now that your project has gotten simplified, you can head over to our [Uno.Sdk](xref:Uno.Features.Uno.Sdk) documentation to explore its features. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-to-uno-5.md --- uid: Uno.Development.MigratingToUno5 --- # Migrating to Uno Platform 5.0 Uno Platform 5.0 contains binary-breaking changes in order to further align our API surface with the Windows App SDK. Most of these changes are binary-breaking changes but do not introduce behavior changes. You can find a list of these changes below. Additionally, this version: - Adds support for .NET 8 for iOS, Android, Mac Catalyst, and macOS. [Follow this guide](xref:Uno.Development.MigratingFromNet7ToNet8) to upgrade from .NET 7 to .NET 8. - Removes the support for Xamarin.iOS, Xamarin.Android, Xamarin.Mac, .NET 6 (iOS/Android/Catalyst), and netstandard2.0 for WebAssembly. - .NET 7.0 support for iOS, Android, Mac Catalyst, and macOS remains unchanged. - Updates the base Windows SDK version from 18362 to 19041. Uno Platform 5.0 continues to support both UWP ([Uno.UI](https://www.nuget.org/packages/uno.ui) and WinUI ([Uno.WinUI](https://www.nuget.org/packages/uno.winui)) API sets. ## List of common manual changes for Uno Platform 5.0 ### Xaml generator now always uses strict search This change ensures that the XAML parser will only look for types in an explicit way, and avoids fuzzy matching that could lead to incorrect type resolution. In order to resolve types properly in a conditional XAML namespace, make use of the [new syntax introduced in Uno 4.8](https://platform.uno/docs/articles/platform-specific-xaml.html?q=condition#specifying-namespaces). ### Enabling Hot Reload Hot Reload support has changed in Uno Platform 5.0 and a new API invocation is needed to restore the feature in your existing app. - If your project is built using a shared class library, you'll need to add the following lines to the `csproj`: ```xml ``` > [!NOTE] > If your application is using the UWP API set (Uno.UI packages) you'll need to use the `Uno.UI.DevServer` package instead. - Then, in your `App.cs` file, add the following: ```csharp using Uno.UI; //... in the OnLaunched method #if DEBUG MainWindow.UseStudio(); #endif ``` Note that Hot Reload has changed to be based on C#, which means that changes done XAML files will need the use of C# Hot Reload feature to be applied to the running app. See [this documentation](xref:Uno.Features.HotReload) for more details. ### Migrating from Xamarin to net7.0-* targets If your current project is built on Xamarin.* targets, you can upgrade by [following this guide](xref:Uno.Development.MigratingFromXamarinToNet6). ### Migrating from net6.0-*to net7.0-* There are no significant changes needed to upgrade to .NET 7 for applications (iOS, Android, Catalyst), aside from replacing all occurrences of `net6.0` to `net7.0` or `net8.0` in all your `csproj` files. For libraries that are depending on `net6.0-android/ios/maccatalyst`, depending on the impact of the breaking changes listed below, you will need to build your libraries with Uno Platform 5.0 packages, as well as target `net7.0-*` or `net8.0-*`. ### Migrating WebAssembly from `netstandard2.0` to `net7.0` or `net8.0` Migrating from `netstandard2.0` WebAssembly apps to `net7.0` or `net8.0` requires: - Replacing all occurrences of `netstandard2.0` to `net7.0` or `net8.0` in all your `csproj` files - Upgrading `Uno.Wasm.Bootstrap*` packages to version `7.0.x` or `8.0.x`, depending on your chosen target framework. ### Migrating to the new `WpfHost` The `WpfHost` was previously hosted within a WPF `Window` class, but now it takes care of creating individual windows on its own. To migrate, follow these steps: - Remove the `StartupUri="Wpf/MainWindow.xaml"` attribute from `App.xaml` - Delete both `MainWindow.xaml` and `MainWindow.xaml.cs` - In `App.xaml.cs` add the following constructor: ```csharp public App() { var host = new WpfHost(Dispatcher, () => new AppHead()); host.Run(); } ``` ### Migrating `ApplicationData` on Skia targets Previously, `ApplicationData` was stored directly in `Environment.SpecialFolder.LocalApplicationData` folder, and all Uno Platform apps shared this single location. Starting with Uno Platform 5.0, application data are stored in application-specific folders under the `LocalApplicationData` root. For more details see the [docs](features/applicationdata.md). To perform the initial migration of existing data you need to make sure to copy the files from the root of the `LocalApplicationData` folder to `ApplicationData.Current.LocalFolder` manually using `System.IO`. ### Updating the Windows SDK from 18362 to 19041 If your existing libraries or UWP/WinAppSDK projects are targeting the Windows SDK 18362, you'll need to upgrade to 19041. A simple way of doing so is to replace all occurrences of `18362` to `19041` in all your solution's `csproj`, `.targets`, `.props`, and `.wapproj` files. ### The Uno.[UI|WinUI].RemoteControl package is deprecated The `Uno.[UI|WinUI].RemoteControl` is deprecated and should be replaced by `Uno.WinUI.DevServer` (or `Uno.WinUI.DevServer` if you're using UWP). This is not a required change, as the package `Uno.[UI|WinUI].RemoteControl` transitively uses `Uno.WinUI.DevServer`, but the package will eventually be phased out. ## List of other breaking changes ### `ShouldWriteErrorOnInvalidXaml` now defaults to true Invalid XAML, such as unknown properties or unknown x:Bind targets will generate a compiler error. Those errors must now be fixed as they are no longer ignored. ### ResourceDictionary now requires an explicit Uri reference Resources dictionaries are now required to be explicitly referenced by URI to be considered during resource resolution. Applications that are already running properly on WinAppSDK should not be impacted by this change. The reason for this change is the alignment of the inclusion behavior with WinUI, which does not automatically place dictionaries as ambiently available. This behavior can be disabled by using `FeatureConfiguration.ResourceDictionary.IncludeUnreferencedDictionaries`, by setting the value `true`. ### `IsEnabled` property is moved from `FrameworkElement` to `Control` This property was incorrectly located on `FrameworkElement` but its behavior has not changed. ### `RegisterLoadActions` has been removed This method has been removed as it is not available in WinUI. You can migrate code using this method to use the `FrameworkElement.Loaded` event instead. ### Move `SwipeControl`, `SwipeItem`, `SwipeItemInvokedEventArgs`, `SwipeMode`, `SwipeItems`, `SwipeBehaviorOnInvoked`, `MenuBar`, `MenuBarItem`, and `MenuBarItemFlyout` implementation from WUX namespace to MUX namespace These controls were present in both the `Windows.UI.Xaml` and `Microsoft.UI.Xaml`. Those are now located in the `Microsoft.UI.Xaml` namespace for the UWP version of Uno (Uno.UI). ### Move `AnimatedVisualPlayer`, `IAnimatedVisualSource`, and `IThemableAnimatedVisualSource` from WUX to MUX and `Microsoft.Toolkit.Uwp.UI.Lottie` namespace to `CommunityToolkit.WinUI.Lottie` This change moves the `AnimatedVisualPlayer` to the appropriate namespace for WinUI, aligned with the WinAppSDK version of the Windows Community Toolkit. ### `SimpleOrientationSensor` should not schedule on `Dispatcher` `SimpleOrientationSensor` on Android now raises events from a background thread and needs to be explicitly dispatched to the UI thread as needed. ### The following types are removed from public API: `DelegateCommand`, `DelegateCommand`, `IResourceService`, `IndexPath`, and `SizeConverter` These legacy classes have been removed. Use the [`CommunityToolkit.Mvvm`](https://learn.microsoft.com/dotnet/communitytoolkit/mvvm/) package instead. ### `SolidColorBrushHelper` isn't available in UWP, so we are making it internal This type is not present in WinUI, use `new SolidColorBrush(xxx)` instead. ### Application.OnWindowCreated does not exist in WinAppSDK The method has been removed. ### `DependencyObjectGenerator` no longer generated an empty ApplyCompiledBindings method These methods have been unused since Uno 3.0 and have been removed. ### `EasingFunctionBase` API is now aligned with WinUI The easing functions classes are now inheriting properly from `EasingFunctionBase`. ### Remove `ResourcesService` and `ResourceHelper` The legacy `ResourcesService` and `ResourceHelper` have been removed. ### Implicit conversion from string to `Point` is removed The implicit conversion has been removed but a conversion can be performed using the `XamlBindingHelper` class. ### Rename `CreateTheamableFromLottieAsset` to `CreateThemableFromLottieAsset` This change is a rename for an identifier typo. Renaming the invocation to the new name is enough. ### Timeline shouldn't implement IDisposable Timeline does not implement `IDisposable` anymore. This class was not supposed to be disposable and has been removed. ### `GridExtensions` and `PanelExtensions` are removed These legacy classes have been removed. ### `GetLeft`, `GetTop`, `SetLeft`, `SetTop`, `GetZIndex`, and `SetZIndex` overloads that take DependencyObject are now removed Those legacy overloads are now removed and the UIElement overloads should be used instead. ### BaseFragment is not needed and is now removed The legacy BaseFragment class has been removed. Use `Page` navigation instead. ### `ViewHelper.GetScreenSize` method on iOS/macOS is now internal Use the `DisplayInformation` class instead. ### `FrameworkElement` constructors are now protected instead of public Use the `Control` class instead. ### `ViewHelper.MainScreenScale` and `ViewHelper.IsRetinaDisplay` are removed in iOS and macOS Use the `DisplayInformation` class instead. ### WebView.NavigateWithHttpRequestMessage parameter type is now `Windows.Web.Http.HttpRequestMessage` instead of `System.Net.Http.HttpRequestMessage` Use the new types instead. ### `OnVerticalOffsetChanged` and `OnHorizontalOffsetChanged` are now private instead of virtual protected Use the related events instead. ### `FrameBufferHost` and `GtkHost` constructors that take `args` are now removed. `args` were already unused You can remove the last argument of the constructor invocation. The parameters are read by the host directly. ### `RegisterDefaultStyleForType` methods were removed This legacy method was deprecated in Uno 3.x ### Xaml code generator was generating an always-null-returning FindResource method. This method is no longer generated This legacy method was deprecated in Uno 3.x ### The type `Windows.Storage.Streams.InMemoryBuffer` is removed Use `Windows.Storage.Streams.Buffer` instead. ### `ContentPropertyAttribute.Name` is now a field to match UWP This change has no effect on Control's behavior. ### Remove `FontWeightExtensions` and `CssProviderExtensions` `Uno.UI.Runtime.Skia.GTK.UI.Text.FontWeightExtensions` and `Uno.UI.Runtime.Skia.GTK.Extensions.Helpers.CssProviderExtensions` don't exist in UWP/WinUI. So they are made internal. ### Change `GtkHost`, `WpfHost`, `FrameBufferHost` namespaces `GtkHost`, `WpfHost`, and `FrameBufferHost` are now `Uno.UI.Runtime.Skia.Gtk.GtkHost`, `Uno.UI.Runtime.Skia.Wpf.WpfHost`, and `Uno.UI.Runtime.Skia.Linux.FrameBuffer.FrameBufferHost` instead of `Uno.UI.Runtime.Skia.GtkHost`, `Uno.UI.Skia.Platform.WpfHost`, and `Uno.UI.Runtime.Skia.FrameBufferHost`, respectively. ### Change `RenderSurfaceType` namespace There used two be two `RenderSurfaceType`s, `Uno.UI.Runtime.Skia.RenderSurfaceType` (for Gtk) and `Uno.UI.Skia.RenderSurfaceType` (for Skia). They are now `Uno.UI.Runtime.Skia.Gtk.RenderSurfaceType` and `Uno.UI.Runtime.Skia.Wpf.RenderSurfaceType` respectively. ### `Panel`s no longer measure or arrange any children in `MeasureOverride` or `ArrangeOverride`, respectively `Panel`s used to measure and arrange the first child in `MeasureOverride` or `ArrangeOverride`, respectively. This is no longer the case. Now, to match WinUI, `Panel`s just return an empty size in `MeasureOverride`, and the `finalSize` as is in `ArrangeOverride`. You should override these layout-override methods in `Panel`-derived subclasses instead. ### Remove `Windows.UI.Xaml.Controls.NavigationView` in Uno.WinUI Uno.WinUI used to have NavigationView both in `Microsoft.UI.Xaml.Controls` and `Windows.UI.Xaml.Controls` namespaces. It's now removed from `Windows.UI.Xaml.Controls` and kept only in `Microsoft.UI.Xaml.Controls` namespace. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/migrating-to-uno-6.md --- uid: Uno.Development.MigratingToUno6 --- # Migrating to Uno Platform 6.0 Uno Platform 6.0 contains some breaking changes required to provide a consistent experience when using the Skia rendering feature, as well as **the removal of the UWP API set support** and the **removal of the GTK desktop runtime support**. You can find a list of these changes below. ## Removal of the UWP API Set Uno Platform started off with UWP as the common API set, then added WinUI/WinAppSDK. Both API sets were kept as a convenience for upgrading to WinUI, and now that WinUI is sufficiently advanced, Uno Platform 6.0 removes the UWP API set entirely. This makes Uno Platform easier to maintain in the long run and easier to contribute to. If you're still using the UWP API set, you can see our [migration guides on how to move to WinUI](xref:Uno.Development.UpdatingToWinUI3). ## Removal of Skia GTK Desktop support Over the years, we've provided desktop platform abstractions through different technologies. While desktop support started with a GTK3 shell as a common ground, Uno Platform 5.6 introduced [specialized shell support for X11, WPF, and AppKit](xref:Uno.Skia.Desktop). Now that the support for these targets is stable, we're removing the support for the GTK shell for projects that have not yet used the Uno.SDK. If your project is still using the GTK support, you can keep using Uno Platform 5.6, or [migrate to the Uno.SDK style project](https://platform.uno/docs/articles/migrating-from-previous-releases.html), which uses the latest platform support, including the new Win32 shell feature. ## List of common manual changes for Uno Platform 6.0 ### Updating the Desktop Builder Upgrading the Desktop platform builder is required when moving to Uno Platform 6.0, in order to align builders for all platforms, for all renderers. To upgrade, in your `Platforms/Desktop/Program.cs`: - Replace `using Uno.UI.Runtime.Skia;` with `using Uno.UI.Hosting;` - Replace `SkiaHostBuilder` with `UnoPlatformHostBuilder` ### Use the new Win32 desktop support Uno Platform 6.0 provides support for a new, faster, and leaner Windows support, which does not depend on additional libraries (like WPF in previous Uno Platform versions). This new support also enables IL, XAML, and Resource Trimming for smaller published app packages. To upgrade to the Win32 support, in your `Platforms/Desktop/Program.cs`, replace `.UseWindows()` with `.UseWin32()`. ### WinAppSDK 1.7 considerations Uno Platform 6 updates to WinAppSDK 1.7 when using the [`Uno.SDK`](xref:Uno.Features.Uno.Sdk). If you encounter the following build error: ```output error CS1705: Assembly 'Assembly_Name' with identity 'Assembly_Name, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null' uses 'WinRT.Runtime, Version=2.2.0.0, Culture=neutral, PublicKeyToken=99ea127f02d97709' which has a higher version than referenced assembly 'WinRT.Runtime' with identity 'WinRT.Runtime, Version=2.1.0.0, Culture=neutral, PublicKeyToken=99ea127f02d97709' ``` This may be due to a mismatch in the Windows SDK version used by your project. To fix this issue, add the following to your `.csproj` file to ensure the correct Windows SDK is referenced for the `net9.0-windowsXX` target to build properly: ```xml 10.0.19041.57 ``` ### Uno Extensions Uno Platform 6.0 introduces a breaking change to the `Http` Uno Feature: - The existing `Http` feature still exists, but no longer includes the `Uno.Extensions.Http.Refit` package by default. - Two new features have been added: - **HttpRefit** – Configures `Uno.Extensions.Http.Refit` so you can register and consume REST APIs using Refit’s type-safe client generation. - **HttpKiota** – Configures `Uno.Extensions.Http.Kiota` so you can register and consume OpenAPI-defined endpoints using Kiota’s HTTP client generator. > [!NOTE] > If you’re upgrading and previously relied on Refit from the `Http` feature, remove `Http` from your `` and add `HttpRefit` instead. See the [HTTP overview](xref:Uno.Extensions.Http.Overview) for more information. ### Optional use of Skia Rendering for iOS, Android, and WebAssembly In order to use Skia Rendering for these targets, we're adding new APIs that make the bootstrapping of iOS and WebAssembly platforms using common builders. To upgrade: - Make sure that your project is using the Uno.SDK. - In your `.csproj`, add the following to enable Skia rendering: ```diff + SkiaRenderer; ``` - In your `Platforms/WebAssembly/Program.cs` change this: ```csharp public static int Main(string[] args) { // code omitted for brevity Microsoft.UI.Xaml.Application.Start(_ => _app = new App()); return 0; } ``` with the following: ```csharp using Uno.UI.Hosting; ... public static async Task Main(string[] args) { // code omitted for brevity var host = UnoPlatformHostBuilder.Create() .App(() => new App()) .UseWebAssembly() .Build(); await host.RunAsync(); } ``` If your startup code contained a static `_app` field, you can remove it as well. You can also use the top-level program code, as found in the default Uno Platform templates. > [!NOTE] > Removing `SkiaRenderer` from `UnoFeatures` inside the project's `.csproj` file to target native rendering, then setting it back after a new build will raise a runtime Exception. You will need to remove `bin` and `obj` folders, and clear site data of the browser app in order to avoid encountering this exception. - In your `Platforms/iOS/Main.iOS.cs` change the following: ```csharp using UIKit; ... public static void Main(string[] args) { UIApplication.Main(args, null, typeof(App)); } ``` with the following: ```csharp using Uno.UI.Hosting; ... public static void Main(string[] args) { // code omitted for brevity var host = UnoPlatformHostBuilder.Create() .App(() => new App()) .UseAppleUIKit() .Build(); host.Run(); } ``` You can also use the top-level program code, as found in the default Uno Platform templates. - In your `Platforms/Android/Main.Android.cs`, change the following: ```diff public Application(IntPtr javaReference, JniHandleOwnership transfer) : base(() => new App(), javaReference, transfer) { - ConfigureUniversalImageLoader(); } -private static void ConfigureUniversalImageLoader() -{ - var config = new ImageLoaderConfiguration.Builder(Context).Build(); - ImageLoader.Instance.Init(config); - ImageSource.DefaultImageLoader = ImageLoader.Instance.LoadImageAsync; -} ``` Uno Platform handles image loading entirely with the Skia Rendering mode. - If you had platform specific modifications to your `UIApplicationDelegate` in App.xaml.cs, [some modifications](xref:Uno.Features.CustomizingUIApplicationDelegate) are needed to upgrade. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/native-frame-nav-tutorial.md --- uid: Uno.Tutorials.UseNativeFrameNav --- # How to use native Frame navigation ## Example The complete sample code can be found in [NativeFrameNav on Uno.Samples GitHub repository](https://github.com/unoplatform/Uno.Samples/tree/master/UI/NativeFrameNav). ## Step-by-step instructions 1. Create a new Uno Platform application, following the instructions in [Get Started guide](../get-started.md). 2. Add two more pages (`BlankPage1` and `BlankPage2`) to the `Your_Project_Name` project Right-click on the `Your_Project_Name` project -> `Add` -> `New Item...` -> `Page (Uno Platform Windows App SDK)` Repeat once 3. Modify the content of `MainPage.xaml`, `BlankPage1.xaml`, and `BlankPage2.xaml` pages to the following: ```xml ``` Put a different text for each page: "MainPage", "Content 1", "Content 2". > [!NOTE] > Add `xmlns:toolkit="using:Uno.UI.Toolkit"` to the `` element. 4. Add a button for forward navigation in the first two pages: - `MainPage.xaml` and `BlankPage1.xaml`: ```xml ``` ## Step 4 - Prepare the Requesting Code Add the following code to the main page of your application: ```csharp //add this namespace on top of the class using IdentityModel.OidcClient; // Put this code in the class of MainPage.xaml.cs private OidcClient _oidcClient; private AuthorizeState _loginState; private Uri _logoutUrl; public MainPage() { this.InitializeComponent(); PrepareClient(); } private async void PrepareClient() { var redirectUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().OriginalString; // Create options for endpoint discovery var options = new OidcClientOptions { Authority = "https://demo.duendesoftware.com/", ClientId = "interactive.confidential", ClientSecret = "secret", Scope = "openid profile email api offline_access", RedirectUri = redirectUri, PostLogoutRedirectUri = redirectUri, }; // Create the client. In production application, this is often created and stored // directly in the Application class. _oidcClient = new OidcClient(options); // Invoke Discovery and prepare a request state, containing the nonce. // This is done here to ensure the discovery mechanism is done before // the user clicks on the SignIn button. Since the opening of a web window // should be done during the handling of a user interaction (here it's the button click), // it will be too late to reach the discovery endpoint. // Not doing this could trigger popup blocker mechanisms in browsers. _loginState = await _oidcClient.PrepareLoginAsync(); btnSignin.IsEnabled = true; // Same for logout url. _logoutUrl = new Uri(await _oidcClient.PrepareLogoutAsync(new LogoutRequest())); btnSignout.IsEnabled = true; } ``` ## Step 5 - Proceed to Authentication Add following button handlers: ```csharp private async void SignIn_Clicked(object sender, RoutedEventArgs e) { var startUri = new Uri(_loginState.StartUrl); // Important: there should be NO await before calling .AuthenticateAsync() - at least // on WebAssembly, in order to prevent triggering the popup blocker mechanisms. var userResult = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, startUri); if (userResult.ResponseStatus != WebAuthenticationStatus.Success) { txtAuthResult.Text = "Canceled"; // Error or user cancellation return; } // User authentication process completed successfully. // Now we need to get authorization tokens from the response var authenticationResult = await _oidcClient.ProcessResponseAsync(userResult.ResponseData, _loginState); if (authenticationResult.IsError) { var errorMessage = authenticationResult.Error; // TODO: do something with error message txtAuthResult.Text = $"Error {errorMessage}"; return; } // That's completed. Here you have to token, ready to do something var token = authenticationResult.AccessToken; var refreshToken = authenticationResult.RefreshToken; // TODO: make something useful with the tokens txtAuthResult.Text = $"Success, token is {token}"; } private async void SignOut_Clicked(object sender, RoutedEventArgs e) { // Important: there should be NO await before calling .AuthenticateAsync() - at least // on WebAssembly, in order to prevent triggering the popup blocker mechanisms. await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, _logoutUrl); } ``` ## Step 6 - Finalize & Compile > [!IMPORTANT] > On WebAssembly, it's important to configure the linker to prevent the removal of some important part of the *OIDC Connect* client library: > `LinkerConfig.xml`: > > ```xml > > > > > > > > > > > > > > > > ``` Now compile & Run! --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/orientation-sensor.md --- uid: Uno.Features.OrientationSensor --- # Orientation sensor > [!TIP] > This article covers Uno-specific information for SimpleOrientationSensor. For a full description of the feature and instructions on using it, see [SimpleOrientationSensor Class](https://learn.microsoft.com/uwp/api/windows.devices.sensors.simpleorientationsensor). * The `Windows.Devices.Sensors.SimpleOrientationSensor` class allows you to determine the general orientation of the device. ## Supported features | Feature | Windows | Android | iOS | Web (WASM) | macOS | Linux (Skia) | Win 7 (Skia) | |----------------------|---------|---------|-----|------------|-------|--------------|--------------| | `GetDefault` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | `OrientationChanged` | ✔ | ✔ | ✔ | ✔ | ✖ | ✖ | ✖ | > [!IMPORTANT] > The `OrientationChanged` event is not supported by iOS simulators. ## Using SimpleOrientationSensor with Uno * The `GetDefault` method is available on all targets and will return `null` on those that do not support `SimpleOrientationSensor` or devices that do not have such a sensor. * Ensure to unsubscribe from the `OrientationChanged` event when you no longer need the readings so that the sensor is no longer active to avoid unnecessary battery consumption. ## Example ### Capturing sensor readings ```csharp var simpleOrientationSensor = SimpleOrientationSensor.GetDefault(); simpleOrientationSensor.OrientationChanged += SimpleOrientationSensor_OrientationChanged; private async void SimpleOrientationSensor_OrientationChanged(object sender, SimpleOrientationSensorOrientationChangedEventArgs args) { // If you want to update the UI in some way, ensure the Dispatcher is used, // as the OrientationChanged event handler does not run on the UI thread. await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { switch (orientation) { case SimpleOrientation.NotRotated: tb.Text = "Not Rotated"; break; case SimpleOrientation.Rotated90DegreesCounterclockwise: tb.Text = "Rotated 90 Degrees Counterclockwise"; break; case SimpleOrientation.Rotated180DegreesCounterclockwise: tb.Text = "Rotated 180 Degrees Counterclockwise"; break; case SimpleOrientation.Rotated270DegreesCounterclockwise: tb.Text = "Rotated 270 Degrees Counterclockwise"; break; case SimpleOrientation.Faceup: tb.Text = "Faceup"; break; case SimpleOrientation.Facedown: tb.Text = "Facedown"; break; default: tb.Text = "Unknown orientation"; break; } }); } ``` ### Unsubscribing from the readings ```csharp simpleOrientationSensor.OrientationChanged -= SimpleOrientationSensor_OrientationChanged; ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/orientation.md --- uid: Uno.Features.Orientation --- # Controlling orientation The application's orientation can be controlled using the [DisplayInformation](https://learn.microsoft.com/uwp/api/windows.graphics.display.displayinformation) class, more specifically, the static [AutoRotationPreferences](https://learn.microsoft.com/uwp/api/windows.graphics.display.displayinformation.autorotationpreferences) property. ## Controlling Orientation on iOS In order for the DisplayInformation's AutoRotationPreferences to work properly, you need to ensure that all potential orientations are supported within the iOS application's `info.plist` file. > [!WARNING] > On iOS 9 and above, the system does not allow iPad applications to dictate their orientation if they support [Multitasking / Split View](https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/AdoptingMultitaskingOniPad/). In order to control orientation through the DisplayInformation class, you will need to opt-out of Multitasking / Split View by ensuring that you have defined the following in your `info.plist`: > > ```xml > UIRequiresFullScreen > > ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/concepts/overview/philosophy-of-uno.md --- uid: Uno.Overview.Philosophy --- # Philosophy of Uno Platform ## Mission **To empower developers to build pixel-perfect, single-codebase applications for Windows, WebAssembly, iOS, macOS, Android, and Linux.** Uno Platform is committed to providing tools for developers to efficiently create high-quality, native-feeling applications across all modern platforms from a unified codebase. ## Vision Uno Platform strives to be the leading cross-platform UI framework enabling .NET developers to reuse their skills and code, thereby shrinking development time and cost while maximizing reach. Our vision is to make true cross-platform UI/UX parity possible—whether deploying to mobile, web, or desktop—with full support for the latest device capabilities, modern tooling including AI, and next-generation development experiences. --- ## Core Philosophy & Principles ### 1. Leverage Existing Tools and Skills Uno Platform is built on the foundation of well-established Microsoft technologies—including XAML and C#—so developers can apply the skills they already know instead of learning entirely new paradigms. And because Uno Platform supports development from any operating system, teams can build and ship cross-platform applications using the tools and workflows that fit their environment best. **Key Benefits:** - Maximize productivity with cross-OS tooling like C# and XAML Hot Reload, Hot Design for real-time visual editing, AI-powered assistance through Docs MCP and App MCP, and streamlined CLI tools such as uno-check and project templates. - Build apps using proven Microsoft technologies and deploy to multiple platforms: WebAssembly, iOS, Android, macOS, Windows, and Linux - Reduce learning curve for .NET developers transitioning to cross-platform development - Day-0 support for the latest .NET and Visual Studio ecosystems ### 2. AI-Powered Agentic Development As of 2024-2026, Uno Platform has embraced AI-powered development workflows to dramatically increase developer productivity while maintaining full developer control. **Innovation Highlights:** - **Hot Design:** The only visual designer that enables real-time, on-app visual editing and AI-assisted UI creation. - **AI Agents in Development:** Uno Platform Studio 2.0 (an AI-powered development tool suite) introduces AI assistants like the Hot Design Agent, an AI-powered design assistant that can understand your code, context, and even control the running app to suggest and implement UI changes in real time - **Human-in-the-Loop:** Developers preview and approve changes, ensuring quality while benefiting from AI assistance - **MCP Servers:** AI interacts with documentation, APIs, app states, and UI elements live via Model Context Protocol (MCP) servers, providing context-aware assistance - **App Live Testing:** AI agents can interact with running apps, trigger UI events, and automate testing/debugging with human approval This approach represents a fundamental shift in how developers work—enabling faster iterations, better design fidelity, and reduced time-to-market without sacrificing code quality or control. ### 3. Pixel-Perfect, Rich, and Responsive UIs We believe developers shouldn't have to choose between productivity and great design. Uno Platform prioritizes both. **Our Commitment:** - Support sophisticated animations, templating, and visual effects - Achieve responsive, pixel-perfect interfaces that adapt across devices - Enable designers and developers to work together seamlessly with tools like Figma integration (one-click export from Figma to C# or XAML) - Provide visual designers with hot reload capabilities on running apps for instant feedback ### 4. Separation of Concerns Uno Platform advocates a clear separation between model, view, and presentation logic, promoting MVVM (Model-View-ViewModel) principles. **Architecture Benefits:** - Clean, maintainable code using features like data binding and attached properties - Support for both classic MVVM and modern state management approaches (MVUX) - Scalable application architecture that grows with your team and project - Testable code with clear boundaries between business logic and UI ### 5. Native Inter-compatibility While promoting maximum code reuse as the ideal approach, Uno recognizes the need for platform-specific functionality. **Flexibility Features:** - Support "escape hatches" for platform-specific code when needed - Easy integration of native third-party libraries and APIs - Ability to call platform-specific APIs directly from shared code - Hybrid UI scenarios combining web and native elements ### 6. Performance as a Feature Performance is not an afterthought; it's a primary consideration. We prioritize optimization based on real-world profiling and ongoing enhancements to ensure apps are fast and responsive. **Performance Focus:** - Optimized Skia rendering engine for smoother performance - Hardware-accelerated UI features (e.g., hardware-accelerated shadows) - Optimized image loading (e.g., offloading decoding to WebWorkers for WebAssembly) - Continuous profiling and performance improvements in every release - Prevention of poor user experiences and negative reviews through proactive performance work --- ## Comprehensive Cross-Platform Support Uno Platform enables building applications for all major platforms from a **single codebase**: - **Windows** (Win32, UWP, WinUI 3) - **WebAssembly** (Browser-based, no plugins required) - **iOS** (iPhone and iPad) - **Android** (Phones and tablets) - **macOS** (Native Mac applications) - **Linux** (GTK-based applications) - **Embedded devices** (IoT and specialized hardware) This comprehensive support dramatically lowers maintenance costs and reduces time-to-market for updates and new features. --- ## Enterprise-Grade Tooling & Ecosystem ### Development Tools - **Visual Studio Integration:** Full support for Visual Studio 2026 (and previous versions) - **Always on the latest .NET:** Day-0 support for new .NET releases, with preview‑specific builds available for teams who want to stay on the bleeding edge. - **Hot Reload & Real-Time UI Design:** Visual designer lets you tweak XAML and C# on a running app with instant changes - **Status Indicators:** Enhanced developer experience with environment health monitoring, restore progress, and SDK validation ### Rich Component Ecosystem - Seamless integration with **WinUI controls** - **Windows Community Toolkit** - **Uno Toolkit** for additional controls and extensions - **.NET MAUI controls** compatibility - Hundreds of UI components available out of the box - Extensive open-source and 3rd party libraries support ### Collaboration Features - **Figma Integration** for rapid prototyping and design handoff - **Modern Solution Formats:** Support for the human-readable `.slnx` solution format for easier team collaboration and code reviews - **Source Control Friendly:** Designed with team development and version control in mind --- ## Open Source and Commercial Flexibility Uno Platform balances open-source principles with commercial sustainability: - **Open-Source Foundation:** Free and open-source under the Apache 2.0 license - **Commercial Tools:** Optional AI-powered workflows and visual designers available - **Community Edition:** Full access to core platform features - **Professional Edition:** Advanced features for enterprise teams - **Educational Support:** Discounts for educational institutions and open-source contributors --- ## Why Uno Platform? ### For Organizations - **Cost Efficiency:** Single codebase significantly reduces development and maintenance costs compared to platform-specific implementations - **Faster Time-to-Market:** Deploy to all platforms simultaneously rather than building separately - **Future-Proof:** Active development, regular updates, and commitment to latest technologies - **Risk Mitigation:** Open-source foundation ensures you're never locked in ### For Developers - **Leverage Existing Skills:** Use your C# and XAML knowledge immediately - **Career Growth:** Cross-platform expertise is highly valued in the market - **Modern Tooling:** AI-assisted development, hot reload, visual designers - **Community Support:** Active community, extensive documentation, and commercial support options ### For Teams - **Unified Codebase:** Frontend and backend teams can work in the same language and ecosystem - **Design-Developer Collaboration:** Figma integration and visual tools bridge the gap - **Scalable Architecture:** From prototypes to enterprise applications - **Quality Assurance:** Single codebase means testing once deploys everywhere --- ## Looking Forward Uno Platform continues to evolve with the industry, embracing: - **AI Integration:** Making AI-powered development accessible and productive - **Modern .NET:** Supporting the latest .NET releases on day-0 - **Performance:** Continuous optimization for better user experiences - **Developer Experience:** Tools that make developers more productive and happier - **Platform Expansion:** Supporting emerging platforms and form factors Our philosophy is simple: **empower developers with the best tools, leverage proven technologies, and never compromise on quality, performance, or developer experience.** --- ## Learn More - **Official Website:** [https://platform.uno](https://platform.uno) - **Documentation:** [https://platform.uno/docs](https://platform.uno/docs) - **GitHub:** [https://github.com/unoplatform](https://github.com/unoplatform) - **Community:** [https://discord.gg/eBHZSKG](https://discord.gg/eBHZSKG) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/platform-specific-csharp.md --- uid: Uno.Development.PlatformSpecificCSharp --- # Platform-specific C# code Uno Platform allows you to reuse views and business logic across platforms. Sometimes though, you may want to write different code per platform. You may need to access platform-specific native APIs and 3rd-party libraries, or want your app to look and behave differently depending on the platform. > [!Video https://www.youtube-nocookie.com/embed/WgKNG8Yjbc4] This guide covers multiple approaches to managing per-platform code in C#. See [this guide for managing per-platform XAML](xref:Uno.Development.PlatformSpecificXaml). ## Project structure There are multiple ways to restrict code or XAML markup to be used only on a specific platform: * Use conditional code based on the `OperatingSystem.IsXXX` method * Use [conditionals](https://learn.microsoft.com/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if) in a source file * Place the code in a separate file which is only included in the desired platform. The structure of an Uno Platform app created with the default Visual Studio template is [explained in more detail here](xref:Uno.Development.AppStructure). ### OperatingSystem.IsXXX The Uno Platform templates differentiate platforms using the current target framework, yet it's possible to determine the running platform at runtime using: ```csharp if (OperatingSystem.IsBrowser()) { // Do something WebAssembly specific } ``` When building an application that uses the Skia renderer, it is generally best to use such conditionals in order to build for only one target framework in class libraries (e.g., when only targeting `net9.0`, without a platform specifier like `net9.0-ios`). > [!NOTE] > [JSImport/JSExport](xref:Uno.Wasm.Bootstrap.JSInterop) and [BrowserHtmlElement](xref:Uno.Interop.WasmJavaScript1) are available on all platforms targeting .NET 7 and later, and code using those APIs to be conditionally excluded at compile time, and should only use `OperatingSystem` conditions. ## `#if` conditionals The most basic means of authoring platform-specific code is to use `#if` conditionals: ```csharp #if __UNO__ Console.WriteLine("Uno Platform - Pixel-perfect WinUI apps that run everywhere"); #else Console.WriteLine("Windows - Built with Microsoft's own tooling"); #endif ``` If the supplied condition is not met, e.g. if `__UNO__` is not defined, then the enclosed code will be ignored by the compiler. The following conditional symbols are predefined for each Uno platform: | Platform | Symbol | Remarks | | --------------- | ------------------ | ------- | | Android | `__ANDROID__` | | | iOS | `__IOS__` | | | tvOS | `__TVOS__` | | | Catalyst | `__MACCATALYST__` | | | iOS or tvOS or Catalyst | `__APPLE_UIKIT__` | | | WebAssembly | `__WASM__` | Only available in the `net9.0-browserwasm` target framework, see [below](xref:Uno.Development.PlatformSpecificCSharp#webassembly-considerations) | | Desktop | `__DESKTOP__` | Only available in the `net9.0-desktop` target framework. | | Skia | `__UNO_SKIA__` | Only available with `SkiaRenderer` feature. | | _Non-Windows_ | `__UNO__` | To learn about symbols available when `__UNO__` is not present, see [below](xref:Uno.Development.PlatformSpecificCSharp#windows-specific-code) | > [!TIP] > Conditionals can be combined with boolean operators, e.g. `#if __ANDROID__ || __IOS__`. It is also possible to define custom conditional compilation symbols per project in the 'Build' tab in the project's properties. ### Windows-specific code On `net9.0-windows10.0.xxxxx` target framework, an Uno Platform application isn't using Uno.UI at all. It's compiled using Microsoft's own tooling. For that reason, the `__UNO__` symbol is not defined on Windows. This aspect can optionally be leveraged to write code specifically intended for Uno. Apps generated with the default `unoapp` solution template use **Windows App SDK** when targeting Windows. While this is the recommended path for new Windows apps, some solutions instead use **UWP** to target Windows. Both app models define a different conditional symbol: | App model | Symbol | Remarks | | ----------- | ------------- | ------------- | | Windows App SDK | `WINDOWS10_0_18362_0_OR_GREATER` | Depending on the `TargetFramework` value, the _18362_ part may need adjustment | | Universal Windows Platform | `NETFX_CORE` | No longer defined in new apps by default | ## Type aliases Defining a [type alias](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/using-directive) with the `using` directive, in combination with `#if` conditionals, can make for cleaner code. For example: ```csharp #if __ANDROID__ using _View = Android.Views.View; #elif __IOS__ using _View = UIKit.UIView; #else using _View = Windows.UI.Xaml.UIElement; #endif ... public IEnumerable<_View> FindDescendants(FrameworkElement parent) => ... ``` ## Partial class definitions Heavy usage of `#if` conditionals in shared code makes it hard to read and comprehend. A better approach is to use [partial class definitions](https://learn.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods) to split shared and platform-specific code. Starting from Uno Platform 5.2, in project or class libraries using the `Uno.Sdk`, a set of implicit file name conventions can be used to target specific platforms: * `*.wasm.cs` is built only for `net9.0-browserwasm` * `*.desktop.cs` is built only for `net9.0-desktop` * `*.iOS.cs` is built only for `net9.0-ios` and `net9.0-maccatalyst` * `*.tvOS.cs` is built only for `net9.0-tvos` * `*.UIKit.cs` is built only for `net9.0-ios` and `net9.0-maccatalyst` and `net9.0-tvos` * `*.Apple.cs` is built only for `net9.0-ios` and `net9.0-maccatalyst` and `net9.0-tvos` * `*.Android.cs` is built only for `net9.0-android` * `*.WinAppSDK.cs` is built only for `net9.0-windows10` (eg. `net9.0-windows10.0.22621`) In addition, for class libraries: * `*.reference.cs` is built only for reference implementation * `*.crossruntime.cs` is built for WebAssembly, Desktop, and reference implementation > [!NOTE] > For backwards compatibility, using `.skia.cs` is currently equivalent to `.desktop.cs`. This might change in the future, so we recommend using the suffixes above instead. Using file name conventions allows for reducing the use of `#if` compiler directives. ### A simple example Shared code in `PROJECTNAME/NativeWrapperControl.cs`: ```csharp public partial class NativeWrapperControl : Control { ... protected override void OnApplyTemplate() { base.OnApplyTemplate(); _nativeView = CreateNativeView(); } ``` Platform-specific code in `PROJECTNAME/NativeWrapperControl.Android.cs`: ```csharp #if __ANDROID__ public partial class NativeWrapperControl : Control { ... private View CreateNativeView() { ... //Android-specific code } ``` Platform-specific code in `PROJECTNAME/NativeWrapperControl.iOS.cs`: ```csharp #if __IOS__ public partial class NativeWrapperControl : Control { ... private UIView CreateNativeView() { ... //iOS-specific code } ``` You can use [partial methods](https://learn.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods#partial-methods) when only one platform needs specialized logic. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/platform-specific-xaml.md --- uid: Uno.Development.PlatformSpecificXaml --- # Platform-specific XAML markup in Uno Uno Platform allows you to reuse views and business logic across platforms. Sometimes, though, you may want to write different code per platform, either because you need to access platform-specific native APIs and 3rd-party libraries, or because you want your app to look and behave differently depending on the platform. > [!Video https://www.youtube-nocookie.com/embed/IZt-ymNZpZw] This guide covers multiple approaches to managing per-platform markup in XAML. See [this guide for managing per-platform C#](xref:Uno.Development.PlatformSpecificCSharp). ## Project structure There are two ways to restrict code or XAML markup to be used only on a specific platform: * Use conditionals within a shared file * Place the code in a file that is only included in the desired target framework. The structure of an Uno Platform app created with the default [Visual Studio template](https://marketplace.visualstudio.com/items?itemName=unoplatform.uno-platform-addin-2022) is [explained in more detail here](xref:Uno.Development.AppStructure). ## XAML conditional prefixes The Uno platform uses pre-defined prefixes to include or exclude parts of XAML markup depending on the target framework being used. These prefixes can be applied to XAML objects or to individual object properties. Conditional prefixes you wish to use in XAML files must be defined at the top of the file, like other XAML prefixes. They can then be applied to any object or property within the body of the file. For prefixes which will be excluded on Windows (e.g. `android`, `ios`), the actual namespace is arbitrary, since the Uno parser ignores it. The prefix should be put in the `mc:Ignorable` list. For prefixes which will be included on Windows (e.g. `win`, `not_android`) the namespace should be `http://schemas.microsoft.com/winfx/2006/xaml/presentation` and the prefix should not be put in the `mc:Ignorable` list. ### Examples #### Example 1 Using the following XAML: ```xml ``` Results in: ![Visual output](Assets/platform-specific-xaml.png) In this example note how the properties `FontSize` and `Foreground` are selectively used based on platform. The `TextBlock` property `Text` also has two different values based on whether or not the app is running in Android. Finally, an entire `TextBlock` is added if the app is running in iOS. This shows: 1. How certain properties can be used based on the platform 2. How the values of certain properties can be changed based on the platform 3. How entire controls can be added or removed for certain platforms #### Example 2 Platform-specific XAML also allows you to exclude a parent element and all its children. This is especially useful for cases where children are already part of a namespace but need to be excluded on certain platforms. Consider the following XAML which is using the Windows Community Toolkit's [Blur](https://learn.microsoft.com/windows/communitytoolkit/animations/blur) animation. While this runs for UWP, it is not currently supported in the Uno Platform and needs to be conditionally disabled. It isn't possible to add something like `` to disable the behavior itself. Instead, the entire `Grid` is disabled on any platforms except Windows and child elements will be disabled along with it. ```xml ``` ### Available prefixes The pre-defined prefixes are listed below: > [!NOTE] > Skia in the context of this table refers to all Skia targets, including when Android, iOS, or Wasm are running with Skia rendering. > > [!NOTE] > Unless explicitly stated, Android, iOS, and web in the context of this table refer specifically to the old native platforms and not when running with Skia rendering. | Prefix | Included platforms | Excluded platforms | Namespace | Put in `mc:Ignorable`? | |-------------------|------------------------------------------------|--------------------------------------|-------------------------------------------------------------|------------------------| | `win` | WinUI | Android, iOS, web, macOS, Skia | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | | `not_win` | Android, iOS, web, macOS, Skia | WinUI | `http://uno.ui/not_win` | yes | | `android` | Android | WinUI, iOS, web, macOS, Skia | `http://uno.ui/android` | yes | | `ios` | iOS | WinUI, Android, web, macOS, Skia | `http://uno.ui/ios` | yes | | `wasm` | web | WinUI, Android, iOS, macOS, Skia | `http://uno.ui/wasm` | yes | | `macos` | macOS | WinUI, Android, iOS, web, Skia | `http://uno.ui/macos` | yes | | `skia` | Skia | WinUI, Android, iOS, web, macOS | `http://uno.ui/skia` | yes | | `androidskia` | Android running with Skia rendering | Everything else | `http://uno.ui/androidskia` | yes | | `iosskia` | iOS running with Skia rendering | Everything else | `http://uno.ui/iosskia` | yes | | `wasmskia` | Web running with Skia rendering | Everything else | `http://uno.ui/wasmskia` | yes | | `not_android` | WinUI, iOS, web, macOS, Skia | Android | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | | `not_ios` | WinUI, Android, web, macOS, Skia | iOS | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | | `not_wasm` | WinUI, Android, iOS, macOS, Skia | web | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | | `not_macos` | WinUI, Android, iOS, web, Skia | macOS | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | | `not_skia` | WinUI, Android, iOS, web, macOS | Skia | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | | `not_androidskia` | All except Android running with Skia rendering | Android running with Skia rendering | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | | `not_iosskia` | All except iOS running with Skia rendering | iOS running with Skia rendering | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | | `not_wasmskia` | All except web running with Skia rendering | web running with Skia rendering | `http://schemas.microsoft.com/winfx/2006/xaml/presentation` | no | More visually, platform support for the pre-defined prefixes is shown in the below table: | Prefix | Windows | Android | iOS | Web | macOS | Skia | |---------------|-------|-------|-------|-------|-------|-------| | `win` | ✔ | ✖ | ✖ | ✖ | ✖ | ✖ | | `android` | ✖ | ✔ | ✖ | ✖ | ✖ | ✖ | | `ios` | ✖ | ✖ | ✔ | ✖ | ✖ | ✖ | | `wasm` | ✖ | ✖ | ✖ | ✔ | ✖ | ✖ | | `macos` | ✖ | ✖ | ✖ | ✖ | ✔ | ✖ | | `skia` | ✖ | ✖ | ✖ | ✖ | ✖ | ✔ | | `not_win` | ✖ | ✔ | ✔ | ✔ | ✔ | ✔ | | `not_android` | ✔ | ✖ | ✔ | ✔ | ✔ | ✔ | | `not_ios` | ✔ | ✔ | ✖ | ✔ | ✔ | ✔ | | `not_wasm` | ✔ | ✔ | ✔ | ✖ | ✔ | ✔ | | `not_macos` | ✔ | ✔ | ✔ | ✔ | ✖ | ✔ | | `not_skia` | ✔ | ✔ | ✔ | ✔ | ✔ | ✖ | ### XAML prefixes in cross-targeted libraries For Uno Platform 6.0 and above, XAML prefixes behave differently in class libraries than when used directly in application code. Specifically, it isn't possible to distinguish Skia and Wasm/Native in a library, since both platforms use the `net9.0`/`net10.0` target. The `wasm` and `skia` prefixes will always evaluate to false inside of a library. The prefix `netstdref` is available and will include the objects or properties in both Skia and Wasm builds. A prefix `not_nestdref` can also be used to exclude them. Since Skia and Wasm/Native are similar, it is often not necessary to make the distinction. In cases where it is needed (fonts are one example), the XAML files must be placed directly in the app project. | Prefix | Namespace | Put in `mc:Ignorable`? | |-----------------|-------------------------------------------------------------|------------------------| | `netstdref` | `http://uno.ui/netstdref` | yes | | `not_netstdref` | `http://uno.ui/not_netstdref` | yes | ### Specifying namespaces Specifying CLR namespaces in platform specific XAML namespace can be done as follows: ```xml ``` In this example, types prefixed in the `android` XAML namespace will be looked up in `My.Custom.Namespace1`, `MyCustomNamespace2` then in all the namespaces defined in default namespace `http://schemas.microsoft.com/winfx/2006/xaml/presentation`. > [!NOTE] > When using Uno Platform 4.x and in the absence of CLR namespace specification (using the `#using:` prefix), type matching is done through partial name based matching, without using the namespace information. In Uno Platform 4.8, this partial matching can be controlled by the `UnoEnableXamlFuzzyMatching` msbuild property. Uno Platform 5.0 and later will be setting `UnoEnableXamlFuzzyMatching` to `false` by default and will force explicit type matching. ## XAML Conditional Methods You can use standard WinUI conditional XAML prefixes with Uno Platform, [as documented here](https://learn.microsoft.com/windows/uwp/debug-test-perf/conditional-xaml). Currently the following conditional methods are supported: * IsApiContractPresent(ContractName, VersionNumber) * IsApiContractNotPresent(ContractName, VersionNumber) * IsTypePresent(ControlType) * IsTypeNotPresent(ControlType) ### IsApiContractPresent The following `ContractName` values are currently supported: * **"Windows.Foundation.UniversalApiContract"**: resolves to `true` if `VersionNumber` is 10 or below, and `false` otherwise. * **"Uno.WinUI"**: resolves to `true` if the [`Uno.WinUI` NuGet package](updating-to-winui3.md) (ie the WinUI 3 API mapping) is in use, `false` if the `Uno.UI` NuGet package is in use. All other contract names will resolve to false. ### IsTypePresent `IsTypePresent()` will resolve to true if the type is found **and** it isn't marked with the `[NotImplemented]` attribute. This is useful for conditionally enabling XAML in a more declarative way, instead of referring to specific platforms. #### Limitations in cross-targeted libraries `IsTypePresent()` is resolved at compile time. In a cross-targeted library, this means that for WebAssembly and Skia, it doesn't use the correct implementation status for those platforms, but instead uses the implementation status reported by the 'reference' Uno.UI .NET Standard 2.0 assembly. Therefore it may report an incorrect status for WebAssembly and/or Skia inside of a cross-targeted library. ### Example The following example uses `IsTypePresent` to use WebView to display content on platforms where it's available, and a custom control to display the content on platforms where WebView isn't supported: ```xml ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/pointers-keyboard-and-other-user-inputs.md --- uid: Uno.Features.UserInputs --- # Uno support for user inputs ## Supported user inputs User inputs are usually propagated using `RoutedEvents`. See Uno's [routed events documentation](routed-events.md) to better understand their implementation on Uno. | Routed Event | Android | iOS | Wasm | Skia Desktop | | | ----------------------------- | ------- | ---------------- | ------- | ------------ | --- | | **_focus events_** | `GotFocus` | Yes | Yes (1) | Yes (1) | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.gotfocus) | | `LostFocus` | Yes | Yes (1) | Yes (1) | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.lostfocus) | | **_keyboard events_** | `KeyDown` | Hardware Only (2) | Yes (2) | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.keydown) | | `KeyUp` | Hardware Only (2) | Yes (2) | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.keyup) | | **_pointer events_** | `PointerCanceled` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.pointercanceled) | | `PointerCaptureLost` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.pointercapturelost) | | `PointerEntered` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.pointerentered) | | `PointerExited` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.pointerexited) | | `PointerMoved` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.pointermoved) | | `PointerPressed` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.pointerpressed) | | `PointerReleased` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.pointerreleased) | | `PointerWheelChanged` | No | No | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.pointerwheelchanged) | | **_manipulation events_** | `ManipulationStarting` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.manipulationstarting) | | `ManipulationStarted` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.manipulationstarted) | | `ManipulationDelta` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.manipulationdelta) | | `ManipulationInertiaStarting` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.manipulationinertiastarting) | | `ManipulationCompleted` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.manipulationcompleted) | | **_gesture events_** | `Tapped` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.tapped) | | `DoubleTapped` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.doubletapped) | | `RightTapped` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.righttapped) | | `Holding` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.holding) | | **_drag and drop_** | `DragStarting` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.dragstarting) | | `DragEnter` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.dragenter) | | `DragOver` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.dragover) | | `DragLeave` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.dragleave) | | `Drop` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.drop) | | `DropCompleted` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.uielement.dropcompleted) | Notes: 1. **Focus** events: * **iOS**: The concept of _focus_ is emulated because it's not supported by the platform, so this event is always bubbling in managed code. * **Wasm**: Current implementation is not totally reliable and doesn't support _lost focus_ most of the time. 2. **Keyboard** events: * **Android**: `KeyDown` and `KeyUp` events are **generated only from hardware keyboards** (Except for the _Editor Action_ on _soft keyboards_, those are translated as `KeyUp` with `KeyCode.Enter`). Some soft keyboard **MAY** generate those events, but your code shouldn't rely on that. This is a limitation [in the Android platform](https://developer.android.com/training/keyboard-input/commands) (see note on this link content). > Because of those limitations, _Key Events_ are not being implemented as _routed events_ on Android, so `AddHandler` & `RemoveHandler` > won't work for keyboard events. **They won't bubble in managed code**. * **iOS**: `KeyDown` & `KeyUp` routed events are generated from only a `TextBox`. Only character-related keyboard events are generated. They are implemented as _Routed Events_ and they are **always bubbling in managed code**. * **Skia**: Keyboard events are supported from `CoreWindow.KeyUp` and `CoreWindow.KeyDown` events, as well as `UIElement.KeyUp` and `UIElement.KeyDown` events for Skia Desktop. ## Pointer Events These events are the base for all other pointing device related events (i.e. Manipulation, Gesture and drag and dop events). They are directly linked to the native events of each platform: * `Touches[Began|Moved|Ended|Cancelled]` on iOS * `dispatchTouchEvent` and `dispatchGenericMotionEvent` on Android * `pointer[enter|leave|down|up|move|cancel]` on WebAssembly On Skia however, they are fully managed events. ### Pointers events and the ScrollViewer Like on WinUI, as soon as the system detects that the user wants to scroll, a control gets a `PointerCancelled` and that control won't receive any other pointer event until the user releases the pointer. That behavior can be prevented by setting the `ManipulationMode` to something other than `System` on a control nested in the `ScrollViewer`. For more information, see [Manipulation events](#manipulation-events). Be aware that on iOS, this will set `DelaysContentTouches` to `false`. So, it means that it will slightly reduce the performance of the scrolling. For more information, see [`delaysContentTouches`](https://developer.apple.com/documentation/uikit/uiscrollview/1619398-delayscontenttouches). ### Known limitations for pointer events As those events are tightly coupled to the native events, Uno has to make some compromises: * On iOS, when tapping with a mouse or a pen on Android, or in a few other specific cases (like `PointerCaptureLost`), multiple managed events are raised from a single native event. These have multiple effects: * On WinUI if you have a control A and a nested control B, you will get: ```output B.PointerEnter A.PointerEnter B.PointerPressed A.PointerPressed ``` but with UNO you will get: ```output B.PointerEnter B.PointerPressed A.PointerEnter A.PointerPressed ``` * If you handle the `PointerEnter` on **B**, the parent control **A** won't get the `PointerEnter` (as expected) nor the `PointerPressed`. * On Android with a mouse or a pen, the `PointerEnter` and `PointerExit` are going to be raised without taking clipping in consideration. This means that you will get the enter earlier and the exit later than on other platforms. * On Android if you have an element with a `RenderTransform` which overlaps one of its sibling elements, the element at the top will get the pointer events. * On WASM, iOS, and Android, the `RoutedPointerEventArgs.FrameId` will be reset to 0 after 49 days of running time of the application. * Unlike on WinUI, controls that are under a `Popup` won't receive the unhandled pointer events. * On non-Skia-based platforms, unlike WinUI, it's impossible to receive a `PointerReleased` without getting a `PointerPressed` before. (For instance if a child control handled the pressed event but not the released event). > On WASM as `TextElement` inherits from `UIElement`, it means that, unlike WinUI, `TextBlock` won't raise the > `PointerReleased` event when clicking on a `Hyperlink`. * Unlike WinUI, on the `Hyperlink` the `Click` will be raised before the `PointerReleased`. * The property `PointerPointProperties.PointerUpdateKind` is not set on Android 5.x and lower (API level < 23) * On Firefox, pressed pointers are reported as fingers. This means you will receive events with `PointerDeviceType == Pen` only for hovering (i.e. `Pointer` - note that, as of 2019-11-28, once pressed `PointerMove` will be flagged as "touch") and you won't be able to track the barrel button nor the eraser. For more information, see [Bug report on Bugzilla](https://bugzilla.mozilla.org/show_bug.cgi?id=1449660). * On WASM, if you touch the screen with the pen **then** you press the barrel button (still while touching the screen), the pointer events will have the `IsRightButtonPressed` set (in addition to the `IsBarrelButtonPressed`). On WinUI and Android, you get this flag only if the barrel button was pressed at the moment where you touched the screen, otherwise, you will have the `IsLeftButtonPressed` and the `IsBarrelButtonPressed`. * For pen and fingers, the `Holding` event is not raised after a given delay like on WinUI, but instead, we rely on the fact that we usually get a lot of moves for those kinds of pointers, so we raise the event only when we get a move that exceeds the defined thresholds for holding. * On WASM, Shapes must have a non-null Fill to receive pointer events (setting the Stroke is not sufficient). * On WASM, if the user scrolls diagonally (e.g. with a Touchpad), but you mark as `Handled` pointer events only for vertical scrolling, then the events for the horizontal scroll component won't bubble through the parents. ### Pointer capture The capture of pointer is handled in managed code only. On WebAssembly, Uno however still requests the browser to capture the pointer, but Uno does not rely on native `[got|lost]pointercapture` events. ### iPadOS mouse support To differentiate between mouse and touch device type for pointer events, include the following in your app's `Info.plist`: ```xml UIApplicationSupportsIndirectInputEvents ``` Without this key, the current version of iPadOS reports mouse interaction as normal touch. ## Manipulation Events They are generated from the PointerXXX events (using the `Microsoft.UI.Input.GestureRecognizer`) and are bubbling in managed only. ## Gesture Events They are generated from the PointerXXX events (using the `Microsoft.UI.Input.GestureRecognizer`) and are bubbling in managed only. Note that `Tapped` and `DoubleTapped` are not linked in any way to a native equivalent, but are fully interpreted in managed code. In order to match the WinUI behavior, on WASM, the default "Context menu" of the browser is disabled (except for the `TextBox`), no matter if you use/handle the `RightTapped` event or not. Be aware that on some browsers (Firefox for example), the user can still request to get the "Context menu" on right click. ### Disabling browser context menu on `-based` elements While the browser context menu enabled on `TextBox` and `PasswordBox` by default, it will be disabled when `ContextFlyout` is set on the control. To manually disable the context menu on a `UIElement` which represents a HTML ``, you can manually set the `context-menu-disabled` CSS class: ```csharp #if __WASM__ MyInputElement.SetCssClasses("context-menu-disabled"); #endif ``` ## Drag and drop Those events are also 100% managed events, built from the PointerXXX events (using the `Microsoft.UI.Input.GestureRecognizer`) ### Inter-app drag and drop support A _drag and drop_ operation can be used to move content within an app, but it can also be used to **copy** / **move** / **link** between apps. While intra-app _drag and drop_ is supported on all platforms without limitations, inter-app _drag and drop_ requires platform-specific support. The table and sections below describe supported functionality and limitations for each platform. | | From uno app to external | From external app to uno | | --------------------- | ------------------------------------------------ | ------------------------ | | Android | No | No | | iOS | No | No | | Wasm | No | Yes (Text, Link, Image, File, Html, Rtf) | | macOS | Yes (Text, Link, Image, Html, Rtf) | Yes (Text, Link, Image, File, Html, Rtf) | | Skia Desktop (Windows) | Yes (Text, Link, Image, File, Html, Rtf) | Yes (Text, Link, Image, File, Html, Rtf) | | Skia Linux | No | No | * "Link" may refer to WebLink, ApplicationLink, or Uri formats #### Wasm Limitations 1. When dragging content from external app to uno, you cannot retrieve the content from the `DataPackage` before the `Drop` event. This a limitations of web browsers. Any attempt to read it before the `Drop` will result into a timeout exception after a hard coded delay of 10 seconds. 2. When dragging some uris from external app to uno, only the first uri will be accessible through the **WebLink** standard format ID. #### macOS Limitations 1. Dragging a File (StorageItem) from an Uno Platform App to an external destination is not currently supported. 2. When receiving a drop within an Uno Platform App from an external source, key modifiers are not supported #### Skia Limitations 1. There is no standard type for **WebLink** (nor **ApplicationLink**) on this platform. They are copied to the external app as raw **Text**, and converted back as **WebLink** or **ApplicationLink** from raw text from the external app when [`Uri.IsWellFormedUriString(text, UriKind.Absolute)`](https://learn.microsoft.com/dotnet/api/system.uri.iswellformeduristring) returns true. 2. The image content seems to not be readable by common apps, only another Uno app can read it properly. ### Drag and Drop Data Format Considerations WinUI has the following standard data formats that correspond with a URI/URL: 1. Uri, now deprecated in favor of: 2. WebLink and 3. ApplicationLink Several platforms such as macOS, iOS, and Android do not differentiate between them and only use a single URI/URL class or string. When applying data to the native clipboard or dragging/dropping data from a DataPackage, only one URI/URL may be used. Therefore, all URI data formats are merged together into a single URI using the above-defined priority. WebLink is considered more specific than ApplicationLink. When pulling data from the native clipboard or drag/drop data, this single native URI/URL is separated into the equivalent WinUI data format (since WinUI's direct equivalent standard data format 'Uri' is deprecated). The mapping is as follows: 1. WebLink is used if the given URL/URI has a scheme of "http" or "https" 2. ApplicationLink is used if not #1 For full compatibility, the Uri format within a DataPackage should still be populated regardless of #1 or #2. ### Known issues for drag and drop events 1. If you have 2 nested drop targets (i.e. element flagged with `AllowDrop = true`), when the pointer leaves the deepest / top most element but not the parent, the parent element will also raise `DragLeave` and immediately after raise `DragEnter`. 1. On WinUI, the default UI will include a tooltip that indicates the accepted drop action, and a "screenshot" of the dragged element. Currently, Uno will display only the tooltip. 1. The accepted drop action displayed in the tooltip is not localized. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/profiling-applications.md --- uid: Uno.Tutorials.ProfilingApplications --- # Profiling Uno Platform Applications ## Profiling .NET Android/iOS applications .NET provides the ability to do CPU profiling through [`dotnet-trace`](https://learn.microsoft.com/dotnet/core/diagnostics/dotnet-trace) for iOS and Android applications. ### Pre-requisites Run the following commands - `dotnet tool update -g dotnet-dsrouter` - `dotnet tool update -g dotnet-trace` - `dotnet tool update -g dotnet-gcdump` ## Profiling .NET iOS applications > [!NOTE] > This documentation is based on [.NET iOS profiling](https://github.com/xamarin/xamarin-macios/wiki/Profiling) and [.NET Android profiling](https://github.com/dotnet/android/blob/main/Documentation/guides/tracing.md) documentation. Profiling iOS apps needs to be done on a mac machine. First, create an alias to `mlaunch`: ```bash cd [your-folder-with-the-csproj] alias mlaunch=$(dotnet build -getProperty:MlaunchPath *.csproj -f net9.0-ios) ``` ### Profiling on an iOS Simulator 1. Build the app with the following parameters: ```dotnetcli cd [your-folder-with-the-csproj] dotnet build -f net10.0-ios -p:DiagnosticAddress=127.0.0.1 -p:DiagnosticPort=9000 -p:DiagnosticSuspend=true -p:DiagnosticListenMode=listen ``` 1. Find the simulator you want to run on: ```dotnetcli $ xcrun simctl list devices ``` Find a device that is shutdown or booted, and take note of its UDID. 1. Launch the app (it will be paused on startup waiting for the .NET tooling to connect): ```bash mlaunch --device :v2:udid=xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb --wait-for-exit --stdout=$(tty) --stderr=$(tty) --launchsim=[your-app-path]/bin/Debug/net*-ios/*/*.app ``` Replace the UDID with the one you found above. 1. Once the app is waiting, go ahead and start profiling: ```dotnetcli dotnet-trace collect --dsrouter ios-sim --format speedscope ``` 1. Optionally take a GC dump: ```dotnetcli dotnet-gcdump collect --dsrouter ios-sim ``` ### Profiling on a physical iOS device 1. Build the app with the following parameters: ```dotnetcli cd [your-folder-with-the-csproj] dotnet build -f net10.0-ios -p:DiagnosticAddress=127.0.0.1 -p:DiagnosticPort=9000 -p:DiagnosticSuspend=true -p:DiagnosticListenMode=listen ``` 1. Install & launch the app: ```bash mlaunch --installdev bin/Debug/net*/*/*.app --devname ... mlaunch --launchdev bin/Debug/net*/*/*.app --devname ... --wait-for-exit ``` 1. Start CPU profiling: ```dotnetcli dotnet-trace collect --dsrouter ios --format speedscope ``` 1. Optionally take a GC dump: ```dotnetcli dotnet-gcdump collect --dsrouter ios ``` ## Profiling on Android ### Enable profiling in your application In `Platforms/Android/environment.conf`, add **one** of the following lines: - For devices: ```text DOTNET_DiagnosticPorts=127.0.0.1:9000,suspend,connect ``` - For emulators: ```text DOTNET_DiagnosticPorts=10.0.2.2:9000,suspend,connect ``` The `suspend` directive means that the application will wait for `dotnet-trace` connections before starting, `nosuspend` may also be used. ### Profiling the application - Start the diagnostics router: - For devices, run `adb reverse tcp:9000 tcp:9001` then `dotnet-dsrouter android -v debug` - For emulators, run `dotnet-dsrouter android-emu -v debug` - Run `dotnet-trace`, in the folder where you want your traces to be stored, using the **PID** provided by the `dotnet-dsrouter` output: ```dotnetcli dotnet-trace collect -p PID --format speedscope ``` - Start the `x64` emulator or the `arm64` device > Running on a 32 bits device is not supported and will generate unusable traces in SpeedScope - Build the application with profiling enabled ```dotnetcli dotnet build -c Release -f net9.0-android -r android-arm64 -t:Run -p:AndroidEnableProfiler=true ``` Use `-r android-x64` for emulators instead. - The app will start and `dotnet-trace` will display a MB number counting up - Use the app, once done, stop `dotnet-trace` by pressing `Enter` or `Ctrl+C` - Open a browser at `https://speedscope.app` and drop the `*.speedscope.json` file in it ### Analyzing the trace data This section provides insights into what to look for when analyzing flame charts. - When building without AOT, a lot of the startup traces will show time spent in `System.Private.CoreLib!System.Runtime.CompilerServices.RuntimeHelpers.CompileMethod(object)`, indicating that that the JIT is doing a lot of work. This can make performance improvements harder to find. - When building with AOT, most of the IL is compiled to native code with some exceptions. You may still find `RuntimeHelpers.CompileMethod` invocations. In such cases, you may need to find what is causing the AOT compiler to skip IL portions. If the JIT still impacts cold paths of your application, you may still need to adjust your code to avoid the JIT. For instance, some generics constructs force the AOT compiler to still use JITing. In other cases, it could be accessing static-type members. The JIT conditions are runtime version dependent, and [looking at the runtime code](https://github.com/dotnet/runtime/blob/9703660baa08914773b26e413e361c8ce04e6d94/src/mono/mono/mini/aot-compiler.c) can help to find out which ones. - Some of the time is spent in the .NET Android binding framework (e.g. `Android.Runtime.JNIEnv` or `Java.Interop.TypeManager`), operations that cannot be adjusted by the application. One change to consider is to reduce the native code invocations to a strict minimum, where impactful. ## Analyzing GC memory dumps You can analyze the GC memory `.gcdump` files using the [Visual Studio 2022/2026 memory profiler](https://learn.microsoft.com/en-us/visualstudio/profiling/memory-usage-without-debugging2?view=visualstudio&pivots=programming-language-dotnet#managed-types-reports) by using the File / Open menu and navigating the results. ## Profiling Skia Desktop applications Profiling Skia-based Uno Platform targets can be done on Windows in Visual Studio 2019 and 2022 using [time and memory profilers](https://learn.microsoft.com/visualstudio/profiling/profiling-feature-tour?view=vs-2019). ## Profiling WebAssembly applications with runtime diagnostics As of Dotnet 10.0, runtime diagnostics like performance traces and GC dumps can be collected by calling some Javascript methods exposed by the Dotnet runtime. For more details, see the [dotnet 10.0 release notes](https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview4/aspnetcore.md#blazor-webassembly-runtime-diagnostics) ## Profiling WebAssembly applications with the browser's DevTools Profiling WebAssembly applications can be done through the use of AOT compilation, and [browsers' performance tab](https://developer.chrome.com/docs/devtools/evaluate-performance/). ### Setup the WebAssembly application for profiling - Enable emcc profiling: ```xml true ``` - Enable AOT compilation: ```xml InterpreterAndAOT ``` - Build and deploy the application - Open the `Performance` tab in your browser - Use your application or restart your application while recording the trace ### Troubleshooting - Deep traces found in large async code patterns or complex UI trees may hit [this chromium issue](https://bugs.chromium.org/p/chromium/issues/detail?id=1206709). This generally makes traces very long to load; you'll need to be patient. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/progressring.md --- uid: Uno.Features.ProgressRing --- # ProgressRing ## [**WinUI**](#tab/winui) ![MUX `ProgressRing`](../Assets/features/progressring/muxprogressring.png) This version comes with [WinUI 2.x and WinUI 3](https://learn.microsoft.com/windows/apps/winui/winui2/release-notes/winui-2.4#progressring) and is using an `` in its Control Template to display Lottie-based animations. > [!IMPORTANT] > To use this Control, you must add a [reference the Lottie package](xref:Uno.Features.Lottie) in your projects, or the ring will not be displayed. ## [**UWP**](#tab/uwp) ![WUX `ProgressRing`](../Assets/features/progressring/wuxprogressring.png) This control works on all platforms and uses the native progress ring control by default, with the exception of Wasm where there is no native progress ring control. > [!NOTE] > In WinUI-based Uno Platform apps, this control is in the `Uno.UI.Controls.Legacy` namespace instead. It is still available as part of Uno Platform 5.x for its support of native styling. On Android and iOS, the WUX `ProgressRing` uses native controls by default (`UIActivityIndicatorView` on iOS and `ProgressBar` on Android). To use the UWP rendering on these targets, you can explicitly apply the `DefaultWuxProgressRingStyle` Style: ```xaml ``` To use the MUX `ProgressRing` on non-Skia targets and WUX `ProgressRing` on Skia targets you can utilize platform-specific XAML syntax: ```xaml ``` --- --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/protocol-activation.md --- uid: Uno.Features.ProtocolActivation --- # Custom protocol activation ## Registering custom scheme ### iOS & macOS Declare your custom URL scheme in `info.plist` in the platform head: ```xml CFBundleURLTypes CFBundleURLName My Useful Scheme CFBundleURLSchemes my-scheme ``` ### Android Register your protocol on the `MainActivity` with the `[IntentFilter]` attribute: ```csharp [IntentFilter( new [] { Android.Content.Intent.ActionView }, Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable }, DataScheme = "my-scheme")] ``` If your target framework is Android 12, you must also add `Exported = true` to the `[Activity]` attribute. `CategoryDefault` is required (must be included for all implicit intents) and `CategoryBrowsable` is optional (allows opening the custom URI from the browser). ### WASM WASM implementation uses the [`Navigator.registerProtocolHandler` API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler). This has several limitations when using a custom scheme: - The custom scheme's name must begin with `web+` - The custom scheme's name must include at least 1 letter after the `web+` prefix - The custom scheme must have only lowercase ASCII letters in its name. You can also use one of the following supported schemes instead: - `bitcoin` - `ftp` - `ftps` - `geo` - `im` - `irc` - `ircs` - `magnet` - `mailto` - `matrix` - `mms` - `news` - `nntp` - `openpgp4fpr` - `sftp` - `sip` - `sms` - `smsto` - `ssh` - `tel` - `urn` - `webcal` - `wtai` - `xmpp` To register the custom theme, call the WASM-specific `Uno.Helpers.ProtocolActivation` API when appropriate to let the user confirm URI handler association: ```csharp #if __WASM__ Uno.Helpers.ProtocolActivation.RegisterCustomScheme( "web+myscheme", new System.Uri("http://localhost:55838/"), "Can we handle web+myscheme links?"); #endif ``` The first argument is the scheme name, the second is the base URL of your application (it must match the current domain to be registered successfully), and the third is a text prompt, which will be displayed to the user to ask for permission (this does not work on all browsers e.g. edge). When a link with the custom scheme gets executed, the browser will navigate to the URL with an additional `unoprotocolactivation` query string key, which will contain the custom URI. Uno internally recognizes this query string key and executes `OnActivated` appropriately. ### WinUI Works according to Windows docs. For more information, see [Handle URI activation | Microsoft Docs](https://learn.microsoft.com/windows/uwp/launch-resume/handle-uri-activation). ## Handling protocol activation Custom URI activation can be handled by overriding the `OnActivated` method in `App.cs` or `App.xaml.cs`: ```csharp protected override void OnActivated(IActivatedEventArgs e) { // Note: Ensure the root frame is created if (e.Kind == ActivationKind.Protocol) { var protocolActivatedEventArgs = (ProtocolActivatedEventArgs)e; var uri = protocolActivatedEventArgs.Uri; // do something } } ``` Note that in line with WinUI, if the application is not running, the `OnLaunched` method is not called and only `OnActivated` is executed instead. You must perform a similar initialization of the root app frame and activate the current `Window` at the end. If the application is running, this initialization can be skipped. A full application lifecycle handling with shared logic between `OnLaunched` and `OnActivated` could look as follows: ```csharp protected override void OnLaunched(LaunchActivatedEventArgs e) { var rootFrame = GetOrCreateRootFrame(e); if (e.PrelaunchActivated == false) { if (rootFrame.Content == null) { rootFrame.Navigate(typeof(MainPage), e.Arguments); } Window.Current.Activate(); } } protected override void OnActivated(IActivatedEventArgs args) { var rootFrame = GetOrCreateRootFrame(args); if (args.Kind == ActivationKind.Protocol) { var protocolActivatedEventArgs = (ProtocolActivatedEventArgs)args; var uri = protocolActivatedEventArgs.Uri; rootFrame.Navigate(typeof(DetailPage), uri.AbsoluteUri); Window.Current.Activate(); } } private Frame GetOrCreateRootFrame(IActivatedEventArgs eventArgs) { var rootFrame = Window.Current.Content as Frame; if (rootFrame == null) { rootFrame = new Frame(); rootFrame.NavigationFailed += OnNavigationFailed; if (eventArgs.PreviousExecutionState == ApplicationExecutionState.Terminated) { // Load state from previously suspended application } Window.Current.Content = rootFrame; } return rootFrame; } ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/proximity-sensor.md --- uid: Uno.Features.ProximitySensor --- # Proximity sensor > [!TIP] > This article covers Uno-specific information for `ProximitySensor`. For a full description of the feature and instructions on using it, see [ProximitySensor Class](https://learn.microsoft.com/uwp/api/windows.devices.sensors.ProximitySensor). * The `Windows.Devices.Sensors.ProximitySensor` class allows measuring distance of an object in millimeters. ## Using `ProximitySensor` with Uno * The sensor is currently only available on Android. * To retrieve the available sensors, `DeviceInformation.FindAllAsync` method is used. ## Example ### Capturing sensor readings ```csharp var selector = ProximitySensor.GetDeviceSelector(); var devices = await DeviceInformation.FindAllAsync(selector); var device = devices.FirstOrDefault(); if (device is not null) { var proximitySensor = ProximitySensor.FromId(device.Id); proximitySensor.ReadingChanged += ProximitySensor_ReadingChanged; } // .. private async void ProximitySensor_ReadingChanged(ProximitySensor sender, ProximitySensorReadingChangedEventArgs args) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { uint? distanceInMillimeters = args.Reading.DistanceInMillimeters; bool isDetected = args.Reading.IsDetected; }); } ``` ### Unsubscribing from the readings ```csharp proximitySensor.ReadingChanged -= ProximitySensor_ReadingChanged; ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/contributing/guidelines/pull-requests.md --- uid: Uno.Contributing.PullRequests --- # Guidelines for pull-requests If you don't know what a pull request is, read the [About pull requests documentation from GitHub](https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). ## Creating a PR If you are an outside contributor, please fork the Uno Platform repository you would like to contribute to your account. See the GitHub documentation for [forking a repo](https://help.github.com/articles/fork-a-repo/) if you have any questions about this. Make sure the repository can build and all tests pass, as well as follow the current [coding guidelines](code-style.md). Pull requests should all be made to the **master** branch. ### Updating your branch on top of the latest of the default branch Make sure to rebase your work on the latest default branch of the Uno repository, when working on a fork: - Add the official uno repository to your remotes: ```bash git remote add uno-origin https://github.com/unoplatform/uno ``` - Fetch the official repository ```bash git fetch uno-origin ``` - Rebase your work on the default branch ```bash git rebase uno-origin/master ``` - Then push your branch to your fork: ```bash git push -f ``` **Commit/Pull Request Format** All commits **must** be in the [Conventional Commits format](../../uno-development/git-conventional-commits.md), otherwise the build will fail. We use this convention to automatically generate release notes for new releases, and means that your commit messages will appear untouched in the release notes. Make sure that: - You create only the least possible commits, where each commit details a specific added feature or bug fix. - Try using the category feature as frequently as possible. (e.g. `feat(NavigationView): Updated the main panel`, or `fix(ProgressRing): Fix visibility`) - Squash your commits, using interactive rebase: ```bash git fetch uno-origin git rebase uno-origin/master -i # Rebase your branch on top of the latest master, squash using fixups git push -f ``` - If you're fixing a regression introduced by a PR that has not been released in a stable version yet, use the `reg` category. Example: `fix(reg): Fixing issue of previous PR`. When opening a PR, you'll see the description is filled by a template. Make sure to read through the template and fill the missing parts in it. If you haven't [added tests](creating-tests.md) appropriate to your changes, the reviewers will probably ask you to add some. ## Reviewing Maintainers, contributors, and the community can participate in reviewing pull-requests. We require `two approvals` before the pull-request can be merged. Please apply the appropriate labels to the pull-request when reviewing. If the pull-request requires minor touch ups, consider doing them in the GitHub editor rather than asking the initiator of the pull-request to do them for you. The history should be squashed to meaningful commits, and the branch should be rebased to a recent commit. ## Merging Once a PR is reviewed and approved. One of the team members will merge it when it passes CI and is ready to merge. If the branch is within the `unoplatform/uno` repository then the branch will be automatically deleted after merging by the [delete-merged-branch](https://github.com/apps/delete-merged-branch) robot. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/raspberry-pi/raspberry-pi-intro.md --- uid: Uno.RaspberryPi.Intro --- # Getting Started with Uno Platform and the Raspberry Pi ![Uno Hello World](images/00_uno-hello-world.jpg) ## Prerequisites For this guide, you'll need various pieces of hardware and an Azure Account; - Raspberry Pi 3b+ and above (I'll be using a [4Gb Pi 4](https://shop.pimoroni.com/products/raspberry-pi-4?variant=29157087445075)) - [Raspberry Pi Power Supply](https://shop.pimoroni.com/products/universal-usb-c-power-supply-5-1v-3a) - [16GB SD Card](https://amzn.to/2YAI07e) - SSH Client like [PuTTY](https://putty.org/)(Both Windows and Mac have a built in ssh client) - Code Editor - [Visual Studio Code](https://code.visualstudio.com) - Choose the two following options: - [LCD Touchscreen](https://amzn.to/3uYSXvt), Keyboard and mouse - OR [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) ## What we'll be doing In this guide, we'll be setting up our Raspberry Pi to launch a "Hello World" Uno Application. For this guide, we'll install all of the requirements to build and run the application directly on the Pi, but I will show you how to do this on your main machine at the end. There will be a series of steps involved in this; - [Connect to your Raspberry Pi](#connect-to-your-raspberry-pi) - [Update Raspberry Pi OS](#update-raspberry-pi-os) - [Install .NET](#install-net) - [Install Uno Platform Templates](#install-uno-platform-templates) - [Create a new Uno Solution](#create-a-new-uno-solution) - [Give the SSH Session access to use the display](#give-the-ssh-session-access-to-use-the-display) - [Build and run the application](#build-and-run-the-application) - [Creating and Building on a PC](#creating-and-building-on-a-pc) - [Wrap Up](#wrap-up) ## Connect to your Raspberry Pi Before we go anywhere, let's make sure we can dial in to our Raspberry Pi. You may need to do this part with a Keyboard, a Mouse and Monitor of course, unless you enabled SSH on the SD card before you installed Raspberry Pi OS. Firstly, make sure that your Pi is connected to the same network. We need to enable both SSH and VNC connections, so click the Raspberry Pi OS start button, then go to the Preferences sub menu and hit the "Raspberry Pi Configuration Item"; ![Raspberry Pi Configuration Menu Item](images/01_raspberry_pi_configuration_menu_item.png) Next, click the Interfaces Tab, and make sure that SSH and VNC are enabled; ![Raspberry Pi Configuration](images/02_enabled_ssh_and_vnc.png) Hit the Ok button, and accept the offer to reboot your Pi. ## Update Raspberry Pi OS Before we can do anything, assuming you've gotten your Raspberry Pi all set up, we need to make sure that everything is up to date. Run the following two commands; ```bash sudo apt update sudo apt full-upgrade ``` Once those two commands have completed, restart your Pi using; ```bash sudo reboot ``` ## Install .NET Now that our Pi is all up to date, we're ready to install the .NET. Normally for the Pi, as there's no `apt-get install dotnet`, we'd need to go through a bunch of steps to get .NET installed. However, I've created a single line install script for .NET 7 on the Raspberry Pi. Run the following command; ```bash wget -O - https://raw.githubusercontent.com/pjgpetecodes/dotnet7pi/main/install.sh | sudo bash ``` You can see the contents of this .NET installation script in [install.sh on GitHub](https://github.com/pjgpetecodes/dotnet7pi/blob/main/install.sh) ![Install .NET](images/03_install-dot-net.gif) Once the process has completed, go ahead and reboot your Pi again with; ```bash sudo reboot ``` Once you're finished, you should be able to run the following to check your .NET version; ```dotnetcli dotnet --info ``` ![.NET Installed](images/04_dot-net-info.png) ## Install Uno Platform Templates Next we can add the Uno Platform Project Templates to our .NET Installation; ```dotnetcli dotnet new --install Uno.Templates ``` ![Install Uno Templates](images/05_install-uno-templates.png) Once the templates are installed, you can scroll back up and see the list of Uno templates that were installed; ![Uno Templates Installed](images/06_uno-templates-installed.png) ## Create a new Uno Solution Now we have the moving parts installed on our Pi, we can spin up a brand new Uno solution with the following command; ```dotnetcli dotnet new unoapp -o HelloPi && cd HelloPi ``` You should now find yourself in the solution directory for your new Uno App. If we have a look at the folder contents with; ```bash dir ``` ![Uno Templates Installed](images/07_uno-app-directory.png) The directory we're interested in is the `HelloPi` directory. This directory contains the project which we'll build and run on the Raspberry Pi. ## Give the SSH Session access to use the display Before we can launch our application, we need to give our SSH session access to the display. If we don't do this, we'll get an error like; ```console Unable to init server: Could not connect: Connection refused (HelloPi:18530): cannot open display: ``` We can sort this out using the following command: ```bash export DISPLAY=:0 ``` You won't get any response to this message, so don't worry. You'll need to remember do this every time you launch a new SSH session currently, but don't worry too much about that for now. ## Build and run the application We're now ready to run our application. Firstly, we need to navigate to the HelloPi directory; ```bash cd HelloPi ``` We can now run our application with; ```dotnetcli dotnet run -f net9.0-desktop ``` This will take quite some time to run this command the first time as the Pi isn't as powerful as a desktop PC of course. You may also see some errors, but don't worry about those, as they're complaining that we're not running this from Visual Studio for XAML Hot reload to connect to. To be able to see your app running, you're going to need to either connect a Monitor or VNC, but all being well, after a minute or so, you should see the Uno Hello World application running happily on your Pi; ![Uno App Running](images/09_uno-app-running.png) ## Creating and Building on a PC We've performed most of this on the Pi itself of course. However, you can actually create and build the whole application on your PC and copy the built files to your Pi using; ```dotnetcli dotnet publish -r linux-arm -o bin\linux-arm\publish --no-self-contained ``` You can copy the contents of the `bin\linux-arm\publish` directory to your Pi in whatever way takes your fancy. You then need to navigate to the directory where you've copied the files and make the main application executable with; ```bash chmod +x HelloPi ``` Don't forget that, if you've just dialled in you'll need to give access to the Display; ```bash export DISPLAY=:0 ``` If you are using a 64-bit version of the Raspberry Pi OS, you need to run the following commands to be able to run 32-bit executable : ```bash sudo apt-get install ia32-libs-multiarch sudo apt-get install ia32-libs ``` You can then run the application with; ```bash ./HelloPi ``` See [Developing UWP Apps for the Raspberry Pi with Uno Platform](https://www.petecodes.co.uk/developing-uwp-apps-for-the-raspberry-pi-with-uno-platform/) blog post for how you can actually automate Building, Deploying, and even debugging from your Windows machine using VS Code. ## Wrap Up With that, we've gotten our first Hello World application up and running on the Raspberry Pi. Thanks. [Pete Gallagher](https://www.twitter.com/pete_codes) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/raygun-monitoring.md --- uid: Monitoring.Raygun --- # Error Monitoring & Crash Reporting with Raygun > [!TIP] > This article covers the basic setup and Uno-specific information for using Raygun with Uno. For a full description of the feature and instructions on using it, see the [official .NET 6+ | Raygun documentation](https://raygun.com/documentation/language-guides/dotnet/crash-reporting/net-core/). Crash reporting is crucial for developing mobile and desktop applications. It ensures you are alerted when exceptions occur, whether they are unhandled or caught exceptions you want to report. With Visual Studio App Center's retirement on the horizon, what diagnostic tool should we turn to? Raygun provides various products, including crash reporting, real user monitoring, and application performance monitoring (APM). It supports a wide range of frameworks, including .NET. ## Setting Up Raygun Raygun offers a free trial, allowing you to explore its features before committing to a subscription. Follow these steps to get started: ### Create a Raygun Account Visit the [Raygun website](https://raygun.com) and sign up for an account. ### Create Your Application 1. Log in to your Raygun account. 2. Create a new application and name it. 3. Select C#/.NET as the language and choose .NET 6+ as the framework. ## Integrating Raygun into Your Uno Platform Application Let's start with a new Uno Platform application using the default template provided by the Uno Template Wizard. ### Step 1 – Create a New Uno Platform Project Start by creating a new Uno Platform project using your preferred development environment. ### Step 2 - Install the NuGet Package Install the Raygun package in your Uno Platform application. Use the Manage NuGet Packages option or the following dotnet CLI command: ```sh dotnet add package Mindscape.Raygun4Net.NetCore ``` ### Step 3 - Create a RaygunClient Create an instance of `RaygunClient` by passing it a `RaygunSettings` object with your application API key. You can also enable automatic catching of unhandled exceptions: ```csharp using Mindscape.Raygun4Net; private static RaygunClient _raygunClient = new RaygunClient(new RaygunSettings() { ApiKey = "YOUR_API_KEY_HERE", CatchUnhandledExceptions = true // Enable to log all unhandled exceptions }); ``` Replace `"YOUR_API_KEY_HERE"` with the actual API key provided by Raygun when you created your application. ### Step 4 - Release and Test Deploy Raygun into your production environment for optimal results. To test the integration, you can raise a test exception: ```csharp try { throw new Exception("Temporary example exception to send to Raygun"); } catch (Exception ex) { _raygunClient.SendInBackground(ex); } ``` > [!IMPORTANT] > If you are setting up Raygun on Wasm, you need to either enable support for multithreading (see the [Wasm threading documentation](https://platform.uno/docs/articles/external/uno.wasm.bootstrap/doc/features-threading.html) for more information) or use the `SendAsync` method instead of `SendInBackground`. ### Step 5 - Observe the Website Once Raygun detects your first error event, the dashboard will automatically update, allowing you to start monitoring. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/release-procedure.md --- uid: Uno.Contributing.ReleaseProcedure --- # Uno.UI release procedure Uno.UI uses [NBGV](https://github.com/dotnet/nbgv) for its versioning. Tagging is the main driver for planning releases. ## Branches - On the `master` branch, the main development is happening and is considered unstable. The nuget packages produced end with `-dev.X`, where X is the number of commits since the last initiated release. - On the `release/beta` branch, stabilization occurs to get a stable release. The version is inherited from the branch point from master. The nuget packages produced end with `-beta.X`, where X is the number of commits since the last stable release. - On the `release/stable` branch, stable nuget packages are produced for each pushed merge or commit. The **Patch** number is increased by the number of commits since the release tagging occurred. - On `dev`, `feature`, and `project` branches, the behavior is to inherit from the base branch it was created from and create a nuget package with an experimental tag. Those branches must not be tagged. ## Creating a release ### When planning for a beta - Once a release is planned, make a branch in `release/beta` (e.g. `release/beta/1.29`), and tag the commit using the requested version (e.g. `1.29`). Do not include the patch number, as it will be added by GitHub when publishing a release. Tagging will automatically increased the version in the `master` branch by a **minor** number. - Make stabilization fixes to the `release/beta/1.29` branch. - Once the stabilization fixes are done, take the last `release/beta/1.29` commit and make a `release/stable/1.29` branch. Commits to this branch will automatically keep the `1.29` version, as the base **beta branch** was tagged `1.29`. - Publish the release on GitHub using the patch number (e.g. `1.29.0` if there where no changes) ### When planning for a release without a beta - Once a release is planned, make a branch in `release/stable` (e.g. `release/stable/1.29`), and tag the commit using the requested version (e.g. `1.29`). Tagging will automatically the version in the `master` increased by a **minor** number. - Commits to `release/stable/1.29` will automatically keep the `1.29` version. - Publish the release on GitHub using the patch number (e.g. `1.29.0` if there where no changes) ## Canaries A 'canary' in Uno parlance is a version of a real-world application (or class library) that is used to test changes to Uno. There are continuous integration (CI) pipelines configured that consume the latest development builds of Uno and produce new nightly canary versions of applications (eg [Calculator](https://github.com/unoplatform/calculator), [UADO](https://github.com/unoplatform/uado) etc). If the builds of these applications fail then then it's an early signal that overnight a breaking compilation change may have been accidentally introduced into Uno. This style of regression (binary breaking change) is rare as there are API approval tests that are run on every pull-request to master. Typically if a regression slips in then it's something that only integration testing would have picked up - ie. package incompatibility between dependencies. The Uno team does manual QA on canary failures to determine the differences between the canary build and the previous stable version of Uno. Fixes to regressions are resolved as quickly as possible by the team. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/getting-started/requirements.md --- uid: Uno.GettingStarted.Requirements --- # Supported platforms Uno Platform applications run on [Android](#android), [iOS](#ios), [Web](#webassembly), [macOS (Desktop)](#macos---desktop), [Linux](#linux), and [Windows](#windows). See below for the minimum supported versions for each platform. ## WebAssembly Uno Platform runs in browsers that support WebAssembly, including Chrome, Edge, Edge Dev, Opera, Firefox, and Safari. Desktop and mobile browser versions are supported, using the `net9.0-browserwasm` target framework. See the official WebAssembly site for [more details](https://webassembly.org/roadmap). Uno Platform runs in browsers that support WebAssembly, including Chromium-based browsers (e.g., Chrome, Edge, Arc, Opera etc.), as well as Firefox and Safari. Desktop and mobile browser versions are supported, using the `net9.0-browserwasm` target framework. See the official WebAssembly site for [more details](https://webassembly.org/roadmap). ## Windows Two paths are available: - Applications built with Uno Platform's [Skia Desktop](xref:Uno.Skia.Desktop) target framework, supporting Windows 7 and above, using the `net9.0-desktop` target framework. - Running apps built with WinAppSDK or WinUI run on Windows 10. Currently Uno.UI's API definition is aligned with [Windows 10 2004 (19041)](https://learn.microsoft.com/windows/uwp/whats-new/windows-10-build-19041), using the `net9.0-windows10.0.19041` target framework. Lower versions can be targeted. ## Android Uno Platform apps run on devices running Android 5 and above, using the `net9.0-android` target framework. At compile time, Uno Platform typically supports two versions of the Android SDK, the latest and the immediately previous (e.g. Android 15 and Android 14). It's generally recommended to use the latest version of the SDK. > [!NOTE] > This **does not** affect the runtime version. Apps compiled with Android 15 will run properly on devices running Android 10. ## iOS Uno Platform apps run on iOS 11 and above, using the `net9.0-ios` target framework. ## macOS - Desktop Uno Platform applications run on all macOS versions supported by .NET, currently macOS 10.15 and above, using the `net9.0-desktop` target framework. ## Linux Uno Platform applications run on Linux distributions and versions where latest .NET versions are supported, [listed here](https://learn.microsoft.com/dotnet/core/install/linux), using the `net9.0-desktop` target framework. Supported environments are X11 and Framebuffer. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/resources-trimming.md --- uid: Uno.Features.ResourcesTrimming --- # XAML Resource Trimming XAML Resource and Binding trimming is an optional feature used to reduce the size of the final payload of an Uno Platform application. The trimming phase happens after the compilation phase and tries to determine which UI controls are not used explicitly, and removes the associated XAML styles. The XAML styles are found through the value specified in the `TargetType` attribute. As of Uno Platform 6.0, XAML Resources Trimming is available for apps targeting WebAssembly, iOS, and Desktop. ## Using XAML Resources trimming for applications In order for an application to enable resources trimming, the following needs to be added to all projects of your solution that reference the Uno.WinUI (or Uno.UI) package, as well as the WebAssembly head project: ```xml true ``` Make sure to update your dependencies: - If you're using the .NET SDK 8.0.200 or later, you'll need to use the [Uno.Wasm.Bootstrap](https://www.nuget.org/packages/Uno.Wasm.Bootstrap) package 8.0.9 or later. - With .NET SDK 8.0.10x or earlier, you will also need to add the following package to your `.Wasm.csproj`: ```xml ``` ## Enabling XAML Resources trimming for libraries and NuGet Packages For libraries to be eligible for resources trimming, the `UnoXamlResourcesTrimming` tag must also be added. ## Troubleshooting ### Aggressive trimming The XAML trimming phase may remove controls for which the use cannot be detected statically. For instance, if your application relies on the `XamlReader` class, trimmed controls will not be available and will fail to load. If XAML trimming is still needed, the [IL Linker configuration](xref:uno.articles.features.illinker) can be adjusted to keep controls individually or by namespace. ### Size is not reduced even if enabled The IL Linker tool is used to implement this feature, and can be [controlled with its configuration file](xref:uno.articles.features.illinker). For instance, if the linker configuration file contains ``, none of the UI Controls will be excluded, and the final app size will remain close as without trimming. ## Size reduction statistics As of Uno Platform 6.0, for a `dotnet new unoapp` created app: | | without XAML Trimming | with XAML Trimming | | -------------------- | --------------------- | ------------------ | | Total IL Payload | 12.9 MB | 9.12 MB | | dotnet.wasm | 53 MB | 28.9 MB | | iOS IPA | 93 MB | 73MB | | Win32 Desktop | 200 MB | 52 MB | | macOS Desktop | 200 MB | 58 MB | --- # Source: https://raw.githubusercontent.com/unoplatform/uno.toolkit.ui/refs/heads/main/doc/helpers/responsive-extension.md --- uid: Toolkit.Helpers.ResponsiveExtension --- # ResponsiveExtension The `ResponsiveExtension` class is a markup extension that enables the customization of `UIElement` properties based on screen size. This functionality provides a dynamic and responsive user interface experience. ## Platform limitation (UWP-desktop) `ResponsiveExtension` relies on `MarkupExtension.ProvideValue(IXamlServiceProvider)` to find the target control and property for continuous value updates, and to obtain the property type to apply automatic type conversion, as its value properties are parsed as `string` by the XAML engine. Since this overload is a recent addition exclusive to WinUI, UWP projects targeting Windows won't have access to these features. Uno UWP projects targeting non-Windows platforms do not face this limitation. However, the Windows app may crash or present unexpected behavior if you attempt to use this markup on a non-`string` property. ```xml ``` You can workaround this by declaring the values as resources and using {StaticResource} to refer to them: ```xml Red Blue ... ``` ## Properties | Property | Type | Description | |-------------|--------------------|------------------------------------------------------------| | `Narrowest` | `object` | Value to be used when the screen size is at its narrowest. | | `Narrow` | `object` | Value to be used when the screen size is narrow. | | `Normal` | `object` | Value to be used when the screen size is normal. | | `Wide` | `object` | Value to be used when the screen size is wide. | | `Widest` | `object` | Value to be used when the screen size is at its widest. | | `Layout` | `ResponsiveLayout` | Overrides the screen size thresholds/breakpoints. | ### ResponsiveLayout Provides the ability to override the default breakpoints (i.e., the window widths at which the value changes) for the screen sizes. This is done using an instance of the `ResponsiveLayout` class. #### Properties | Property | Type | Description | |-------------|----------|------------------------| | `Narrowest` | `double` | Default value is 150. | | `Narrow` | `double` | Default value is 300. | | `Normal` | `double` | Default value is 600. | | `Wide` | `double` | Default value is 800. | | `Widest` | `double` | Default value is 1080. | #### Resolution Logics The layouts whose value(ResponsiveExtension) or template(ResponsiveView) is not provided are first discarded. From the remaining layouts, we look for the first layout whose breakpoint at met by the current screen width. If none are found, the first layout is return regardless of its breakpoint. Below are the selected layout at different screen width if all layouts are provided: | Width | Layout | |----------------|-----------| | 149 | Narrowest | | 150(Narrowest) | Narrowest | | 151 | Narrowest | | 299 | Narrowest | | 300(Narrow) | Narrow | | 301 | Narrow | | 599 | Narrow | | 600(Normal) | Normal | | 601 | Normal | | 799 | Normal | | 800(Wide) | Wide | | 801 | Wide | | 1079 | Wide | | 1080(Widest) | Widest | | 1081 | Widest | Here are the selected layout at different screen width if only `Narrow` and `Wide` are provided: | Width | Layout | |--------------------|--------| | 149 | Narrow | | 150(~~Narrowest~~) | Narrow | | 151 | Narrow | | 299 | Narrow | | 300(Narrow) | Narrow | | 301 | Narrow | | 599 | Narrow | | 600(~~Normal~~) | Narrow | | 601 | Narrow | | 799 | Narrow | | 800(Wide) | Wide | | 801 | Wide | | 1079 | Wide | | 1080(~~Widest~~) | Wide | | 1081 | Wide | ## Usage > [!TIP] > It is not necessary to define every template or layout breakpoint: Narrowest, Narrow, Normal, Wide, Widest. You can just define the bare minimum needed. ```xml xmlns:utu="using:Uno.Toolkit.UI" ... ``` > [!NOTE] > The `ResponsiveExtension` requires a `FrameworkElement` to initialize. In the case of non-`FrameworkElement`, like `ColumnDefinition` or `TextBlock` inlines, it uses the xaml root-object to initialize. Because of this, it will not work on non-FE defined inside a `ResourceDictionary` file, but res-dicts defined within a `Page`/`Control` are not affected. ### Custom thresholds ```xml xmlns:utu="using:Uno.Toolkit.UI" ... ... ``` > [!NOTE] > The `ResponsiveLayout` can also be provided from different locations. In the order of precedences, they are: > > - from the `Layout` property > - in the property owner's parent `.Resources` with `x:Key="DefaultResponsiveLayout"`, or the property owner's parent's parent's... > - in `Application.Resources` with `x:Key="DefaultResponsiveLayout"` > - from the hardcoded `ResponsiveHelper.DefaultLayout` which is defined as [150/300/600/800/1080] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/other/rider-eula.md --- uid: Uno.Rider.EULA --- # End-User License Agreement (EULA) for Uno Platform for Rider Plugin ## 1. IMPORTANT: READ CAREFULLY This End-User License Agreement ("EULA") is a legal agreement between you ("Licensee" or "You") and Uno Platform ("Licensor" or "We") for the use of the Uno Platform Plugin for Rider ("Software"). By installing, copying, or otherwise using the Software, you agree to be bound by the terms of this EULA. ## 2. LICENSE GRANT ### 2.1 License Subject to the terms of this EULA, Licensor hereby grants you a non-exclusive, non-transferable, revocable license to use the Software, free of charge, solely for your personal or internal business purposes. ## 3. LICENSE RESTRICTIONS ### 3.1 No Distribution You may not distribute, sublicense, rent, lease, lend, or otherwise transfer the Software to any third party. ### 3.2 Modifications You may not modify, adapt, translate, reverse engineer, decompile, or disassemble the Software, or create derivative works based on the Software. ### 3.3 Proprietary Notices You may not remove or alter any proprietary notices or labels on the Software. ## 4. OWNERSHIP ### 4.1 Intellectual Property The Software is licensed, not sold. All rights, title, and interest in and to the Software, including all intellectual property rights therein, remain with Licensor. ## 5. DISCLAIMER OF WARRANTIES ### 5.1 No Warranties The Software is provided "AS IS" and "AS AVAILABLE" without warranty of any kind, whether express, implied, or statutory, including but not limited to the implied warranties of merchantability, fitness for a particular purpose, title, and non-infringement. ## 6. LIMITATION OF LIABILITY ### 6.1 No Liability for Damages In no event shall Licensor be liable for any damages (including, without limitation, lost profits, business interruption, or lost information) arising out of your use of or inability to use the Software, even if Licensor has been advised of the possibility of such damages. ## 7. TERMINATION ### 7.1 Termination by You You may terminate this EULA at any time by uninstalling and destroying all copies of the Software. ### 7.2 Termination by Licensor Licensor may terminate this EULA immediately upon notice if: 1. You breach any term of this EULA, 2. Licensor is required to do so by law (for example, where the provision of the Software to Licensor is, or becomes, unlawful), 3. Licensor elects to discontinue providing the Software, in whole or in part. ### 7.3 Effect of Termination Upon termination, you must immediately cease all use of the Software and destroy all copies of the Software. Licensor will make reasonable efforts to notify you about Software license termination. ## 8. COLLECTION AND USE OF DATA Uno Platform uses tools to deliver certain Software features and extensions, identify trends and bugs, collect activation information, usage statistics, and track other data related to your use of the Software as further described in the most current version of Uno Platform’s Privacy Policy (located at: [https://platform.uno/privacy-policy/](https://platform.uno/privacy-policy/)). By your acceptance of the terms of this Agreement and/or use of the Software, you authorize the collection, use, and disclosure of this data for the purposes provided for in this Agreement and/or the Privacy Policy. ## 9. GOVERNING LAW ### 9.1 Governing Law This EULA shall be governed by and construed in accordance with the laws of Quebec, Canada, without regard to its conflict of law principles. ## 10. MISCELLANEOUS ### 10.1 Severability If any provision of this EULA is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable, and the remaining provisions of this EULA shall remain in full force and effect. ### 10.2 Entire Agreement This EULA constitutes the entire agreement between you and Licensor with respect to the Software and supersedes all prior or contemporaneous understandings or agreements, written or oral, regarding such subject matter. By installing or using the Software, you acknowledge that you have read this EULA, understand it, and agree to be bound by its terms and conditions. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/routed-events.md --- uid: Uno.Features.RoutedEvents --- # Uno Platform Support for Routed Events Per the WinUI contract, Uno Platform provides support for [routed events](https://learn.microsoft.com/windows/uwp/xaml-platform/events-and-routed-events-overview), events which are 'bubbled' from a child object to each of its successive parents in the XAML object tree. In most cases, you can expect routed events to behave the same way on Windows and non-Windows platforms. This article covers some of the finer technical details of Uno Platform's routed events implementation that may be relevant in advanced scenarios, eg those involving custom native (non-WinUI) views in your visual tree. ## Event Bubbling Flow ```plain [1]---------------------+ | An event is fired | +--------+--------------+ | [2]------v--------------+ | Event is dispatched | | to corresponding | [12] | element | ^ +-------yes-------------+ | | [11]---no--------------+ |<---[13]-raise on parent---yes A parent is | | | defined? | [3]------v--------------+ | | | Any local handlers? no--------+ +-------^--------------+ +-------yes-------------+ | | | | [10]----+--------------+ [4]------v--------------+ | | Event is bubbling | | Invoke local handlers | | | to parent in <--+ +--------+--------------+ | | managed code (Uno) | | | | +-------^--------------+ | [5]------v--------------+ | | | | Is the event handled | v [6]-----no-------------+ | | by local handlers? no------------>| Event is coming from | | +-------yes-------------+ | platform? | | | +------yes-------------+ | [9]------v--------------+ | | | Any parent interested | [7]-----v--------------+ | | by this event? yes-+ | Is the event | | +-------no--------------+ | | bubbling natively? no-+ | | +------yes-------------+ [12]-----v--------------+ | | | Processing finished | v [8]-----v--------------+ | for this event. | [10] | Event is returned | +-----------------------+ | for native | | bubbling in platform | +----------------------+ ``` 1. **An event is fired**: when an event is intercepted from the platform. 2. **Event dispatcher**: the source element in visual tree receive the event through its event handler. 3. **Local handlers?**: check if there is any local handlers for the event. 4. **Invoke handlers**: they are invoked one after the other, taking care of the "IsHandled" status. 5. **Handled?**: check if any of the local handlers marked the event as _handled_. 6. **Originating from platform?**: check if the source of the event is from native code. 7. **Bubbling natively?**: check if the bubbling should be done natively for this event. bubbling natively will let controls not implemented in Uno the ability to intercept the event. 8. **Returned for native bubbling**: let the event bubbling in the platform. 9. **Any Parent Interested?**: check if any parent control is interested by a "handled" version of this event (using `AddEventHandler(, , handledEventsToo: true)`). 10. **Bubbling in managed code**: propagate the event in Uno to parents (for events not bubbling natively or `handledEventsToo: true`). 11. **Parent defined?**: if the element is connected to any parent element. 12. **Processing finished**: no more handlers is interested by this event. Propagation is stopped. Native bubbling is stopped too because the event is fully handled. ## Native bubbling vs Managed bubbling A special property named `EventsBubblingInManagedCode` is used to determine how properties are propagated through the platform. This value of this property is inherited in the visual tree. This value is set to `RoutedEventFlag.None` by default, so all routed events are bubbling natively by default (except for those which can't bubble natively like `LostFocus` on iOS or `KeyDown` on Android). Bubbling natively will improve interoperability with native UI elements in the visual tree by letting the platform propagate the events. But this will cause more interop between managed and unmanaged code. You can control which events are bubbling in managed code by using the `EventsBubblingInManagedCode` dependency property. The value of this property is inherited to children. Example: ```csharp // Make sure PointerPressed and PointerReleased are always bubbling in // managed code when they are originating from myControl and its children. myControl.EventsBubblingInManagedCode = RoutedEventFlag.PointerPressed | RoutedEventFlag.PointerReleased; ``` ### Limitations of managed bubbling When using a managed bubbling for a routed event, you'll have a the following limitations: * Native container controls (scroll viewer, lists...) won't receive the event, so they can stop working properly. * Once an event is converted for _managed_ bubbling, it cannot be switched back to native propagations : it will bubble in managed code to the root, no matter how the bubbling mode is configured for this event type. ### Limitations of native bubbling * Registering handler using `handledEventsToo: true` won't receive events if they are _consumed_ (marked as _handled_) in platform components. If it's a problem, you must switch to managed bubbling for those events. If the event is _consumed_ before reaching the first managed handler, you must add a handler in one one the children to give Uno a way to intercept the event and make it bubble in managed code. * Bubbling natively can lead to many back-in-forth between managed and native code, causing a lot of interop marshalling. ## Guidelines for performance 1. When you can, prefer _managed_ bubbling over _native_ to reduce crossing the interop boundary many times for the same event. 2. Try to reduce the usage of `handledEventsToo: true` when possible. ## Differences from UWP/WinUI 3 Due to serious differences between various platforms, some compromises were done during the implementation of RoutedEvents: ### Property `OriginalSource` might not be accurate on _RoutedEventArgs_ In some cases/events, it's possible that the `OriginalSource` property of the _RoutedEventArgs_ is `null` or referencing the element where the event crossed the _native-to-managed_ boundary. This property is however always accurate for "Pointers", "Manipulation", "Gesture", and "Drag and drop" events. ### Resetting `Handled` to false won't behave like in UWP There's a strange behavior in UWP where you can switch back the `event.Handle` to `false` when intercepted by a handler with `handledEventsToo: true`. In UWP, the event will continue to bubble normally. Trying to do this in Uno can lead to unreliable results. --- # Source: https://raw.githubusercontent.com/unoplatform/uno.wasm.bootstrap/refs/heads/main/doc/runtime-execution-modes.md --- uid: Uno.Wasm.Bootstrap.Runtime.Execution --- # Runtime Execution Modes The mono for WebAssembly runtime provides three execution modes, Interpreter, and Mixed Mode Interpreter/AOT (Ahead of Time). The execution mode can be set as follows: ```xml Interpreter ``` The possible values are: - `Interpreter` (the default mode) - `InterpreterAndAOT` ## Interpreter mode This mode is the slowest but allows for great flexibility and debugging, as well as an efficient payload size. The linker mode can also be completely disabled for troubleshooting, as this will not impact the wasm payload size. ## Jiterpreter mode This mode is a hybrid between the interpreter and the AOT modes, where the interpreter is used to execute the code, but the JIT engine is used to generate some WebAssembly code on the fly. This mode is generally faster than the interpreter, but slower than the AOT mode. To enable this mode, use the following option: ```xml true ``` Additionally, some options can be used to fine-tune the Jiterpreter mode, using options found [in this file](https://github.com/dotnet/runtime/blob/6a047a9aec7a36039cffac61186b04bd3f16dbe0/src/mono/mono/utils/options-def.h#L86-L114): ```xml --jiterpreter-stats-enable --jiterpreter-estimate-heat ``` Finally, runtime statistics are maintained by the jiterpreter and can be displayed by running `INTERNAL.jiterpreter_dump_stats()` in the browser debugger console. ## Mixed Interpreter and AOT Mode This mode enables AOT compilation for most of the assemblies, with [some specific exceptions](https://github.com/dotnet/runtime/issues/50609). This mode is only active when running `dotnet publish`, `dotnet build -r Release` or any other build mode will not activate it. To enable AOT compilation on normal builds, use the following: ```xml true ``` ### Required configuration for Mixed AOT Mode or static linking on Linux - Ubuntu 20.04+ or a [container](https://hub.docker.com/r/unoplatform/wasm-build) - A [.NET SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu) >= 6.0 ## Profile Guided AOT This mode allows for the AOT engine to selectively optimize methods to WebAssembly, and keep the rest as interpreted. This gives a very good balance when choosing between performance and payload size. It also has the advantage of reducing the build time, as less code needs to be compiled down to WebAssembly. This feature is used in two passes: - The first pass needs the creation of a profiled interpreted build, which records any methods invoked during the profiling session. - The second pass rebuilds the application using the Mixed AOT/Interpreter mode augmented by the recording created during the first pass. This mode gives very good results, where the RayTracer sample of this repository goes from an uncompressed size of 5.5MB to 2.9MB. To create a profiled build: - In your Wasm csproj, add the following: ```xml true ``` - Run the application once, without the debugger (e.g. Ctrl+F5) - Navigate throughout the application in high-usage places. - Once done, either: - Press the `Alt+Shift+P` key sequence - Launch App.saveProfile() - Download the `aot.profile` file next to the csproj file - Comment the `WasmShellGenerateAOTProfile` line - Add a reference to the generated file: - If you're using the [Uno.Sdk](xref:Uno.Features.Uno.Sdk), place the file in the `Platforms/WebAssembly` folder - If you're not using the Uno.Sdk, add the following lines: ```xml ``` - Make sure that Mixed mode is enabled: ```xml InterpreterAndAOT ``` - Publish your application again, using `dotnet publish`. (`dotnet build` does not activate AOT) Note that the AOT profile is a snapshot of the current set of assemblies and methods in your application. If that set changes significantly, you'll need to re-create the AOT profile to get optimal results. ### AOT Profile method exclusion The generated profile contains all the methods found to be executed during the profiling session, but some methods may still need to be manually excluded for some reasons (e.g. runtime or compile time errors). The `WasmShellAOTProfileExcludedMethods` property specifies a semi-colon separated list of regular expressions to exclude methods from the profile: ```xml Class1\.Method1;Class2\.OtherMethod $(WasmShellAOTProfileExcludedMethods);Class3.* ``` The `MixedModeExcludedAssembly` is also used to filter the profile for assemblies, see below for more information. Dumping the whole list of the original and filtered lists is possible by adding: ```xml true ``` This will generate files named `AOTProfileDump.*.txt` in the `obj` folder for inspection. ### Mixed AOT/Interpreter Mode This mode allows for the WebAssembly generation of parts of the referenced assemblies and falls back to the interpreter for code that was excluded or not known at build time. This allows for a fine balance between payload size and execution performance. At this time, it is only possible to exclude assemblies from being compiled to WebAssembly through the use of this item group: ```xml ``` Adding assemblies to this list will exclude them from being compiled to WebAssembly. ### Troubleshooting Mixed AOT/Interpreter Mode When using the Mixed AOT/Interpreter mode, it is possible that some methods may not be compiled to WebAssembly for a variety of reasons. This can cause performance issues, as the interpreter is slower than the AOT-generated code. In order to determine which methods are still using the interpreter, you can use the following property: ```xml true ``` The logs from the AOT compiler can be found in [binlogs generated](https://aka.platform.uno/msbuild-troubleshoot) from the build. ### Increasing the Initial Memory Size When building with Mixed AOT/Interpreter modes, the initial memory may need to be adjusted in the project configuration if the following error message appears: ```text wasm-ld: error: initial memory too small, 17999248 bytes needed ``` In order to fix this, you'll need to set the [`INITIAL_MEMORY`](https://emscripten.org/docs/tools_reference/settings_reference.html?highlight=initial_memory#initial-memory) emscripten parameter, this way: ```xml ``` which will set the initial memory size accordingly. Note that setting this value to a sufficiently large value (based on your app's usual memory consumption) can improve the startup performance. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/samples-tutorials-overview.md --- uid: Uno.SamplesTutorials.Overview --- # Samples & Tutorials Welcome to the Uno Platform Samples & Tutorials section! Here, you'll find a collection of resources designed to help you learn and explore the capabilities of Uno Platform. Whether you're a beginner looking to get started with your first app, or an experienced developer seeking to expand your knowledge, we have something for everyone. ## Getting Started [**Counter App Tutorial**](xref:Uno.Workshop.Counter): Learn the basics of Uno Platform by creating a simple counter app. There are four variants of the Counter tutorial, combining markup language ([XAML](https://learn.microsoft.com/en-us/visualstudio/xaml-tools/xaml-overview) or [C# Markup](xref:Uno.Extensions.Markup.Overview)) and presentation framework ([MVVM](https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-and-mvvm) or [MVUX](xref:Uno.Extensions.Mvux.Overview)). Also, you can build the Counter tutorial using our visual designer, [Hot Design](xref:Uno.HotDesign.GetStarted.CounterTutorial). ## Workshops Dive into these hands-on workshops that guide you through building applications with the Uno Platform. These workshops will help you learn more about the tools, libraries, and patterns available in the Uno Platform, which are there to help you rapidly build high-quality applications. Finally, these workshops have been set up to provide you with optional content, allowing you to tailor the experience to your needs. - [**SimpleCalc Workshop**](xref:Workshop.SimpleCalc.Overview): A step-by-step tutorial to build a fully functional calculator. There are four paths possible for this workshop, combining markup language ([XAML](https://learn.microsoft.com/en-us/visualstudio/xaml-tools/xaml-overview) or [C# Markup](xref:Uno.Extensions.Markup.Overview)) and presentation framework ([MVVM](https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-and-mvvm) or [MVUX](xref:Uno.Extensions.Mvux.Overview)). - [**TubePlayer Workshop**](xref:Workshop.TubePlayer.Overview): A step-by-step tutorial to build an app that allows the user to search for, and stream, YouTube videos. By the end of this workshop, you'll have built a multi-platform application using Uno Platform features like [C# Markup](xref:Uno.Extensions.Markup.Overview) and [MVUX](xref:Uno.Extensions.Mvux.Overview). You'll have the option to import a UI from [Figma](https://aka.platform.uno/uno-figma) or to continue following the steps to build the UI for the application. ## In-Depth Tutorials Expand your skills with these in-depth tutorials. [**Tutorials Overview**](xref:Uno.Tutorials.Intro): A collection of tutorials to delve deeper into specific features and concepts that will show you how to use Uno Platform and solve specific problems. ## Sample Projects Explore a range of sample projects showcasing the versatility of Uno Platform. [**Chefs**](xref:Uno.Chefs.Overview): A recipe app that combines recipe browsing with interactive features, allowing users to explore step-by-step instructions, video tutorials, nutritional information, user reviews, and even create their own personalized cookbooks, all while showcasing powerful features of the Uno Platform in a practical, real-world scenario. [**Samples Repository**](xref:Uno.Samples): A curated list of sample projects that demonstrate various functionalities and use cases ranging from small single-feature samples to larger showcase applications. ## Additional Resources Further your knowledge and discover more about Uno Platform. [**Next Steps in Learning**](xref:Uno.GetStarted.NextSteps): Resources for advancing your understanding of Uno Platform, including documentation, community links, and more. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/external/uno.samples/doc/samples.md # Source: https://raw.githubusercontent.com/unoplatform/uno.samples/refs/heads/master/doc/samples.md --- uid: Uno.Samples --- # Uno.Samples The [Uno.Samples repository](https://github.com/unoplatform/Uno.Samples) gathers various working examples for Uno Platform, ranging from small single-feature samples to larger showcase applications. Browse the complete list below: ## Reference Samples ### Counter App Experience the simplicity and power of Uno.Extensions through the Counter App, a straightforward yet powerful demonstration of both basic and advanced features of the Uno Platform. This app provides a hands-on experience with fundamental concepts such as state management, user interaction, and real-time UI updates. This sample app was built using the four variants of the [Counter workshop](https://aka.platform.uno/counter-tutorial), combining markup language (XAML or C# Markup) and presentation framework (MVVM or MVUX). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/reference/Counter) ### SimpleCalc App The SimpleCalc App is a sample application designed to perform basic arithmetic operations. App was built using the four variants of the [Simple Calc workshop](https://aka.platform.uno/simplecalc-workshop), combining different markup languages (XAML or C# Markup) and presentation frameworks (MVVM or MVUX). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/reference/SimpleCalc) ### TubePlayer App The TubePlayer App is a sample application that allows users to search for, and stream Youtube videos. This app was created using the tools, libraries, and patterns provided by the Uno Platform, designed to facilitate the rapid development of high-quality applications. This sample app was built following the [Tube Player workshop](https://aka.platform.uno/tubeplayer-workshop). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/reference/TubePlayer) ### Chefs App The [Chefs app](xref:Uno.Chefs.Overview) is an engaging recipe platform where you can explore a wide variety of recipes with step-by-step instructions, video tutorials, nutritional details with charts, and user reviews. You can save your favorite recipes, filter options based on your preferences, and even discover nearby contributors on the maps. The app also offers an exciting opportunity to learn from the [Recipe Books](xref:Uno.Recipes.Overview) section, where you'll find specially selected collections that show how powerful Uno Platform features are applied in real-world scenarios, providing you with practical insights and examples to enhance your development skills. [Browse source](https://github.com/unoplatform/uno.chefs) ### Commerce App The Commerce App is a sample application that demonstrates the use of ListFeed pagination, Feedviews, and other features provided by Uno.Extensions. It illustrates how these features can be applied to create an application complete with a shopping cart, products, and more. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/reference/Commerce) ### ToDo App Dive into the essentials of task management with the ToDo App, a meticulously crafted sample application that highlights the power and flexibility of Uno.Extensions. By emphasizing the creation and organization of to-do lists, this app showcases practical applications of essential Uno.Extensions features, offering a hands-on experience in crafting responsive and user-friendly interfaces across multiple platforms. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/reference/ToDo) ### Other Samples ### Advanced XBind The {x:Bind} markup extension (new for Windows 10) is an alternative to {Binding}. {x:Bind} runs in less time and less memory than {Binding} and supports better debugging. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/AdvancedXBind) ### Android Custom Camera An Android-specific sample that shows how to start a camera capture intent, and display the result in an `Image` control. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/AndroidCustomCamera) ### Authentication with OpenID Connect (OIDC) This sample application demonstrates the usage of the `WebAuthenticationBroker` in Uno with an OpenID Connect endpoint. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/Authentication.OidcDemo) | [Follow the tutorial](https://aka.platform.uno/auth-open-id-connect) ### Auto-Suggest An implementation of the XAML `AutoSuggest` control, showing how to autofill suggestions for user input. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/AutoSuggestSample) ### Benchmark An implementation of the .NET Benchmark Control, a performance comparison tool. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/Benchmark) ### BluetoothExplorer A sample that allows the user to search for nearby Bluetooth connections and connect to a device of their choice. Uses [InTheHand.BluetoothLE](https://www.nuget.org/packages/InTheHand.BluetoothLE). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/BluetoothExplorer) ### Camera Capture UI A cross-platform implementation of the UWP `CameraCaptureUI` class that allows the user to capture audio, video, and photos from the device camera. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/CameraCaptureUI) ### CardView Migration An Uno conversion of the Xamarin `CardView` sample showing how to migrate a custom control. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/CardViewMigration) ### ChatGPT A ChatGPT sample using OpenAI SDK with C# Markup, MVUX, and immutable records. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/ChatGPT) ### Chat SignalR Demonstrates the use of [SignalR](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-3.1) in an Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/ChatSignalR) ### ChatUI A chat app featuring a UI template that's ready to connect to a service with real data. The app leverages MVUX to manage incoming data efficiently. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/ChatUI) ### Control Library An example of creating a custom control library and calling a control from your shared project. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/ControlLibrary) ### Country Data [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/CountryDataSample) ### Custom Sorting Sample app to accompany "Adding Custom Sorting Logic" blog post. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/CustomSorting) ### Dual-Screen A simple example using the `TwoPaneView` control spanned across dual screens (such as Neo or Duo dual-screen devices for example). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/DualScreenSample) ### EmbeddedResources An example that demonstrates the use of embedded resources and how to read them from your app. Note that the [`Default namespace`](https://stackoverflow.com/questions/2871314/change-project-namespace-in-visual-studio) property of all projects is the same in order for the embedded resource names to be the same on all platforms. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/EmbeddedResources) ### Entity Framework Core Demo An example of Entity Framework Core 7 with a SQLite storage for WebAssembly, WinAppSDK, iOS, and Android. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/EFCoreSQLiteSample) ### FileSavePicker iOS A working implementation of a folder-based save file picker for iOS. See [the 'iOS' section in the Windows.Storage.Pickers Uno documentation](https://platform.uno/docs/articles/features/windows-storage-pickers.html#ios) for more information. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/FileSavePickeriOS) ### Food Delivery [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/FoodDeliveryUI) ### HtmlControls This is a WASM-only sample. It is creating _native_ HTML elements that can be used directly in XAML. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/HtmlControls) ### LiteDB This is an example that utilizes the [LiteDB NuGet package](http://www.litedb.org/) to save data. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/LiteDB) ### Inserting Separators This example demonstrates the dynamic creation of a menu incorporating nested items as well as items with separators. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/InsertingSeparators) ### Localization Samples A pair of samples related to localization: - Localization: A sample showcasing the basics of localization. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/LocalizationSamples/Localization) | [Follow the tutorial](https://aka.platform.uno/how-to-localize) - RuntimeCultureSwitching: An example of changing app language while it is running. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/LocalizationSamples/RuntimeCultureSwitching) | [Follow the tutorial](https://aka.platform.uno/how-to-hotswap-app-language) ### Map Control An implementation of the UWP `Maps` control with a custom slider that binds the value of the slider to the `ZoomLevel` property of the control. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MapControlSample) ### Media Gallery Implementation of a class that enables saving media files into a gallery on Android, iOS, and Mac Catalyst. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MediaGallery) ### MVUX Samples An implementation of simple, to-the-point code samples for [MVUX](https://aka.platform.uno/mvux) topics. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MVUX) ### .NET MAUI Embedding Multiple samples that demonstrate third-party control libraries embedded in Uno Platform applications using .NET MAUI Embedding. Note that these controls work only for target platforms .NET MAUI reaches – iOS, Android, MacOS, and Windows. #### Esri ArcGIS Maps SDK for .NET Embeds the [Esri ArcGIS Maps SDK for .NET](https://aka.platform.uno/maui-embedding-tutorial-arcgis) in an Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MauiEmbedding/ArcGisApp) #### DevExpress .NET MAUI Controls Embeds the [DevExpress .NET MAUI Controls](https://aka.platform.uno/maui-embedding-tutorial-devexpress) in an Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MauiEmbedding/DevExpressApp) ### GLCanvasElement Samples Samples showcasing the usage of GLCanvasElement: - GLCanvasElementSimpleTriangle: A sample that draws a simple triangle with GLCanvasElement. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/GLCanvasElementSamples/GLCanvasElementSimpleTriangle) - GLCanvasElementRotatingCube: A sample that draws a continuously-rotating 3D cube. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/GLCanvasElementSamples/GLCanvasElementRotatingCube) #### MESCIUS ComponentOne .NET MAUI Controls Embeds the MESCIUS (formerly GrapeCity) [ComponentOne .NET MAUI Controls](https://aka.platform.uno/maui-embedding-tutorial-grapecity) in an Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MauiEmbedding/GrapeCityApp) #### Grial UI Kit Embeds the [Grial UI Kit](https://aka.platform.uno/maui-embedding-tutorial-grialkit) in an Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MauiEmbedding/GrialKitApp) #### .NET MAUI Community Toolkit Embeds the [.NET MAUI Community Toolkit](https://aka.platform.uno/maui-embedding-tutorial-mauicommunitytoolkit) in an Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MauiEmbedding/MauiCommunityToolkitApp) #### Syncfusion .NET MAUI Controls Embeds the [Syncfusion .NET MAUI Controls](https://aka.platform.uno/maui-embedding-tutorial-syncfusion) in an Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MauiEmbedding/SyncfusionApp) #### Telerik UI for .NET MAUI Embeds the [Telerik UI for .NET MAUI](https://aka.platform.uno/maui-embedding-tutorial-telerik) in an Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MauiEmbedding/TelerikApp) ### Migrating Xamarin.Forms Animations Code to accompany the [blog post](https://platform.uno/blog/migrating-animations-from-xamarin-forms-to-uno-platform/) on migrating animations from Xamarin Forms to Uno. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MigratingAnimations) ### Migrating Xamarin.Forms Effects Code samples to accompany the [blog post](https://platform.uno/blog/xamarin-forms-migration-to-uno-platform-effects-and-alternative-approaches/) on Migrating from Xamarin.Forms Effects: - XamarinFormsEffect: A reference implementation of an effect with an Android implementation. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MigratingEffects/XamarinFormsEffect) - UnoEffectSample: Showcasing how to replace Effects with either ControlTemplates or custom code accessing the native control. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/MigratingEffects/UnoEffectsSample) ### Native Frame Navigation An example showcasing how to set up the native frame navigation for iOS and Android, and frame navigation in general for Uno. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/NativeFrameNav) | [Follow the tutorial](https://aka.platform.uno/how-to-use-native-frame-nav) ### Native Style Switch An example of a toggle that allows you to switch between Native UI Controls and UWP UI Controls. The sample includes a checkbox, slider, button, and toggle. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/NativeStylesSwitch) ### Navigation (Uno.Extensions) An example series demonstrating the use of various Navigation features. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/Navigation) ### Neumorphism An example of an app containing an animated lock that you can unlock. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/Neumorphism) ### Package Resources An example that demonstrates the use of package assets and how to read them from your app. Note that WebAssembly assets are downloaded on demand, as can be seen in the browser's network tab. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/PackageResources) ### Pet Adopt An example that demonstrates the use of `PipsPager` with a `FlipView`, in an app created with the help of the [Uno Platform (Figma to C# or XAML) plugin](https://aka.platform.uno/uno-figma-plugin). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/PetAdoptUI) ### Uno PongWars Uno PongWars is a simple minigame that draws inspiration from the [PongWars HTML/JavaScript sample](https://github.com/vnglst/pong-wars), reimagined with the modern capabilities of [Uno Platform](https://platform.uno). Set in the backdrop of the eternal conflict between day and night, good and bad. This sample showcases Material design for a visually appealing experience. It demonstrates the use of [C# Markup](https://aka.platform.uno/csharp-markup) for UI development and [MVUX](https://aka.platform.uno/mvux) for state management, highlighting how Uno Platform enables building responsive games across Web (WebAssembly), Windows, Linux, Mac Catalyst, iOS, and Android from a single codebase. Explore interactive elements like a speed slider and adaptable theme colors, all running natively across platforms. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/PongWars) ### ScottPlot [ScottPlot](https://scottplot.net/) is a free and open-source plotting library for .NET that makes it easy to interactively display large datasets. Line plots, bar charts, pie graphs, scatter plots, and more can be created with just a few lines of code. Three sample apps are available: 1. **Quickstart sample** This sample app was created by following the [ScottPlot Uno Platform Quickstart documentation](https://scottplot.net/quickstart/unoplatform). 2. **Signal plot with 5 million points sample** This sample app was created the same way by following the [ScottPlot Uno Platform Quickstart documentation](https://scottplot.net/quickstart/unoplatform). Only the code-behind differs to display a signal plot with 5 million random points. 3. **SQLite Data Persistence and Large Dataset Visualization Sample** This sample demonstrates how to combine SQLite for database-driven data persistence with ScottPlot for visualizing large datasets. It showcases how to handle and visualize different plot types while persisting the data in a database for long-term storage. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/ScottPlot) | [Follow the quickstart tutorial](https://scottplot.net/quickstart/unoplatform) ### SKCanvasElement Showcase A sample demonstrating how to use `SKCanvasElement`. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/SKCanvasElementShowcase) | [Read the documentation](https://aka.platform.uno/skcanvaselement) ### SkiaSharp Test An example of the Uno implementation of SkiaSharp creating a basic canvas with text. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/SkiaSharpTest) ### SkiaSharp Skottie: Lottie file player This sample shows the use of the SkiaSharp.Skottie component, which allows the playback of [lottie files](https://airbnb.design/lottie). This component provides Lottie support for all available Uno Platform targets. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/SkottieSample) ### Splash Screen Sample An example showing how to set the splash/launch screen in Uno. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/SplashScreenSample) | [Follow the tutorial](https://aka.platform.uno/how-to-manually-add-splashscreen) ### SQLite This is a simple standalone app demonstrating the use of SQLite in an Uno application, including WebAssembly. It uses Erik Sink's [SQLitePCLRaw](https://github.com/ericsink/SQLitePCL.raw), and Frank Krueger's [sqlite-net](https://github.com/praeclarum/sqlite-net) libraries. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/SQLiteSample) ### StatusBar Theme Color An example showing how to adjust the `StatusBar` and `CommandBar` dynamically based on the current light/dark theme. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/StatusBarThemeColor) | [Follow the tutorial](https://aka.platform.uno/how-to-update-status-bar-theme-color) ### The Cat API Client An example demonstrating an approach to consuming REST web services in Uno using HttpClient. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/TheCatApiClient) | [Follow the tutorial](https://aka.platform.uno/how-to-consume-webservices) ### Time Entry Code for the Silverlight migration tutorial. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/TimeEntry) | [Follow the tutorial](https://aka.platform.uno/silverlight-migration-landing) ### Toy Car A proof of concept of a car animation using the `TwoPaneView` control spanned across dual screens (such as Neo or Duo dual-screen devices for example). Inspiration from Justin Liu's [demo app](https://twitter.com/justinxinliu/status/1281123335410049027). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/ToyCar) ### Travel UI A sample travel app that shows how a user could 1) search for locations, 2) favorite locations, and 3) view their profile as well as others' profiles. For the layout, showcases many ListViews coupled with Grids. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/TravelUI) ### Uno BackgroundWorker: Background Work [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoBackgroundWorker) ### Uno Cakes Mobile A port of Shaw Yu's Cakes Mobile App from [XampleUI](https://github.com/shawyunz/XampleUI) to Uno Platform. Used to demonstrate simple page navigation from View and ViewModel. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoCakesMobile) ### Uno Contoso A port of Microsoft's Contoso Enterprise UWP app to Uno Platform, using Prism. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoContoso) ### Uno Cupertino Theme An example showing how to set up the [`Uno.Cupertino`](https://github.com/unoplatform/Uno.Themes) library. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoCupertinoSample) | [Consult the documentation](https://aka.platform.uno/cupertino-getting-started) ### Uno Ethereum+Blockchain A sample showing how to integrate smart contracts on the Ethereum blockchain with a multi-targeted Uno Platform application. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoEthereumBlockChain) ### Uno GoodReads A sample showing how to make an app containing several pages in a TabView, as well as fake data generation to populate those pages. The blog post series for this app includes parts on [creating the home page](https://platform.uno/blog/recreating-amazon-goodreads-app-home-page-using-material-ui-figma-and-uno-platform/), [creating the author page](https://platform.uno/blog/how-to-quickly-build-goodreads-author-page-with-figma-and-uno-platform/), [creating the books page](https://platform.uno/blog/replicating-goodreads-detail-page-in-figma-with-uno-platform/), and [code generation with Figma](https://platform.uno/blog/from-figma-to-visual-studio-adding-back-end-logic-to-goodreads-app/). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoGoodReads) ### Uno Islands This sample shows how you can integrate Uno Platform XAML controls into existing WPF applications using Uno Islands. This feature allows you to enhance WPF apps with Uno Platform features by hosting Uno Platform XAML files in a Shared project and adding an Uno Island using the UnoXamlHost control. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoIslandsSampleApp) | [Follow the tutorial](https://aka.platform.uno/uno-islands) ### Uno Material Theme An example showing how to set up the [`Uno.Material`](https://github.com/unoplatform/Uno.Themes) library. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoMaterialSample) | [Consult the documentation](https://aka.platform.uno/uno-material-colors) ### Uno Onnx [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/OnnxSamples) ### Uno Scroll Reveal [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoScrollReveal) ### Uno SQlite One Drive Invoice [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoSQLiteOneDriveInvoiceSample) ### Uno Toolkit Material An example showing how to set up the [`Uno.Toolkit.Material`](https://github.com/unoplatform/uno.toolkit.ui/tree/main/src/library/Uno.Toolkit.Material) library. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoMaterialToolkitSample) | [Consult the documentation](https://aka.platform.uno/toolkit-material-getting-started) ### Windows Community Toolkit The [Windows Community Toolkit](https://learn.microsoft.com/windows/communitytoolkit/) is a collection of helper functions, custom controls, and app services. It simplifies and demonstrates common developer patterns when building experiences for Windows. > [!IMPORTANT] > **Here is the [Migration Guide from v7 to v8 for Windows Community Toolkit](https://github.com/CommunityToolkit/Windows/wiki/Migration-Guide-from-v7-to-v8) for additional information on what changed lately between these versions.** > > For some controls (`DataGrid`, `Carousel`, ect...) you will need to use **version 7.x** for them as they are no longer available in the latest 8.x version of Windows Community Toolkit. The complete list of changes is available in the [migration guide](https://github.com/CommunityToolkit/Windows/wiki/Migration-Guide-from-v7-to-v8). > > For additional information, here are the releases notes for Windows Community Toolkit: > > - [Release notes for version 7.x](https://github.com/CommunityToolkit/WindowsCommunityToolkit/releases) > - [Release notes for version 8.x](https://github.com/CommunityToolkit/Windows/releases) Depending on the version of the Windows Community Toolkit you want to use, the samples below provide examples of implementation. #### For WCT version 8.x This sample showcases the `SettingsCard` control, that can be used to display settings in your experience. It uses the default styling found in Windows 11 and is easy to use, meets all accessibility standards and will make your settings page look great! [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WindowsCommunityToolkit/Version-8.x/UnoWCTSettingsCardSample) | [Follow the tutorial](https://aka.platform.uno/install-uno-community-toolkit) #### For WCT version 7.x This sample showcases the `DataGrid` control, a dynamic grid view ported from the Windows Community Toolkit that allows for x:Bind. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WindowsCommunityToolkit/Version-7.x/UnoWCTDataGridSample) | [Follow the tutorial](https://aka.platform.uno/install-uno-community-toolkit) ### WCT DataGrid, TreeView, TabView A combined Windows Community Toolkit sample showing the DataGrid, TreeView, and TabView controls in action. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WCTDataTreeTabSample) ### WebRTC Demo of the usage of WebRTC in Uno WebAssembly. This sample establishes a direct WebRTC connection between 2 browsers and uses it to send messages between peers. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WebRTC) ### Windowing samples Provides examples of the usage of multi-window APIs in Uno Platform apps. [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WindowingSamples) ### XAML Basics: ListView [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/XamlBasics/ListViewSample) ### XamlBrewer SkiaSharp Port of the XAML Brewer WinUI3 SkiaSharp Sample application ([blog post](https://xamlbrewer.wordpress.com/2023/09/25/getting-started-with-skiasharp-in-winui-3/) and [source code](https://github.com/XamlBrewer/XamlBrewer.WinUI3.SkiaSharp.Sample)). [Browse source](https://github.com/unoplatform/Uno.Samples/tree/master/UI/XamlBrewerUnoApp) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/settings.md --- uid: Uno.Features.Settings --- # Settings > [!TIP] > This article covers Uno-specific information for managing user preferences. For a full description of the feature and instructions on using it, see [Save and load settings in a WinUI app](https://learn.microsoft.com/windows/uwp/get-started/settings-learning-track). * Settings API allows you to store the preferences of the user and preserve them across the launches of the application. ## Supported features | Feature | Windows | Android | iOS | Web (WASM) | macOS | Linux (Skia) | Win 7 (Skia) | |-------------------------------------------|---------|---------|-----|------------|-------|--------------|--------------| | `ApplicationData.Current.LocalSettings` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | `ApplicationData.Current.RoamingSettings` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ## Using Settings with Uno * On each target platform, the native user preferences APIs are used for storage. * `RoamingSettings` are not roamed across devices, as this feature has been disabled by WinUI. ## Examples ### Storing a Setting ```csharp ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; localSettings.Values["MySettingName"] = "A user setting"; ``` ### Reading a setting ```csharp ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; var localValue = localSettings.Values["MySettingName"] as string; ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/shapes-and-brushes.md --- uid: Uno.Features.ShapesAndBrushes --- # Shapes & Brushes ## Implemented Shapes | Shape | Android | iOS | macOS | Wasm (1) | | | ----------- | ------- | ------- | ------- | -------- | ------------------------------------------------------------ | | `Ellipse` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.ellipse) | | `Line` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.line) | | `Path` | Yes | Yes | Yes | Yes (2) | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.path) | | `Polygon` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.polygon) | | `Polyline` | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.polyline) | | `Rectangle` | Yes (3) | Yes (3) | Yes (3) | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.rectangle) | Notes: 1. All shapes on _Wasm_ platform (including `Rectangle`) are rendered as `SVG` elements. 2. On _Wasm_, only the `Data=` text format is implemented. On other platforms, you can use either the _data_ or the geometries. 3. Rectangles on _Android_, _iOS_, and _macOS_ are rendered as a simple border. ## Implemented Shapes properties | Shape | Android | iOS | macOS | Wasm | | | -------------------- | ------- | ---- | ----- | ------- | ------------------------------------------------------------ | | `Fill` (1) | Yes | Yes | | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.fill) | | `GeometryTransform` | No | No | | No | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.geometrytransform) | | `Stretch` | Yes | Yes | | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.stretch) | | `Stroke` (1) | Yes | Yes | | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.stroke) | | `StrokeDashArray` | No | Yes | | No | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.strokedasharray) | | `StrokeDashCap` | No | No | | No | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.strokedashcap) | | `StrokeDashOffset` | No | No | | No | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.strokedashoffset) | | `StrokeEndLineCap` | No | No | | No | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.strokeendlinecap) | | `StrokeLineJoin` | No | No | | No | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.strokelinejoin) | | `StrokeMiterLimit` | No | No | | No | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.strokemiterlimit) | | `StrokeStartLineCap` | No | No | | No | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.strokestartlinecap) | | `StrokeThickness` | Yes | Yes | | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.shapes.shape.strokethickness) | Notes: 1. See next section for _fill_ & _stroke_ brushes limitations. ## Implemented Brushes / Properties | Brush | Android | iOS | macOS | Wasm | Skia Desktop | | | ---------------------------------- | ------- | ------- | ---- | ------------------------------------------------------------ | ---------------------------------- | | `AcrylicBrush` | Yes (3) | Yes (3) | Yes (3) | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.media.acrylicbrush) | | `ImageBrush` | Yes (1) | Yes (1) | | No | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.media.imagebrush) | | `LinearGradientBrush` | Yes (2) | Yes (2) | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.media.lineargradientbrush) | | `RadialGradientBrush` (WinUI 2.4+) | Yes | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.media.radialgradientbrush) | | `RevealBrush` (WinUI 2.0+) | No | No | No | No | No | [Documentation](https://learn.microsoft.com/windows/winui/api/microsoft.ui.xaml.media.revealbrush) | | `SolidColorBrush` | Yes | Yes | Yes | Yes | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.media.solidcolorbrush) | | `XamlCompositionBrushBase` | No | No | No | No | Yes | [Documentation](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.media.xamlcompositionbrushbase) | Notes: 1. `ImageBrush` on Android & iOS can only be used as a `Fill` / `Background` brush; it is not supported for `Stroke` / `BorderBrush` properties and **the image needs to be a local asset**. They are not supported as text's `Foreground`. 2. On Android and iOS, gradient brushes (`LinearGradientBrush` & `RadialGradientBrush`) are only used as a `Fill` / `Background` brush. 3. On Android, iOS, and macOS `AcrylicBrush` has some limitations. Please see the following section for details. ## AcrylicBrush Uno Platform supports the `Backdrop` version of `AcrylicBrush` (blurring in-app content behind element) on all targets. In addition, on macOS we support the `HostBackdrop` acrylic (blurring content behind the app window). The brush currently has an important limitation on Android, iOS, and macOS: it can be used **only on elements which have no children**. Eg., if you wanted to have an acrylic effect in the background of a `Grid` with child content, then you would add a `Border` with no inner child behind the other content in the `Grid` and set the acrylic background on the `Border`, rather than set it directly on the `Grid`: ```xml ``` Because many WinUI styles use `AcrylicBrush` on elements which violate this condition, we made the brush use solid fallback color by default on targets other than WASM. To enable the brush, you need to explicitly set the `AlwaysUseFallback` property to `false`: ```xml ``` ## Brushes Usages Where you can use which brushes | Usage | SolidColorBrush | ImageBrush | GradientBrush | | -------------------------------------------- | --------------- | -------------------- | --------------- | | `Background` property (many controls/panels) | Yes | Yes (except on Wasm) | Yes | | `BorderBrush` (`Border`, `Panel`) | Yes | No | Yes (Skia, Android), partial (iOS, WASM) [see below] | | `Foreground` (`TextBlock`) | Yes | No | Yes (Wasm only) | | `Fill` (Shapes) | Yes | Yes (except on Wasm) | Yes | | `Stroke` (Shapes) | Yes | No | Yes (Wasm only) | ## Gradient border brush limitations on WASM and iOS There are limitations to support for gradient border brushes on some targets. Currently these are: - WebAssembly - gradient borders cannot be applied properly on an element which uses `CornerRadius` - iOS/macOS - gradient borders cannot be applied reliably when `RelativeTransform` is applied on it If these conditions apply, the border will instead be rendered using `SolidColorBrush` provided by the `FallbackColor` property. As default WinUI Fluent styles are using `ElevationBorder` brushes in many places, so we created a presenter that provides a "fake" gradient for these cases - `Uno.UI.Controls.FauxGradientBorderPresenter`. For custom styles we suggest you provide a custom "layered" approach that simulates the border, as this presenter is specifically built to support WinUI style-specific scenarios where: - Exactly two gradient stops are present - `FallbackColor` of the brush is equal to the "major" gradient stop - The brush is applied "vertical" - so the "minor" stop is either on top or on the bottom of the control --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/signalr.md --- uid: Uno.Development.SignalR --- # SignalR [SignalR](https://learn.microsoft.com/aspnet/core/signalr/introduction?view=aspnetcore-7.0) is an ASP.NET Core library that allows server-side code to be instantly pushed to the client. ## Prerequisites - Visual Studio 2019 or higher - Azure account (to publish SignalR service) ## Steps 1. Create `ASP.NET Core web application` in Visual Studio and name it `UnoChat.Service`. ![project-template](Assets/project-structure.JPG) 2. Add [SignalR Hub](https://learn.microsoft.com/aspnet/core/tutorials/signalr?view=aspnetcore-7.0&tabs=visual-studio#create-a-signalr-hub) to your `[YourProjectName].Service` project in a `Hubs` folder. 3. In your `Startup.cs` file, add your `SignalR` service and a `CORS policy` to the `ConfigureServices` method. ```csharp public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddSignalR(); services.AddCors(o => o.AddPolicy( "CorsPolicy", builder => builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() )); } ``` 4. In your `Configure` method, add your CORS policy and `Hubs` endpoint ```csharp app.UseCors("CorsPolicy"); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapHub("/yourProjectHub"); }); ``` You now have a SignalR service that you can use with your Uno application! --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/silverlight-migration/silverlight-migration-landing.md --- uid: Uno.SilverlightMigration.Landing --- # Migrating from Silverlight to WinUI and Uno Platform Documentation Silverlight will reach the end of support on October 12, 2021. As luck would have it, a new Windows UI framework is about to RTM in March 2021 – WinUI – the modern native UI platform of Windows. And with WinUI launch there is a renewed desire by C# and XAML developers to write single codebase applications for Windows and the Web. Enter Uno Platform. Hello “Rich Internet Applications (RIA)” again! There are a number of pages of Silverlight migration documentation to help you with migration – accompanying source code, techniques and considerations you need to make when migrating your Silverlight application. ## Table of contents * [Silverlight to Uno Migration Introduction](00-overview.md) * [Create the Uno solution for UWP and WASM](01-create-uno-solution.md) * [Considering navigation – comparing Silverlight and UWP navigation](02-considering-navigation.md) * [Reviewing the app startup – comparing Silverlight and UWP app lifecycle](03-review-app-startup.md) * [Migrating the home page XAML and styles – comparing XAML](04-migrate-home-page-xaml-and-styles.md) * [Switching to string resources – comparing the Silverlight and UWP approach to resources](05-string-resources.md) * [Dialogs and errors – Silverlight ChildWindow to UWP ContentDialog and console logging](07-dialogs.md) * [Data access services – high-level review of alternatives to WCF RIA Services, data and authentication](08-data-access-overview.md) * [Client Authentication – securing access to data APIs](09-client-auth-service.md) * [Implementing a singleton token service – pattern for implementing singletons and creating a token service to secure data APIs](10-implementing-singleton-token-service.md) * [Implementing an identity service client – implementing an authentication service](11-implementing-identity-service-client.md) * [Migrating the authentication UI – migrating the Silverlight login UI, alternative to Silverlight DataForm](12-migrate-auth-ui.md) * [Integrating authentication and navigation – WIP – will migrate the role check before navigating](13-integrating-auth-and-navigation.md) * [Implement the time entry service – WIP – will implement the Time Entry Service client](14-implement-timeentry-services.md) * [Migrating the time entry UI – WIP – will look at alternatives to the Silverlight DataGrid](15-migrate-timeentry-ui.md) * [Wrap-up – WIP – will summarize the key migration activities](20-wrap-up.md) * [The TimeEntry Sample apps – overview of sample apps and build instructions](98-timeentry-samples.md) * [Useful resources](99-useful-resources.md) ## Next unit: Silverlight to Uno Migration [![button](assets/NextButton.png)](00-overview.md) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/skia-libraries-trimming.md --- uid: Uno.Features.SkiaLibrariesTrimming --- # Skia Native Libraries Trimming [Desktop only] Starting with Uno 6.2, we are trimming rare Skia/HarfBuzz build variants by default. Skia/HarfBuzz build variants were taking over 75% of the total published application size when doing a generic build. By default, we now bundle win-x64, win-arm64, osx (includes arm64 + x64), linux-x64, linux-arm64 and linux-arm. You may disable this behavior by adding a `true` property to your csproj. You can also customize the build variant list by adding a `...` property to your csproj. Where `...` is a semi-colon delimited list of the following values: - win-arm64 - win-x64 - win-x86 - osx - linux-arm - linux-arm64 - linux-loongarch64 - linux-musl-arm - linux-musl-arm64 - linux-musl-loongarch64 - linux-musl-riscv64 - linux-musl-x64 - linux-riscv64 - linux-x64 - linux-x86 For example, you may use: `win-arm64;win-x64`. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/solution-building-single-targetframework.md --- uid: Build.Solution.TargetFramework-override --- # Improve Build Times with Visual Studio The Uno Platform template **prior to Uno Platform 5.2** provides a cross-targeted Class library that includes multiple target frameworks, and your application may contain your own cross-targeted projects as well. This document explains how to make your builds faster. > [!NOTE] > For projects created with Uno Platform 5.2 or later, the Uno.Sdk takes care of building appropriate target frameworks for the selected debugger target when starting a debugging session. Optionally, you can follow [our migration guide](xref:Uno.Development.MigratingToSingleProject) to use the new project structure. If you want to always build one target framework you can follow the guide below. ## Reduce the number of built TargetFrameworks (5.2 templates and later) When using an Uno Platform 5.2 template or later, in the **Folder Explorer**, you can apply the following steps to build only a subset of target frameworks using a configuration file. To do so: - Create a file named `solution-config.props.sample` next to your `.sln` file, with this content: ```xml ``` Make sure to replace `net9.0` and `-windows10.0.19041.0` with the appropriate version from your `.csproj` project. - You can commit `solution-config.props.sample` to your source control. - Next, make a copy of `solution-config.props.sample` to `solution-config.props`. This file is [automatically loaded](https://github.com/unoplatform/uno/blob/71f1d5ab067c0dcfad2f4cccd310e506cdeaf6bf/src/Uno.Sdk/targets/Uno.Import.SolutionConfig.props#L9) by the `Uno.Sdk`. - If you're using git, add this `solution-config.props` to your `.gitignore`. > [!NOTE] > This avoids altering the target frameworks or your own CI, as well as other clones made by other developers. - Follow the directives from the file, uncommenting one of the `OverrideTargetFramework` to your choosing. - In the project head, as well as any other libraries using the `Sdk="Uno.Sdk"`, add the following block immediately below the last `` line: ```xml $(OverrideTargetFramework) ``` - Once done, if you're in Visual Studio, you may need to close and re-open your solution or otherwise click the reload button. For other IDEs, the projects will reload automatically. At this point, you'll notice that the list of target frameworks available in the debugger will have been reduced to the list you added in `OverrideTargetFramework`. ## Improve performance using the Uno Platform templates (5.1 and earlier) When using an Uno Platform 5.0 template, in the **Solution Explorer**, you'll find a folder named **Solution Items**, and a file named `solution-config.props.sample`. You can follow the directions specified in this file, or follow them here: - Right-click on the root item (your solution name) and **Open in file explorer** - Locate the `solution-config.props.sample` and make a copy named `solution-config.props` in the same folder - Back in Visual Studio, and for your convenience you can right-click on `Solution Items` and add `solution-config.props` Now that we have configured this file, let's say that you want to debug for WebAssembly: - In the `solution-config.props` file, uncomment the line that mentions `Wasm` or `WebAssembly` then save it. - For the change to take effect, close and reopen the solution, or restart Visual Studio. Repeat this process when changing your active development platform. > [!NOTE] > The `solution-config.props` is automatically included in a `.gitignore` file to avoid having your CI environment build only for one target. ## Cross-targeted library builds in Visual Studio While building with the command line `dotnet build -f net7.0-ios` only builds the application's head and the class library for `net7.0-ios`, as of Visual Studio 17.8, class library builds are considering all target frameworks, [regardless of the project head's target framework](https://developercommunity.visualstudio.com/t/Building-a-cross-targeted-project-with-m/651372) being built. _(Please help the Uno Platform community by upvoting the issue!)_ Considering that during development, it is common to work on a single platform at a given time, the two sections below contain a suggested set of changes to the Uno Platform solution that can be performed on the solution to restrict the active build platform, and therefore significantly speed up build times and make intellisense respond faster. Choose the section covering your cases, whether you're using a solution built using Uno Platform 5.0 templates or created with an earlier version. ## Improve your own solution (4.9 and earlier) If you created your solution with an earlier version of Uno Platform, you can make some modifications to make your build faster: 1. Let's create a set of solution filters to ensure that individual project heads can be loaded: 1. Create a new app template with **iOS**, **Android**, **WebAssembly** and **Windows** targets selected. 1. Right click on the **.Mobile** and **.Wasm** projects and select **Unload Project** 1. On the top level Solution node, right-click to select **Save As Solution Filter**, name the filter **MyApp-Windows-Only.slnf** 1. Right-click on the **Mobile** project, select **Reload Project** 1. Unload the **.Windows** project, then save a new solution filter called **MyApp-Mobile-Only.slnf** 1. Repeat the operation with the **.Wasm** project, with a solution filter called **MyApp-Wasm-Only.slnf** These solution filters will prevent Visual Studio to restore NuGet packages for TargetFrameworks that will be ignored by the configuration done below. 1. Now, next to the solution file, create a file named `targetframework-override.props`: ```xml $(MyAppTargetFrameworkOverride) ``` 1. Also next to the solution file, create a file named `solution-config.props.sample`: ```xml ``` 1. Next, in all projects of the solution which are cross-targeted (with multiple TargetFrameworks values), add the following lines right after the `PropertyGroup` which defines ``: ```xml ``` The file should then look like this: ```xml net7.0-windows10.0.19041;net7.0;net7.0-ios;net7.0-android ``` > [!NOTE] > If the template is created with `dotnet new`, the path will instead be `../targetframework-override.props` 1. Create a copy of the file `solution-config.props.sample` next to itself, and name it `solution-config.props` 1. If using git, add this specific file to the `.gitignore` so it never gets committed. This way, each developer can keep their own version of the file without corrupting the repository. 1. Commit your changes to the repository. At this point, your solution is ready for single-TargetFramework use. For example, to work on `net7.0-ios`: 1. Before opening the solution, open the `solution-config.props` file and uncomment `MyAppTargetFrameworkOverride` to contain `net7.0-ios` 1. Open the `MyApp-Mobile-Only.slnf` solution filter in Visual Studio 1. You should only see the **.Mobile** and **Class Library** projects in your solution 1. When building and debugging the app, you'll only now build for the target specified in `solution-config.props`. > [!IMPORTANT] > When changing the `MyAppTargetFrameworkOverride` value, make sure to close the solution and reload it so the build system recognizes properly the change. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/splash-screen.md --- uid: Uno.Development.SplashScreen --- # How to manually add a splash screen Projects created using Uno Platform 4.8 or later have the Uno.Resizetizer [package](https://www.nuget.org/packages/Uno.Resizetizer) installed by default. Simply provide an SVG file, and the tool handles the task of generating various image sizes. That package updates the build process to automate configuring a splash screen for each platform. While the new templates simplify adding a splash screen, this article covers how to add one to your application manually if using Uno.Resizetizer is not warranted. > [!TIP] > If your solution was generated using the older templates, it is possible to configure these projects to use Uno.Resizetizer instead. That process makes the steps below unnecessary. > > See the guide [How-To: Get Started with Uno.Resizetizer](xref:Uno.Resizetizer.GettingStarted#unosplashscreen) for more information. ## Step-by-step instructions ### 1. Shared splash screen image resources * Review [Assets and image display](xref:Uno.Features.Assets) to understand the present support for various image asset types * Prepare your images intended for the splash screen under different resolutions, eg: | File name | Width | Height | |----------------------------|:---:|:---:| | SplashScreen.scale-100.png | 216 | 148 | | SplashScreen.scale-125.png | 270 | 185 | | SplashScreen.scale-150.png | 324 | 222 | | SplashScreen.scale-200.png | 432 | 296 | | SplashScreen.scale-300.png | 648 | 444 | | SplashScreen.scale-400.png | 864 | 592 | * Refer to this [table](xref:Uno.Features.Assets#table-of-scales) to see values for the different scales required. * You can instead provide only a single image named `SplashScreen.png` without the `scale-000` qualifier. > [!NOTE] > Regardless if you provide a single image or multiple images, you would always refer to this image as `SplashScreen.png`. * Add these images under the `Assets\` folder of the `MyApp` project, right-click on each image, go to `Properties`, and set their build action as `Content`. ### 2. Windows * In the `MyApp` project, open the file `Package.appxmanifest` and navigate to `Visual Assets > SplashScreen`. * Make sure the value for `Preview Images > Splash Screen` is set to `Assets\SplashScreen.png` ![uwp-splash-screen](Assets/uwp-splash-screen.JPG) ### 3. Android * In the `MyApp` project, open the subfolder for `Platforms/Android` * Navigate further to the file at `Resources/values/Styles.xml` * `Styles.xml` contains Android-specific customizations for the splash screen. Inside, look for the `AppTheme` style and add an `` under it: ```xml @drawable/splash ``` * Navigate upward to `Resources/drawable`, and create a new XML file named `splash.xml`: ```xml ``` > [!IMPORTANT] > Before Uno.UI 4.5, the `@drawable/assets_splashscreen` source should be `@drawable/splashscreen`. > See the [breaking changes](https://github.com/unoplatform/uno/releases/tag/4.5.9) section of that release. * Make sure `splash.xml` is added as an `AndroidResource` in the Droid project file: `[Project-name].Droid.csproj`. * This is not always done automatically and may occur if `splash.xml` was created and added outside the IDE. ```xml ``` > [!TIP] > After modifying `splash.xml`, you may run into errors like these while trying to debug: > > ```console > Resources\drawable-mdpi\SplashScreen.png : error APT2126: file not found. > Resources\drawable-hdpi\SplashScreen.png : error APT2126: file not found. > ``` > > Simply rebuild the Android target to get rid of these errors. ### 4. iOS * In the `MyApp` project, open the subfolder for `Platforms/iOS` * Delete the old splash screen files: * `Resources\SplashScreen@2x.png` * `Resources\SplashScreen@3x.png` * `LaunchScreen.storyboard` * Create a new **StoryBoard** named `LaunchScreen.storyboard`: * Right-click the project subfolder you're working with (ex: `MyApp/Platforms/iOS`) * Select **Add** > **New Item...** * Create a **Visual C#** > **Apple** > **Empty Storyboard** * In the **Toolbox** window, drag and drop a **View Controller** and then an **ImageView** inside the **View Controller** * Enable the **Is initial View Controller**-flag on the **View Controller**. ![`viewcontroller-imageview`](Assets/viewcontroller-imageview.png) * To have an image fill the screen, set your constraints as below ![ios-constraints](Assets/ios-constraints.png) * Set the **Content Mode** to **Aspect Fit** ![ios-content-fit](Assets/ios-content-fit.png) * In the **Properties** > **Storyboard Document** window, select the **Can be Launch Screen** checkbox. ![can-be-launch](Assets/can-be-launch.png) * Close the designer and open the `.storyboard` file. * Add your image path to the `Image View` ```xml ``` * Open `info.plist` and update the `UILaunchStoryboardName` value to `LaunchScreen`. > [!TIP] > iOS caches the splash screen to improve the launch time, even across re-installs. In order to see the actual changes made, you need to restart the iPhone or simulator. Alternatively, you can rename the `CFBundleIdentifier` in `info.plist` incrementally (eg: MyApp1 -> MyApp2) before each build. ### 5. WebAssembly * The default splash screen configuration for WebAssembly is to use the Uno Platform logo as a placeholder. * An `Platforms/WebAssembly/WasmScript/AppManifest.js` file contains some app settings, including properties to customize its splash screen. This file is found in the `MyApp` project. #### General properties You can customize the splash screen image and background color by adjusting several key properties: | Property | Description | Notes | |----------|-------------|-----| | `accentColor` | Color of the progress indicator's filled-in portion displayed during application launch | Default value is `#F85977` | | `displayName` | Default name visible in the browser window's title to represent the application | N/A | | `splashScreenColor` | Background color of the screen displayed during application launch | Any values assigned to the theme-aware properties are ignored unless this property is set to `transparent`.

If the theme-aware properties are unassigned, the default browser background color will be used instead. | | `splashScreenImage` | Path to an image that will be visible on the screen displayed during application launch | You currently need to set an explicit scale for the image | > [!TIP] > `splashScreenColor` allows you to maintain a background color regardless of the system theme. However, a simple method to make the splash screen theme-aware is to assign `transparent` as its value or by omitting that property altogether. #### Theme-aware properties > [!NOTE] > The section below contains optional properties. If nothing is assigned to them, the value of `splashScreenColor` will be used under both themes as the background color. Uno Platform supports theme-aware backgrounds as an optional customization for splash screens. Set the following properties to adjust the splash screen based on a system theme: | Property | Description | Notes | | --- | --- | --- | | `lightThemeAccentColor` | Color of the progress indicator's filled-in portion displayed during application launch if a system light theme is enabled | Default value is `#F85977` | | `darkThemeAccentColor` | Color of the progress indicator's filled-in portion displayed during application launch if a system dark theme is enabled | Default value is `#F85977` | | `lightThemeBackgroundColor` | Background color of the screen displayed during application launch if a system light theme is enabled | Default value is `#F3F3F3` | | `darkThemeBackgroundColor` | Background color of the screen displayed during application launch if a system dark theme is enabled | Default value is `#202020` | * Code example: ```javascript var UnoAppManifest = { splashScreenImage: "Assets/SplashScreen.scale-200.png", splashScreenColor: "transparent", displayName: "SplashScreenSample" } ``` ## See also * [Completed sample on GitHub](https://github.com/unoplatform/Uno.Samples/tree/master/UI/SplashScreenSample) * [Ask for help on Discord](https://www.platform.uno/discord) * [Uno.Resizetizer repository](https://github.com/unoplatform/uno.resizetizer) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/step-counter.md --- uid: Uno.Features.StepCounter --- # Step counter (Pedometer) > [!TIP] > This article covers Uno-specific information for Pedometer. For a full description of the feature and instructions on using it, see [Pedometer Class](https://learn.microsoft.com/uwp/api/windows.devices.sensors.pedometer). * The `Windows.Devices.Sensors.Pedometer` class allows counting steps taken with the device. ## Supported features | Feature | Windows | Android | iOS | Web (WASM) | macOS | Linux (Skia) | Win 7 (Skia) | |-------------------|---------|---------|-----|------------|-------|--------------|--------------| | `GetDefaultAsync` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | `ReadingChanged` | ✔ | ✔ | ✔ | ✖ | ✖ | ✖ | ✖ | | `ReportInterval` | ✔ | ✔ | ✔ | ✖ | ✖ | ✖ | ✖ | ## Using Pedometer with Uno * The `GetDefault` method is available on all targets and will return `null` on those which do not support `Pedometer` or devices that do not have such a sensor. * Ensure to unsubscribe from the `ReadingChanged` event when you no longer need the readings, so that the sensor is no longer active to avoid unnecessary battery consumption. * `ReportInterval` property on WASM is currently not supported directly. Uno uses an approximation in the form of raising the `ReadingChanged` event, only when enough time has passed since the last report. The event is raised a bit more often to make sure the gap caused by the filter is not too large, but this is in line with the behavior of Windows' `Pedometer`. * `DirectionalAccuracy` is not reported on iOS, so it will always return `Unknown`. ## Platform-specific requirements ### [**Android**](#tab/Android) On Android, the first reading returns the cumulative number of steps since the device was first booted up. The sensor may not correctly respect the requested reporting interval, so the implementation does this manually to make sure the `ReadingChanged` events are triggered only after the `ReportInterval` elapses. Since Android 10, your application must declare the permission to use the step counter sensor by adding the following `uses-feature` declaration to the `AndroidManifest.xml` in your project: ```xml ``` ### [**iOS**](#tab/iOS) The first reading on iOS returns the cumulative number of steps from 24 hours back to the current moment. Unfortunately, in case the tracking was not enabled before, this will likely return 0 steps. Once the tracking is enabled, `ReadingChanged` will be triggered and the step count will be updated appropriately. Make sure to add the following capability declaration to your `Info.plist` file, otherwise, the API will crash at runtime. ```xml NSMotionUsageDescription Some reason why your app wants to track motion. ``` --- ## Example ### Capturing sensor readings ```csharp var pedometer = await Pedometer.GetDefaultAsync(); pedometer.ReportInterval = 10000; pedometer.ReadingChanged += Pedometer_ReadingChanged; private async void Pedometer_ReadingChanged(Pedometer sender, PedometerReadingChangedEventArgs args) { // If you want to update the UI in some way, ensure the Dispatcher is used, // as the ReadingChanged event handler does not run on the UI thread. await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { CumulativeSteps = args.Reading.CumulativeSteps; CumulativeStepsDurationInSeconds = args.Reading.CumulativeStepsDuration.TotalSeconds; Timestamp = args.Reading.Timestamp.ToString("R"); }); } ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/studio/studio-feedback.md --- uid: Uno.Platform.Studio.Feedback --- # Providing Feedback for Uno Platform Studio We deeply value your feedback for **Uno Platform Studio** and its tools ([**Hot Design®**](xref:Uno.HotDesign.Overview), [**Hot Reload**](xref:Uno.Platform.Studio.HotReload.Overview), and [**Design-to-Code**](xref:Uno.Figma.GetStarted)) to ensure we can deliver the best possible experience. > [!IMPORTANT] > To start using **Hot Design**, ensure you are signed in with your Uno Platform account. **Follow [these instructions](xref:Uno.GetStarted.Licensing) to register and sign in**. > > - Hot Design is available on all platforms. See the list of **[current known issues](xref:Uno.HotDesign.Troubleshooting)**. > - Hot Design **does not support C# Markup** and is **only available with XAML and .NET 9+**. > - Hot Design is **not available for the WinAppSDK target framework (`netX.0-windowsX.X.X`)** at this time. > - Hot Design relies on **[Hot Reload](xref:Uno.Platform.Studio.HotReload.Overview)** for updates, so be sure to check the [current support for your OS, IDE, and target platforms](xref:Uno.Platform.Studio.HotReload.Overview#supported-features-per-os) before testing. Here’s how you can share your feedback: ## 1. GitHub Feedback Navigate to the [Uno Platform Studio GitHub repository](https://github.com/unoplatform/studio) to: - **Report issues or bugs**: Share any unexpected behavior or issues you encounter with the tools or documentation. - **Propose enhancements**: Suggest features or improvements to enhance Uno Platform Studio, its tools, and its documentation. - **Start discussions**: Engage in conversations about Uno Platform Studio and its tools. For more details, refer to the [feedback guidelines](https://github.com/unoplatform/studio/blob/main/README.md). ## 2. Hot Design Feedback Menu You can also provide feedback directly while using **Hot Design** in a live, running application. Use the **Feedback** menu to: - **Report an issue/bug** - **Suggest a feature** - **Ask a question** Follow these steps to access the feedback menu: 1. Click on the three-dot button in the [Hot Design Toolbar](xref:Uno.HotDesign.GetStarted.Guide#toolbar). 2. Navigate to **Help** > **Feedback**. 3. Choose one of the following options: - **Report an issue/bug** - **Suggest a feature** - **Ask a question** Refer to the image below for guidance: ![Hot Design Feedback Menu](Hot%20Design/Assets/hot-design-feedback-menu.png) ## Additional Support For further assistance, visit our [Discord Server](https://platform.uno/uno-discord), where our engineering team and community will be happy to assist you. For organizations seeking a deeper level of support beyond our community support, please [contact us](https://platform.uno/contact). We look forward to your feedback and thank you for helping us improve Uno Platform Studio and its tools! --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/studio/studio-overview.md --- uid: Uno.Platform.Studio.Overview --- # Uno Platform Studio Overview **Uno Platform Studio** is a set of productivity tools designed to enhance developer productivity, be it for design handoff, to radically improving developer inner dev loop with Hot Reload and the industry-first, cross-platform runtime visual designer for .NET, Hot Design®. **Uno Platform Studio** empowers developers to stay in their flow, enabling seamless cross-platform app development for every platform .NET runs on. ![Introducing Uno Platform Studio](Assets/Introducing-Uno-Platform-Studio.png) ## New in Uno Platform Studio 2.0: Hot Design® Agent + Uno MCP + App MCP **Hot Design® Agent** is an AI-powered assistant designed for rapid UX/UI creation and enhancement within your application. It leverages data contexts and live previews to help developers design, refine, and interact with user interfaces in real time. Built on deep knowledge of Uno Platform and your running app, it simplifies cross-platform .NET design, enabling intuitive and efficient workflows. [Learn more](xref:Uno.HotDesign.Agent) **Uno MCP** provides structured, semantic access to Uno Platform’s complete knowledge base—covering documentation, APIs, and best practices—empowering AI agents and developers with the intelligence they need to build better experiences. Meanwhile, **App MCP** brings intelligent automation to life by enabling AI agents to interact directly with live Uno Platform applications, creating a seamless bridge between design, development, and execution. [Learn more](xref:Uno.Features.Uno.MCPs) **Uno Platform Studio** revolutionizes how developers design, build, and iterate on their applications by leveraging purpose-built tools that streamline your workflow: - **[Hot Design®](xref:Uno.HotDesign.Overview)** The industry-first, runtime visual designer, for cross-platform .NET Applications. Hot Design® transforms your running app into a Designer, from any IDE, on any OS, to create polished interfaces with ease. [Get started](xref:Uno.HotDesign.GetStarted.Guide) - **[Hot Reload](xref:Uno.Features.HotReload)** Reliably update any code in your app and get instant confirmation your changes were applied, with a new Hot Reload Indicator to monitor changes while you develop. [Get started](xref:Uno.HotReload.GetStarted.Guide) - **[Design-to-Code](xref:Uno.Figma.GetStarted)** Generate ready-to-use, well-structured XAML or C# Markup directly from your Figma designs with one click, completely eliminating manual design handoff. [Get started](xref:Uno.Figma.GetStarted) ## Why Choose Uno Platform Studio? **Uno Platform Studio** is designed to make cross-platform development fast, seamless, and enjoyable: - Stay in your flow by working directly in your preferred IDE and Figma design tool on any OS. - Build apps for every platform .NET runs on. - Streamline workflows with tools that integrate design, development, and iteration. ## What's the difference between Uno.Sdk and Uno Platform Studio? **Uno.Sdk** is the core SDK that powers the Uno Platform, enabling you to build cross-platform applications using C# and XAML from a single project. **Uno Platform Studio** is a suite of productivity tools that enhance your development experience, including Hot Design®, Hot Design® Agent, Uno MCPs, Hot Reload, and Design-to-Code. As the **Uno Platform Studio** is built on top of **Uno.Sdk**, it's only available to applications that have been created, or updated, to use the **Uno.Sdk**. If you haven't updated your project to use the **Uno.Sdk**, you can do so by following the [migration guide](xref:Uno.Development.MigratingFromPreviousReleases). Start your journey with **Uno Platform Studio** today by **[registering an account](https://platform.uno/my-account/)**, and take your app development productivity to the next level! --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/supported-features.md --- uid: Uno.Development.SupportedFeatures --- # Uno Platform Features > [!NOTE] > If you are looking for `UnoFeature` reference, check the [Using the Uno.Sdk article](xref:Uno.Features.Uno.Sdk) instead. ## Development Flow - Uno Platform's WinUI/UWP XAML - **Windows-first development** - **Faster compilation** for most of the development cycle, including UI code. iOS, Android, WebAssembly, macOS and Linux can be tested for platform-specific features. - Ability to develop responsive layout in Windowed mode using Windows 10. - Allows for **edit and continue** support from VS2017+ - Allows for **UI and Non-UI code edit and continue** support - Conditional platform features access - All XAML controls have **access to native properties** through conditional XAML - Ability to **add native controls in XAML** - Full WinUI/UWP availability at compile time - Allows for the **compilation of open-source libraries** that depend only on WinUI/UWP and multi-targeted nuget packages - **XamlBehaviors library** support - macOS Compilation ## Features List ### Animations - Animations on any DependencyProperty and AttachedProperty - Visual States (declared animations, advanced setters) - Visual State Groups (multi-state controls) - StateTriggers (Orientation-based responsive design) - Custom StateTriggers (e.g network state-based states) - XAML-defined animation storyboards - Binding expressions to Attached properties (Storyboard setters) ### Styling - Attached Property Style binding (advanced styling, control reuse) - Control templating (without the need of renderers) (control reuse, white-labeling) - TemplateBinding (control reuse) ### Data Binding - Value Precedence - Inheritance - Mode - Trigger - x:Bind with support functions - Converters - Attached Properties binding - RelativeSource.Self ### Design Fidelity - Text Inlines Binding - Text Independent trimming and wrapping - Text Character Spacing - Text Spans (Bold, Italic, Underline) - [Path & Shapes support](features/shapes-and-brushes.md) - Updatable Shapes support - Image Brush support in shapes - `FontIcon` support - Merged Dictionary support ### Responsive Design - Layout constraints \[Min/Max][Width/Height] - Binding SourceTriggers (TextBox immediate vs. focus lost interactions) - DependencyProperty Inheritance (Color, text style propagation) ### Runtime Performance - CoreDispatcher Priority support (Large UIs performance) - `x:DeferLoadStrategy="Lazy"`, `x:Load="false"` and `x:Load="{x:Bind ...}" support (responsive design performance) - Image explicit size support (performance) - Event tracing (sub-millisecond [ETL performance profiling](Assets/diagnostics.PNG)) - Internal logging - Reflection-less bindings (complex UI performance) - Binding suspension and restoration - Expando Binding - DynamicObject Binding - DataTemplate and ControlTemplate reuse, pooling, and prefetching ### ListView - `Selector` - Any `ItemsPanel` support - `ItemsStackPanel` - `ItemsWrapGrid` - Group sticky headers - Group collection tracking - Variable item size - Snap points (with ScrollIntoView support) - `ISupportIncrementalLoading` support - `ICollectionView` support with SelectedItem ### Command Bar - WinUI/UWP Command bar support - Native Command bar support (Image, title, back, Opacity, ...) - Global back button support ### Media - `SolidColorBrush` - `ImageBrush` - `LinearGradientBrush`, with animations support. - Local assets support with automatic conversion from WinUI conventions ### Others - Native property access from any XAML control - Localization for any property via x:Uid, using scoped or unscoped `.resw` files (Size localization) - FocusManager (advanced large forms navigation, dynamic UIs) - Advanced WebView support (scripting, scrolling, string, custom agent) - Automatic asset generation from WinUI assets - Native element embedding - Panels (Grid, StackPanel with `Spacing`, RelativePanel, Canvas) - Custom Panels - Popups/Dialogs - Work with the usual Windows tooling - Animations - Easing functions - Theme Transitions - Entrance animations - XAML Behaviors - AttachedProperty Binding - AttachedProperty Styling - Custom `MarkupExtension` support - Brightness Control - Native and Custom dialogs - Support for StateTriggers - ProgressBar - [Pointer Events](features/routed-events.md) - [Routed Events](features/routed-events.md) - GeneralTransform.TransformBounds - Window.Services.Store (Store ID and links) - Windows.ApplicationModel.Package (InstallDate) - `ApplicationData.LocalSettings` and `RoamingSettings` support - Windows.UI.ViewManagement.ApplicationView.VisibleBounds (Rounded corner/notched screen support) - `SimpleOrientationSensor` - ApplicationData Folders - ScrollViewer Snap Points, Extent, Viewport Properties - ScrollViewer MakeVisible, BringIntoView - InputPane (Occlusion, Visibility, Events, ...) - [Pointer Capture](features/routed-events.md) - Slider - FlipView - Customizable Date and Time Pickers - Orientation management - Accessibility (Font Scaling, screen readers) - Xamarin UITest support and full _Dependency Property_ access - StatusBar management (occlusion, color, events) - Runtime XAML reader - Phased binding (x:Phase) - XAML code-behind event registration - WriteableBitmap - NavigationView - BitmapIcon - MediaPlayer - ViewBox - PersonPicture - ScrollBar ## WinUI Specific Controls (Pre 3.0) - [NumberBox](https://learn.microsoft.com/uwp/api/microsoft.ui.xaml.controls.numberbox?view=winui-2.3) - [TwoPaneView](https://learn.microsoft.com/uwp/api/microsoft.ui.xaml.controls.twopaneview?view=winui-2.3) ### Non-UI Features - Windows.UI.Storage (StorageFile, StorageFolder, Settings) - Windows.UI.Application - Windows.UI.CoreDispatcher - UI Priority dispatch - Windows.Graphics.Display.DisplayInformation orientation - Windows.Media.SpeechRecognition - Windows.Media.Capture.CameraCaptureUI --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/supported-libraries.md --- uid: Uno.Development.SupportedLibraries --- # Supported 3rd-party libraries This article lists some of the 3rd-party libraries supported by Uno Platform. ## Control libraries * [Windows Community Toolkit](uno-community-toolkit.md) * [Syncfusion](https://github.com/syncfusion/Uno.SfChart) * [Lightning Chart](https://platform.uno/blog/lightningchart-introduces-uno-platform-support/) * [Live Charts](https://platform.uno/blog/livecharts-announces-support-for-uno-platform/) * [ScottPlot](https://scottplot.net/quickstart/unoplatform/) * [OxyPlot](https://github.com/HavenDV/H.OxyPlot) ## Presentation frameworks * [CommunityToolkit.Mvvm](https://learn.microsoft.com/dotnet/communitytoolkit/mvvm/) * [Prism](https://prismlibrary.com/) * [ReactiveUI](https://www.reactiveui.net/) * [MVVMCross](https://www.mvvmcross.com/) ## Design and theming * [Uno.Material](external/uno.themes/doc/material-getting-started.md) * [Uno.Cupertino](external/uno.themes/doc/cupertino-getting-started.md) ## HTTP and API clients * [Refit](xref:Uno.Extensions.Http.Overview#refit) - Strongly-typed REST API client * [Kiota](xref:Uno.Extensions.Http.Overview#kiota) - OpenAPI/Swagger client generator ## Data and storage * [SQLite](https://www.sqlite.org/) - Local database for all platforms including WebAssembly * [LiteDB](https://www.litedb.org/) - Embedded .NET NoSQL database * [Json.NET (Newtonsoft.Json)](https://www.newtonsoft.com/json) - Popular JSON framework for .NET ## Logging * [Serilog](https://serilog.net/) - Flexible logging library ## Other libraries * [SkiaSharp](https://www.nuget.org/packages/SkiaSharp.Views.Uno) * [Shiny .NET](https://shinylib.net/mediator/extensions/unoplatform/) If we're missing a library here, [drop us a line](https://github.com/unoplatform/uno/issues/new/choose) or [create a Pull Request](https://github.com/unoplatform/uno/blob/master/doc/articles/supported-libraries.md)! --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/svg.md --- uid: Uno.Features.SVG --- # Using SVG images Uno Platform supports using vector SVG graphics inside of your cross-platform applications, using the `SvgImageSource` class. SVG Images can also be used through [`UnoImage` with Resizetizer](xref:Uno.Resizetizer.GettingStarted). ![Uno SVG sample](../Assets/features/svg/heliocentric.png) ## How to use SVG ## [**Single Project**](#tab/singleproject) To use an SVG, for iOS and Android, you'll need to add the `Svg` [Uno Feature](xref:Uno.Features.Uno.Sdk#uno-platform-features) as follows: ```xml ... Svg; ... ``` On Desktop Skia and WebAssembly, the feature is enabled by default. To include an SVG file, you will need to place it in a folder named `Svg` (e.g. `Assets\Svg\MyFile.svg`). This is required in order to avoid [Uno.Resizetizer](xref:Uno.Resizetizer.GettingStarted) transform the file into a set of scaled PNGs files. Now, you can display the SVG image in an `Image` by referencing it from the `Source` property. For example: ```xml ``` ## [**Legacy Project**](#tab/legacyproject) To use SVG, install the following NuGet packages into the iOS, macOS, Android, and Skia projects: * `Uno.WinUI.Svg` * `SkiaSharp.Views.Uno.WinUI` * `Svg.Skia` (required only for the Skia project) > [!NOTE] > If the `Uno.[UI|WinUI].Svg` package is not installed, you will get a warning when an `.svg` image is loaded. > If the `Svg.Skia` package is not installed, you will get an error when an `.svg` image is loaded for the Skia project. > [!IMPORTANT] > The `Uno.[UI|WinUI].Svg` package is not needed for WebAssembly, and must only be installed on the Mobile and Skia heads. It must not be in any other class libraries of your solution. Add the SVG Image to the app project and make sure that the build action is set to Content. Now, you can display the SVG image in an `Image` by referencing it from the `Source` property. For example: ```xml ``` --- You can also explicitly use `SvgImageSource`: ```xml ``` ## Supported features by platform SVG is supported on all Uno Platform targets. * On Android, iOS, macOS, and Skia, Uno Platform uses SkiaSharp to render the SVG graphics. * On WebAssembly, the browser renders the SVG images directly. * On Windows, the OS is responsible for SVG rendering (and complex SVG files may not render properly). ## When to use SVG Because SVG requires to be parsed initially before rendering and its vector-based form needs to re-render each time the size of the image changes, it may not be suitable for all scenarios. For ideal performance, we recommend using SVG for in-app vector graphics and icons but prefer bitmap image formats in other cases. In case you run into performance issues, test switching from SVG to a bitmap image format to see if it alleviates the problem. You may also consider using SVG rasterization (see below). If you need to keep your Android or iOS app package size as small as possible, it is also preferable to avoid using SVG, as the package depends on SkiaSharp. ## SVG rasterization support For improved performance, you can use the `RasterizePixelHeight` and `RasterizePixelWidth` properties of `SvgImageSource` to rasterize the SVG image when first loaded. When rasterized, the image will always scale this rasterized version of the SVG image instead of rendering the vector-based graphics. For example: ```xml ``` Will render as: ![Scaled up](../Assets/features/svg/rasterized.png) > [!NOTE] > This feature is not available on WebAssembly where the rendering is handled directly by the browser. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/themeresource-internals.md --- uid: Uno.Contributing.ThemeResource --- # Theme resource internals for contributors This article looks at the way theme resources are handled under the hood, including the way that resource assignations are resolved, and the way that assigned resources are updated, for example when the active theme changes in the running application (from light to dark or vice versa). It's aimed at Uno Platform contributors looking to better understand the internals of the feature. From hereon, an understanding of the contract and consumer-visible behavior of [XAML resources](https://learn.microsoft.com/windows/apps/design/style/xaml-resource-dictionary) and [ThemeResource markup extensions](https://learn.microsoft.com/windows/apps/design/style/xaml-theme-resources) is assumed. Review those links if you need a refresher on how the feature is expected to behave. ## Resource resolution When a theme resource or static resource assignation is resolved, the framework looks through all ResourceDictionaries that are in scope from the point of assignation, in a defined order, for a resource with a matching key. ### Priority of ResourceDictionaries Scope and priority are determined by the following rules: - if the `{ThemeResource}` assignation is itself inside a dictionary, other than inside a template, then the containing dictionary is checked first. - if the assignation is on a `frameworkElement` or the logical child of a `frameworkElement`, and the `frameworkElement` is in the visual tree, then the `Resources` of the `frameworkElement` and its visual ancestors are checked in order, outwards from the `frameworkElement`. This typically occurs when the element is first loaded into the visual tree, or when the active theme changes (see below). - the `Application.Resources` dictionary is checked next. - if the XAML containing the assignation comes from an external assembly (ie, a class library), then next the dictionaries within that assembly are checked. (Note that Uno's behavior departs somewhat from WinUI here, because only the `Themes/Generic.xaml` dictionary from that assembly should be checked - see [issue #4424](https://github.com/unoplatform/uno/issues/4424).) - finally, 'system level' resources are checked. This simply means the resources that are defined within the Uno.UI assembly. ### Searching within a ResourceDictionary Resolving a resource within a `ResourceDictionary` is a somewhat complex operation in its own right, because a `ResourceDictionary` may contain nested dictionaries within its `MergedDictionaries` and `ThemeDictionaries` collection properties, those dictionaries may in turn contain dictionaries, and so on recursively. This can be thought of as a 'resource tree' that is traversed in order to find a match for a given resource key. The matching resource is determined according to the following priority: - the key-value pairs directly added to the `ResourceDictionary` are considered first. - ResourceDictionaries in the `MergedDictionaries` collection are searched, in reverse order, in other words the last dictionary added has first priority. - The `ResourceDictionary` in `ThemeDictionaries` whose key matches the active theme will be searched. This will either be the dictionary whose key exactly matches the active theme (eg "Dark" key when dark theme is active), or the "Default"-keyed dictionary if it exists and no exact match is found. Note that if an exact-match dictionary is found, the "Default" dictionary will be ignored, even if the resource key is not found within the exact-match dictionary. - finally, if the search was initiated from consumer code, eg via indexing or the public `TryGetValue()` method, then system level resources will be checked, as defined above. Searching for a resource is a very frequently performed operation and a bottleneck during page loading, and as such is heavily optimized within `ResourceDictionary`, via caching, dedicated internal resource keys, and other mechanisms. It may also be optimized 'outside' `ResourceDictionary` by using a tool to create a single flat merged dictionary out of multiple top-level ControlName.xaml files, which is faster to search (`O(1)`) than many nested MergedDictionaries. ## Resource updates The resource update machinery can be broadly split into two parts: registering resource assignations for updates; and propagating updates to assigned values when the active theme changes. ### Registering assignations for updates ThemeResource assignments can only be created in XAML - WinUI provides no way to create them in code. Thus, in Uno, all assignations come ultimately from either [XamlFileGenerator](https://github.com/unoplatform/uno/blob/master/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs) or XamlReader/[XamlObjectBuilder](https://github.com/unoplatform/uno/blob/master/src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs). There are 3 cases for ThemeResource assignations that are handled differently: 1. Assigning an ordinary dependency property to a ThemeResource reference. 2. Assigning an ordinary non-dependency property to a ThemeResource reference. 3. Assigning the Value property of a [Setter](https://learn.microsoft.com/uwp/api/windows.ui.xaml.setter) to a ThemeResource reference. In case 1., we create a `ResourceBinding`, an internal Uno-only type that inherits from `BindingBase`, that binds the property to the ThemeResource, allowing its value to be subsequently reevaluated when the owner enters the live visual tree and also when the active theme changes. This is done through the `ResourceResolver` static class. As much as possible, XAML-generated code should use helper intermediaries that will not change when the underlying implementation evolves. XAML-generated code compiled with older versions of Uno may run against newer Uno versions, in the case of 3rd-party libraries, and we don't want to introduce breaking changes that could be avoided. In case 2. we can't create a binding because we don't have a dependency property to bind to. The best we can do in this case is to do a one-time resolution of the value. In case 3., the details of the ThemeResource reference are captured on the `Setter` (via the `ApplyThemeResourceUpdateValues()` extension method). When the setter is later applied, either within a `Style` or within a `VisualState`, then the ThemeResource assignation will be applied according to either case 1. or case 2. depending on whether the target property is a DependencyProperty or not. In cases 1. and 3., at the time of registration we capture the 'context'. This is an instance of `XamlParseContext`, which captures the assembly in which the ThemeResource reference is declared, and is used to determine the scope which should be used when resolving it. ### Propagating updates on theme change A theme change update is propagated whenever the active theme changes. This may be because a change in the system theme was detected (eg the user enabled dark mode in their system settings, or perhaps it changed automatically based on the time of day), or because the `RequestedTheme` property on the root element of the visual tree was programmatically changed (eg to support an in-app light/dark mode toggle). In either case, the `Application.OnResourcesChanged()` method will be called. It will: 1. Update all items in the tree of ResourceDictionaries rooted by `Application.Resources`. 2. Update all items in system resources, ie ResourceDictionaries defined within the Uno.UI assembly. 3. Update all items within the active visual tree. Cases 1. and 2. are functionally identical, operating on different root dictionaries. Note that changing the active theme is something that we expect to happen relatively rarely during any given app session, and usually due to explicit user input. The relevant code nonetheless sits alongside and interacts with code paths that are very heavily used during any app session: loading controls, applying bindings, resolving resources etc, which all have an important impact on perceived performance. As much as possible, the theme change machinery has been and should be architected to place its 'performance burden' upon the update itself, rather than the code supporting the update which is called frequently during ordinary activities of the app. #### Updating resource bindings Resource bindings are managed by `DependencyObjectStore`. It checks if any properties of its parent instance are resource-bound, by checking if it has a non-empty resource bindings list. If so, for each binding, it tries to re-resolve the correct theme value from the ResourceDictionaries currently in its scope. If it can, it will then set the value, with the correct precedence as captured when the binding was created. The `DependencyObjectStore` will also propagate the resource binding update to any 'logical children' that are also DependencyObjects, but not FrameworkElements. (Child FrameworkElements will be updated during the traversal of the visual tree.) For performance reasons, the `DependencyObjectStore` does not explicitly maintain a list of logical children. Instead, the `InnerUpdateChildResourceBindings()` method looks at all current property values and pushes the update to those that are either DependencyObjects or collections of DependencyObjects. In case this is inadequate, it also tries to cast to the `IAdditionalChildrenProvider` internal interface, which allows a type to explicitly specify its logical child dependency objects. #### Update other FrameworkElement properties The `FrameworkElement.UpdateThemeBindings()` method is virtual. In addition to updating resource bindings, some controls override it to perform specific updates required when the theme changes. For example, `TextBlock` and `Control` set the default-precedence value of Foreground to the appropriate one for the current theme. #### Updating 'theme-change-aware' entities Some non-FrameworkElement types may also need to react to the theme change. This is supported by the `IThemeChangeAware` internal interface, whose `OnThemeChanged()` method is invoked after resource bindings are applied. For example, `Storyboard` implements this interface in order to re-apply long-running animations with the correct updated values. ## Hot reload updates The ResourceBinding machinery is reused for supporting XAML Hot Reload on standalone ResourceDictionaries. When an application is run in debug with XAML Hot Reload enabled, ResourceBindings are created for all resources assignations, including StaticResource assignations. When a standalone ResourceDictionary XAML file is edited, the file is re-parsed and then an update is triggered in much the same way as if the active theme had changed, so that any modified resources will be reapplied. To support these different use cases whilst preserving correct semantics, resource bindings have a `ResourceUpdateReason` flag associated them. This ensures that static resources are not updated when they shouldn't be while hot reload is operating. --- # Source: https://raw.githubusercontent.com/unoplatform/uno.themes/refs/heads/master/doc/themes-overview.md --- uid: Uno.Themes.Overview --- # Themes Overview

Themes design systems

## Summary - [Material Overview](material-getting-started.md) - [Cupertino Overview](cupertino-getting-started.md) - [Fluent Overview](fluent-getting-started.md) ## Uno Themes Styles [Uno Themes](https://github.com/unoplatform/Uno.Themes) is the repository for add-ons NuGet packages that can be added to any new or existing Uno solution. It contains three libraries: - `Uno Themes`: a library that contains the base resources, extensions, and helper classes for the different design system libraries - `Uno Material`: a library that contains styles following the [Material 3](https://m3.material.io/) Design System - `Uno Cupertino`: a library that contains styles following the [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines) Both `Material` and `Cupertino` libraries help you style your application with a few lines of code including: - Color system for both Light and Dark themes - Styles for existing WinUI controls like Buttons, TextBox, etc. ## Fluent Controls Styles Uno Platform 3.0 and above supports control styles conforming to the [Fluent design system](https://www.microsoft.com/design/fluent). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/troubleshooting-memory-issues.md --- uid: Uno.Contributing.MemoryIssues --- # Troubleshooting Memory Issues Uno Platform provides a set of classes aimed at diagnosing memory issues related to leaking controls, whether it be from an Uno.UI issue or from an invalid pattern in user code. ## WebAssembly memory profiling Starting from [Uno.Wasm.Bootstrap](https://github.com/unoplatform/Uno.Wasm.Bootstrap) 3.2, the Xamarin Profiler can be used to profile memory usage. See [this documentation](https://github.com/unoplatform/Uno.Wasm.Bootstrap#memory-profiling) for additional details. ## Enable Memory instances counter 1. Install the `Uno.Core` NuGet package; 2. In your application, as early as possible in the initialization (generally in the `App.cs` or `App.xaml.cs` constructor), add and call the following method: ```csharp using Uno.UI.DataBinding; using Uno.UI.DataBinding; using System.Threading.Tasks; using Uno.Extensions; using Uno.Logging; // .... private void EnableViewsMemoryStatistics() { // // Call this method to enable Views memory tracking. // Make sure that you've added the following : // // builder.AddFilter("Uno.UI.DataBinding", LogLevel.Information ); // // in the logger settings, so that the statistics are showing up. // var unused = Windows.UI.Xaml.Window.Current.Dispatcher.RunAsync( CoreDispatcherPriority.Normal, async () => { BinderReferenceHolder.IsEnabled = true; while (true) { await Task.Delay(1500); try { BinderReferenceHolder.LogReport(); var inactiveInstances = BinderReferenceHolder.GetInactiveViewBinders(); // Force the variable to be kept by the linker so we can see it with the debugger. // Put a breakpoint on this line to dig into the inactive views. inactiveInstances.ToString(); } catch (Exception ex) { this.Log().Error("Report generation failed", ex); } } } ); } ``` You'll also need to add the following logger filter: ```csharp builder.AddFilter("Uno.UI.DataBinding.BinderReferenceHolder", LogLevel.Information ); ``` As well as this package NuGet (you will need to update to the latest Uno.UI nuget version): ```xaml ``` It is also possible to create diffs between memory snapshots by using the `BinderReferenceHolder.LogInactiveViewReferencesStatsDiff` method. ## Interpreting the statistics output The output provides two sets of DependencyObject in memory: - Active, for which the instances have a parent dependency object (e.g. an item in a Grid) - Inactive, for which the instances do not have a parent dependency object When doing back and forth navigation between pages, instances of the controls in the dismissed pages should generally be collected after a few seconds, once those have been cleared from the `Frame` control's forward stack (done after every new page navigation). Searching for inactive objects first is generally best, as those instances are most likely kept alive by cross references. This can happen when a Grid item has a strong field reference to its parent: ```csharp var myItem = new Grid(){ Tag = grid }; grid.Children.Add(myItem); ``` For Xamarin.iOS specifically, see [this article about performance tuning](https://learn.microsoft.com/xamarin/ios/deploy-test/performance). ## Profiling on Desktop (Skia) On the Desktop target, the Visual Studio diagnostic session can be used to investigate application memory to find issues such as memory leaks. Follow [this guide from Microsoft](https://learn.microsoft.com/en-us/visualstudio/profiling/memory-usage-without-debugging2?view=vs-2022&pivots=programming-language-dotnet). > [!TIP] > If the "Memory Usage" is not listed under the Available Tools of the Performance Profile. Make sure "YourProjectName (Desktop)" is selected as the target. If that still doesn't work, open the `YourProjectName.csproj` and manually replace the following line temporarily: > > ```xml > > net9.0-desktop > ``` > > You may need to close and re-open the solution after making the change. --- > [!TIP] > During profiling, you may use `GC.Collect()` to forces an immediate GC(Garbage Collection) without having to wait. It should be noted that the GC does not take effect immediately, and sometimes it may take more than one GC call for all loose objects to be collected. For rigorousness, it is recommended to call GC twice and wait a few seconds before taking a memory snapshot when troubleshooting memory leaks. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/troubleshooting-source-generation.md --- uid: Uno.Contributing.SourceGeneration --- # Troubleshooting Source Generation Before Uno 5.0, Source Generation in Uno was done in one of two ways: - Using [C# 9.0 source generators](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/) - Using [Uno.SourceGeneration](https://github.com/unoplatform/uno.sourcegeneration) generators C# 9.0 generators are enabled automatically when using .NET 5 and up projects, otherwise Uno.SourceGeneration generators are used. It is possible to enable C# 9.0 generators for non .NET 5+ projects by adding this: ```xml 9.0 true ``` Conversely, Uno.SourceGeneration generators can be used by setting this: ```xml false ``` Starting with Uno 5.0, the only way for source generation is using Roslyn source generators, and setting `UnoUIUseRoslynSourceGenerators` has no effect. ## Adding generated files C# pragma In some cases, the generated code may use patterns that cause C# to raise warnings, and in order to silence those warnings, the generated code can contain a set of custom C# pragma. The MSBuild `XamlGeneratorAnalyzerSuppressions` item is used to configure suppressions, with the format `CATEGORY-CODE_TEXT`: 1. Starting with Uno Platform 5.3, the generator will create a `#pragma warning CODE_TEXT` entry at the top of the generated files. 1. Prior to Uno Platform 5.3, the generation depends on the category: - If `CATEGORY` is `csharp`, the generator will create a `#pragma warning CODE_TEXT` entry at the top of the generated files - If `CATEGORY` is anything else, `SuppressMessageAttribute` attributes will be applied on generated classes. To define a pragma, in your csproj add the following: ```xml ``` It is also possible to have `SuppressMessageAttribute` specified in the code, by using the following syntax: ```xml ``` ## Debugging the XAML Source Generator It is possible to step into the XAML generator by adding the following property: ```xml True ``` Setting this property will popup a Debugger window allowing the selection of a visual studio instance, giving the ability to set breakpoints and trace the generator. ## Dumping the XAML Source Generator state In the context of hot reload or otherwise, troubleshooting the generator's state may be useful. Using this feature, the generator will dump the following for **each** run: - CommandLine arguments - MSBuild properties - MSBuild items - Generated source files To enable this feature, add the following property: ```xml path_to_folder ``` > [!WARNING] > A lot of data may be generated in some cases, make sure to disable this feature once it is no longer needed and don't forget to cleanup. ## Troubleshooting Uno.SourceGeneration based generation When building, if you're having build error messages that looks like one of those: - `the targets [Microsoft.Build.Execution.TargetResult] failed to execute.` - `error : Project has no references.` There may be issues with the analysis of the project's source or configuration. **Security notice: That `binlog` files produced below should never be published in a public location, as they may contain private information, such as source files. Make sure to provide those in private channels after review.** The Source Generation tooling diagnostics can be enabled as follows: - In the project file that fails to build, in the first `PropertyGroup` node, add the following content: ```xml true ``` - Make to update or add the `Uno.SourceGenerationTasks` to the latest version - When building, in the inner `obj` folders, a set of `.binlog` files are generated that can be opened with the [msbuild log viewer](http://msbuildlog.com/) and help the troubleshooting of the generation errors. - Once you've reviewed the files, you may provide those as a reference for troubleshooting to the Uno maintainers. - The best way to provide those file for troubleshooting is to make a zip archive of the whole solution folder without cleaning it, so it contains the proper diagnostics `.binlog` files. **Make sure to remove the `UnoSourceGeneratorUnsecureBinLogEnabled` property once done.** If ever the need arises to view the generated source code of a *failing* CI build, you can perform the following steps: 1. In your local branch, locate the one of build yaml files (located in the root Uno folder): - `.azure-devops-android-tests.yml` - `.azure-devops-wasm-uitests.yml` 2. At the bottom of the yaml files, you'll find *Publish...* tasks, right above these tasks, copy/paste the following code to create a task which will copy all generated source files and put them in an artifact for you to download: ```yml - bash: cp -r $(build.sourcesdirectory)/obj/Release/g/XamlCodeGenerator/ $(build.artifactstagingdirectory) condition: failed() displayName: "Copy generated XAML code" ``` Therefore, in the case of Uno, an example of would be */src/SamplesApp/SamplesApp.Droid*. 3. Once the build fails and completes, you can download the corresponding build artifact from the Artifacts menu to view your generated source files. **Remember that you should never submit this change, this is temporary and only for viewing generated code.** ## Xaml fuzzy matching The XAML source generator used to do fuzzy matching for types. This doesn't match Windows behavior and can cause performance issues. The MSBuild property `UnoEnableXamlFuzzyMatching` controls whether fuzzy matching is enabled or not. The property was introduced in Uno 4.8 and defaulted to `true`. Starting with Uno 5.0, this property defaults to `false`. It is planned that fuzzy matching will be removed completely Uno 6. Note that for XAML-included namespaces (for example `android`, `ios`, etc.), The default namespaces are used (it's considered as if it is `http://schemas.microsoft.com/winfx/2006/xaml/presentation`). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/tutorials-intro.md --- uid: Uno.Tutorials.Intro --- # How-tos and tutorials This section gathers how-tos and longer tutorials that will show you how to use Uno Platform and solve specific problems. [!include[Inline table of contents](includes/how-tos-and-tutorials-inline-toc.md)] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/unhandled-exceptions.md --- uid: Uno.Development.UnhandledExceptions --- # Generic Unhandled Exceptions handler Starting Uno Platform 5.4, we are generating a generic handler for `Application.UnhandledException`, in line with WinUI approach. When debugger is attached, unhandled framework exceptions will be logged in the debugger output by default. If you also want the debugger to break on unhandled exceptions, set the `BreakOnUnhandledExceptions` property to `true` in the `.csproj`: ```xml true ``` If you want to disable the generated `Application.UnhandledException` handler altogether, define the `DISABLE_GENERATED_UNHANDLED_EXCEPTION_HANDLER` constant in `.csproj` instead: ```xml $(DefineConstants);DISABLE_GENERATED_UNHANDLED_EXCEPTION_HANDLER ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-app-solution-structure.md --- uid: Uno.Development.AppStructure --- # Solution Structure This guide briefly explains the structure of an app created with either the [`dotnet new unoapp` template](xref:Uno.GetStarted.dotnet-new) or the [Uno Platform Template Wizard](xref:Uno.GettingStarted.UsingWizard). It is particularly aimed at developers who have not worked with cross-platform codebases before. ## The project files in an Uno Platform app After creating a new blank solution called `MyApp`, it will contain the following project: ![Uno Platform solution structure](Assets/solution-structure.png) The `MyApp.csproj` project supports Mobile (iOS/Android), WebAssembly, Desktop (macOS, Linux X11/Framebuffer, Windows 7+), and Windows App SDK targets. You'll find below details about the contents of the solution. ### Platforms The Platforms folder contains platform specific files for targets supported by Uno Platform: - `Desktop` uses the [Uno Platform Skia Desktop](xref:Uno.Features.Uno.Sdk) support for Windows 7+, Linux, and macOS - `Android` contains files and assets specific to Android Phones, Tablets, TVs, and watches - `iOS` targets Apple's iOS devices, Phones, and Tablets - `WebAssembly` targets the browser using WebAssembly - `Windows` targets the [Windows App SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/) to run on Windows ### Properties This folder contains the debug profile configuration. This is used to choose where to debug your Skia Desktop app (Local Windows or WSL), the Web Server for your WebAssembly app, or Package and Unpackaged modes for Windows App SDK. ### Assets This folder contains [all the assets](xref:Uno.Features.Assets) (images, splash screens, data, ...) that are published as part of the app. ## Other project files - `App.xaml` and `App.xaml.cs` are the common entry point for the app. The generic app setup runtime code generally goes here. - `MainPage.xaml` and `MainPage.xaml.cs` contain the main UI of the app. - `GlobalUsings.cs` contains the [global usings](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive#global-modifier) define for the project. - `app.manifest` contains [Windows specific configuration](https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests) for `net9.0-desktop` and `net9.0-windows` targets. - `Package.appxmanifest` contains metadata about the application such as the app name and description. ### Solution items This solution folder contains the configuration for the whole solution: - `global.json` contains the [.NET SDK configuration](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json) as well as the Uno.Sdk version to use. See [our documentation](xref:Uno.Features.Uno.Sdk) on how to update it. - `Directory.Build.props` and `Directory.Build.targets` contain common solution configurations applied to all projects. - `Directory.Packages.props` contains the [NuGet Central Package Management](https://learn.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management) package versions. ## Further information See additional guides on handling platform-specific [C# code](xref:Uno.Development.PlatformSpecificCSharp) and [XAML markup](xref:Uno.Development.PlatformSpecificXaml) in an Uno Platform project. ## Next Steps Learn more about: - [Uno Platform features and architecture](xref:Uno.GetStarted.Explore) - [Hot Reload feature](xref:Uno.Features.HotReload) - [Troubleshooting](xref:Uno.UI.CommonIssues) - [List of views implemented in Uno](implemented-views.md) for the set of available controls and their properties. - You can head to [How-tos and tutorials](xref:Uno.Tutorials.Intro) on how to work on your Uno Platform app. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-build-error-codes.md --- uid: Build.Solution.error-codes --- # Uno error codes ## MSBuild Errors ### UNOB0001: Cannot build with both Uno.WinUI and Uno.UI NuGet packages referenced This error code means that a project has determined what both `Uno.WinUI` and `Uno.UI` packages are referenced. To fix this issue, you may be explicitly referencing `Uno.UI` and `Uno.WinUI` in your `csproj`, or you may be referencing a NuGet package that is incompatible with your current project's configuration. For instance, if your project references `Uno.WinUI`, and you try to reference `SkiaSharp.View.Uno`, you will get this error. To fix it, you'll need to reference `SkiaSharp.View.Uno.WinUI` instead. ### UNOB0002: Project XX contains a reference to Uno Platform but does not contain a WinAppSDK compatible target framework This error code means that a WinAppSDK project is referencing a project in your solution which is not providing a `net7.0-windows10.xx` TargetFramework. This can happen if a project contains only a `net7.0` TargetFramework and has a NuGet reference to `Uno.WinUI`. To fix this, it is best to start from a `Cross Platform Library` project template provided by the Uno Platform [visual studio extension](xref:Guide.HowTo.Create-Control-Library), or using [`dotnet new`](xref:Uno.GetStarted.dotnet-new). ### UNOB0003: Ignoring resource XX, could not determine the language This error may occur during resources (`.resw`) analysis if the framework does not recognize the specified language code. For instance, the language code `zh-CN` is not recognized and `zh-Hans` should be used instead. ### UNOB0004: The $(UnoVersion) property must match the version of the Uno.Sdk defined in global.json The build process has determined that an MSBuild property was defined to override `UnoVersion`. This property is defined by the Uno.Sdk and cannot be changed and must be updated through the `global.json` file Follow this guide in order to [update the Uno Platform packages](xref:Uno.Development.UpgradeUnoNuget). ### UNOB0005: The Version of Uno.WinUI must match the version of the Uno.Sdk found in global.json The build process has determined that the version of the Uno.WinUI NuGet package does not match the Uno.Sdk version. In general, restarting your IDE and compiling again will fix this issue. Follow this guide in order to [update the Uno Platform packages](xref:Uno.Development.UpgradeUnoNuget). ### UNOB0006: The UnoFeature 'XX' was selected, but the property XXXVersion was not set The build process has determined that you have specified an UnoFeature that requires a version to be set for a Package group such as Uno.Extensions, Uno.Toolkit.WinUI, Uno Themes, or C# Markup. Update your `csproj` file or `Directory.Build.props` with the property specified in the error along with the version that you would like to pin your build to. ### UNOB0007: AOT compilation is only supported in Release mode. Please set the 'Optimize' property to 'true' in the project file The build process has detected that you have set the value `UnoGenerateAotProfile` to true for a build configuration that has not optimized the assembly (i.e. Debug build Configuration). You should only generate an AOT profile from a build Configuration that will optimize the assembly such as the Release build Configuration. ### UNOB0008: Building a WinUI class library with dotnet build is not supported Building a `net8.0-windows10.x.x` class library using `dotnet build` is not supported at this time because of a [Windows App SDK issue](https://github.com/microsoft/WindowsAppSDK/issues/3548), when the library contains XAML files. To work around this, use `msbuild /r` on Windows. You can build using `msbuild` with a **Developer Command Prompt for VS 2022** (or 2026), or by using `vswhere` or using [GitHub actions scripts](https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/ci-for-winui3?pivots=winui3-packaged-csharp) in a CI environment. This particular check can be disabled by setting the msbuild property `UnoDisableValidateWinAppSDK3548` to `true`. ### UNOB0009: Uno Platform Implicit Package references are enabled When Uno Implicit Package References are enabled you do not need to provide an explicit PackageReference for the Packages listed in the build message. You should open the csproj file, find and remove the `` as listed in the build message. Alternatively you may disable the Implicit Package References ```xml true ``` ### UNOB0010: The browserwasm TargetFramework must not be placed first in the TargetFrameworks property In Visual Studio 2022/2026, [an issue](https://aka.platform.uno/singleproject-vs-reload) prevents debugging and Hot Reload from working properly for all targets when the `net8.0-browserwasm` TargetFramework is placed first in the `TargetFrameworks` property. Make sure to place `net8.0-browserwasm` last in your `` property. This warning can be disabled by adding the following to your `.csproj`: ```xml true ``` ### UNOB0011: The desktop TargetFramework must be placed first in the TargetFrameworks property In Visual Studio 2022/2026, [an issue](https://aka.platform.uno/singleproject-vs-reload) prevents other platforms debugging from working properly when the `net8.0-desktop` TargetFramework is placed first in the `TargetFrameworks` property. Make sure to place `net8.0-desktop` first in your `` property. This warning can be disabled by adding the following to your `.csproj`: ```xml true ``` ### UNOB0012: The windows TargetFramework must not be placed first in the TargetFrameworks property In Visual Studio 2022/2026, [an issue](https://aka.platform.uno/singleproject-vs-reload) prevents other platforms debugging from working properly when the `net8.0-windows10.xxx` TargetFramework is placed first in the `TargetFrameworks` property. Make sure that `net8.0-windows10.xxx` is not first in your `` property. This warning can be disabled by adding the following to your `.csproj`: ```xml true ``` ### UNOB0013: The net8.0 TargetFramework must not be placed first in the TargetFrameworks property In Visual Studio 2022/2026, [an issue](https://aka.platform.uno/singleproject-vs-reload) prevents other platforms debugging from working properly when the `net8.0` TargetFramework is placed first in the `TargetFrameworks` property. Make sure that `net8.0` is not first in your `` property. This warning can be disabled by adding the following to your `.csproj`: ```xml true ``` ### UNOB0014: The target framework is not supported on macOS or Linux When building with Rider on Linux or macOS, unsupported target frameworks are [not filtered automatically like other IDEs](https://youtrack.jetbrains.com/issue/RIDER-114790/Unsupported-target-framework-filtering). See how to [make platforms conditional](xref:Uno.GettingStarted.CreateAnApp.Rider#considerations-for-macos-and-linux) for Rider. ### UNOB0015: The desktop TargetFramework must be placed first In Visual Studio 17.13 or earlier, when both mobile (`-ios`, `-android`) and `desktop` target frameworks are used, the `-desktop` target framework must be placed first in order for WSL debugging to work. If `-desktop` is not first, the following message will appear: ```text The project doesn't know how to run the profile with name 'MyApp (Desktop WSL2)' and command 'WSL2'. ``` To fix the issue, reorder the items in your `.csproj` so that `TargetFrameworks` contains `netX.0-desktop` as the first target framework, or upgrade to Visual Studio 17.13 (when a stable release will be available). The Uno Platform team is following this [Visual Studio issue](https://developercommunity.visualstudio.com/t/WSL-launch-profile-cannot-be-found-when/10776961). ### UNOB0016: The Publish Profile file must not contain the "PublishDir" When publishing an app using ClickOnce on Windows, the `PublishProfile` file may not contain a `PublishDir` entry if the command line parameter `UnoClickOncePublishDir` has been set. This situation is due to an MSBuild property overriding bug found in the .NET SDK. For more information, see our [publishing with ClickOnce](xref:uno.publishing.desktop#windows-clickonce) documentation. ### UNOB0017: A reference to either Uno.WinUI.Runtime.WebAssembly or Uno.WinUI.WebAssembly has been detected When the `SkiaRenderer` feature is enabled, the `Uno.WinUI.Runtime.WebAssembly` and `Uno.WinUI.WebAssembly` packages must not be referenced directly. This is generally a package authoring error, make sure to open an issue in the Uno Platform repository to report the problem. ### UNOB0018: Code signing cannot be applied on files with extended attributes (e.g. iCloud) On macOS code signing will fail if the project's output is located inside a directory that is backed up using [iCloud](https://www.icloud.com). This is because iCloud adds some extended attributes to files and directories while `codesign` will refuse to sign such files. ref: https://developer.apple.com/library/archive/qa/qa1940/_index.html Solution: Move your Uno solution/project(s) to a different location, one that is not backed up by iCloud. ## Compiler Errors ### UNO0001 A member is not implemented, see [this page](xref:Uno.Development.NotImplemented) for more details. ### UNO0002 **Do not call Dispose() on XXX** On iOS, calling `Dispose()` or `Dispose(bool)` on a type inheriting directly from `UIKit.UIView` can lead to unstable results. It is not needed to call `Dispose` as the runtime will do so automatically during garbage collection. Invocations to `Dispose` can cause the application to crash in `__NSObject_Disposer drain`, causing `ObjectDisposedException` exception to be thrown. More information can be found in [xamarin/xamarin-macios#19493](https://github.com/xamarin/xamarin-macios/issues/19493). ### UNO0006 **Call 'InitializeComponent()' from code-behind** The method `InitializeComponent` should always be called in class constructor. A missing call will lead to hard-to-diagnose bugs. This analyzer reports when it's missing to make issues more apparent. ### UNO0007 **An assembly required for a component is missing** Some components like `ProgressRing` and `MediaPlayerElement` requires you to reference a specific NuGet package for them to work correctly. - For `ProgressRing`, it requires Lottie dependency. For more information about adding Lottie to your project, see [Lottie for Uno](xref:Uno.Features.Lottie). - For `MediaPlayerElement` on WebAssembly or Gtk, it requires `Uno.WinUI.MediaPlayer.WebAssembly` or `Uno.WinUI.MediaPlayer.Skia.Gtk` NuGet package. For more information, see [MediaPlayerElement](xref:Uno.Controls.MediaPlayerElement). ### UNO0008 In Uno Platform 5.5, the `EnableHotReload` method has been deprecated and replaced by `UseStudio()`. Note that this change only applies to projects using the Uno.Sdk. If you're not using the Uno.Sdk, you can disable this warning using the following code: ```xml #pragma warning disable UNO0008 // Replace with UseStudio() when migrating to the Uno.Sdk. window.EnableHotReload(); #pragma warning restore UNO0008 ``` ## XAML Errors ### UNOX0001 The `ProgressRing` control [needs an additional Lottie](xref:Uno.Features.Lottie) dependency to be enabled. ## VS Code Errors ### UVSC0001 Building for the specified target framework is not supported on the current platform or architecture. For example: - A Mac computer is required to build iOS and macOS applications - A Windows computer is required to build WinUI applications ### UVSC0002 Building WinUI applications requires the use of `msbuild` and the extension must be able to find it. This is done by using the `vswhere` utility. Installing the latest stable Visual Studio release should provide both tools. With version 0.14 (and later) you can override the location of `msbuild.exe` by: 1. Opening the **Settings** using `Ctrl`+`,` 1. Searching for `msbuild` 1. Setting the location where your `msbuild.exe` is located ![settings](Assets/quick-start/vs-code-settings-msbuild.png) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-builds-troubleshooting.md --- uid: Uno.Development.Troubleshooting --- # Troubleshooting build issues ## Diagnose environment problems with `uno-check` If you're not sure whether your environment is correctly configured for Uno Platform development, running the [`uno-check` command-line tool](https://www.nuget.org/packages/Uno.Check) should be your first step. Find installation instructions and other details in the [using uno-check guide](external/uno.check/doc/using-uno-check.md). ## Multi-targeting considerations Uno Platform projects use multi-targeting, for which each target framework has to be built individually, for some errors to disappear from the **Error List** window (notice the **Project** column values). In order to clear the **Error List** window, build the whole solution completely once. Subsequently, build a specific project and prefer the use of the **Output** tool window (in the menu **View** -> **Output**), taking build messages by order of appearance. ## Troubleshooting build errors using the build Output Window To troubleshoot build error, you can change the text output log level: - Go to **Tools**, **Options**, **Projects and Solution**, then **Build and Run** - Set **MSBuild project build output verbosity** to **Normal** or **Detailed** - Build your project again and take a look at the additional output ## Generating MSBuild Binary Log files If you have trouble building your project, you can get additional information using binary log (binlog) files. **Important: Note that binlog files contain environment variables and csproj files used to build the sources, but not the source files themselves.** Make sure to review the content of the file for sensitive information before posting it on a public issue, otherwise contact us on Discord for additional information to send us the build logs.** ### From Visual Studio To use MSBuild binary logs: - Go to **Tools**, **Options**, **Projects and Solution**, then **Build and Run** - Set **MSBuild project build log verbosity** to **Detailed** or **Diagnostics** - Install the [MSBuild log viewer](http://msbuildlog.com/) - Install the [Project System Tools for VS 2022](https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.ProjectSystemTools2022) or [VS 2019](https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.ProjectSystemTools) add-in - Open **View** > **Other Windows** > **Build Logging**, then click the green play button - Build your project again and right click the **Failed** build entry in the **Build Logging** tool window. - The binlog viewer tool will expand to the detailed build error ### From the command line You may be asked to generate a binlog from the command line, as it includes more information (the project structure, but not the source files) that can help troubleshoot issues. To generate a binlog file from the command line: - Open a : - [Visual Studio Developer command prompt](https://learn.microsoft.com/visualstudio/ide/reference/command-prompt-powershell) on Windows - A terminal window on Linux or macOS - Navigate to the folder of the project head - For WinUI/iOS/Android/macOS projects, type the following: ```bash msbuild /r /bl MyProject.csproj ``` - For other targets (.NET 5+, WebAssembly, Skia, etc...) ```dotnetcli dotnet build /bl MyProject.csproj ``` - Once the build has finished, a file named `msbuild.binlog` is generated next to the `.csproj` file. ## Common Build errors troubleshooting You can also browse the [common issues list](xref:Uno.UI.CommonIssues.AllIDEs) for build errors and their resolutions. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-community-toolkit-v7.md --- uid: Uno.Development.CommunityToolkit.v7 --- # How to use Windows Community Toolkit - Version 7.x This tutorial will walk you through adding and implementing the `DataGrid` control but the same steps can be followed for **other\*** Uno ported Windows Community Toolkit controls versions 7.x. **\* See the [non-Windows platform compatibility](xref:Uno.Development.CommunityToolkit#non-windows-platform-compatibility) section for more details.** > [!NOTE] > The complete source code that goes along with this guide is available in the [unoplatform/Uno.Samples](https://github.com/unoplatform/Uno.Samples) GitHub repository - [`DataGrid` Sample](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WindowsCommunityToolkit/Version-7.x/UnoWCTDataGridSample). ## Prerequisites For a step-by-step guide to installing the prerequisites for your preferred IDE and environment, consult the [Get Started guide](xref:Uno.GetStarted). > [!TIP] > If you are unsure of the version of the Windows Community Toolkit to use between v7 and v8, make sure to read the details about the [migration guide](xref:Uno.Development.CommunityToolkit). ## NuGet Packages for Uno Platform Uno Platform has ported the Windows Community Toolkit 7.x for use in Uno Platform applications to allow for use on Windows, Android, iOS, Linux, and WebAssembly. The following packages are available: - [Uno.CommunityToolkit.WinUI](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI) - [Uno.CommunityToolkit.WinUI.Connectivity](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.Connectivity) - [Uno.CommunityToolkit.WinUI.DeveloperTools](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.DeveloperTools) - [Uno.CommunityToolkit.WinUI.UI](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI) - [Uno.CommunityToolkit.WinUI.UI.Animations](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Animations) - [Uno.CommunityToolkit.WinUI.UI.Behaviors](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Behaviors) - [Uno.CommunityToolkit.WinUI.UI.Controls](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Controls) - [Uno.CommunityToolkit.WinUI.UI.Controls.Core](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Controls.Core) - [Uno.CommunityToolkit.WinUI.UI.Controls.DataGrid](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Controls.DataGrid) - [Uno.CommunityToolkit.WinUI.UI.Controls.Input](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Controls.Input) - [Uno.CommunityToolkit.WinUI.UI.Controls.Layout](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Controls.Layout) - [Uno.CommunityToolkit.WinUI.UI.Controls.Markdown](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Controls.Markdown) - [Uno.CommunityToolkit.WinUI.UI.Controls.Media](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Controls.Media) - [Uno.CommunityToolkit.WinUI.UI.Controls.Primitives](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Controls.Primitives) - [Uno.CommunityToolkit.WinUI.UI.Media](https://www.nuget.org/packages/Uno.CommunityToolkit.WinUI.UI.Media) These package IDs are for Uno Platform (non-Windows) projects. For WinUI 3 projects, you should use the equivalent packages published by Microsoft (`CommunityToolkit.WinUI`, `CommunityToolkit.WinUI.UI.Controls`, etc). ## Referencing the Windows Community Toolkit When using the Uno Platform solution templates, add the following to your application: 1. Install the NuGet package(s) reference(s) that you need ### [Single Project Template [WinUI / WinAppSDK]](#tab/singleproj) 1. Edit your project file `PROJECT_NAME.csproj` and add the following conditional references: ```xml ``` If you already had a reference to the Community Toolkit, you should remove this line: ```xml ``` 1. Edit `Directory.Packages.props` and add the following conditional references: ```xml ``` ### [Multi-Head Project Template (Legacy) [WinUI / WinAppSDK]](#tab/multihead-winui) Edit your project file `PROJECT_NAME.csproj` and add the following conditional references: ```xml ``` If you already had a reference to the Community Toolkit, you should remove this line: ```xml ``` ### [Shared Project (.shproj) Template (Legacy) [WinUI / WinAppSDK]](#tab/shproj-winui) 1. Select the following project `PROJECT_NAME.Windows.csproj` for installation and add the following reference: ```xml ``` 1. Select the following projects for installation and add the following reference to each of them: - `PROJECT_NAME.Wasm.csproj` - `PROJECT_NAME.Mobile.csproj` (or `PROJECT_NAME.iOS.csproj`, `PROJECT_NAME.Droid.csproj`, and `PROJECT_NAME.macOS.csproj` if you have an existing project) - `PROJECT_NAME.Skia.Gtk.csproj` - `PROJECT_NAME.Skia.WPF.csproj` ```xml ``` If you already had a reference to the Community Toolkit, you should remove this line: ```xml ``` --- If you're getting an error like this one : ```console Controls\TextBox\Themes\Generic.xaml : Xaml Internal Error error WMC9999: Type universe cannot resolve assembly: Uno.UI, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null. ``` This means that there's an unconditional reference to Uno Platform's packages, and you'll need to make sure to add the conditional references as suggested above. 1. Add the the related needed namespaces In XAML: ```xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"``` In C#: ```using CommunityToolkit.WinUI.UI.Controls;``` ## Example with the DataGrid Control This control will create an easily organized grid that will allow you to create flexible columns and rows. 1. Begin by adding the control using the syntax below. Change the `x:Name` to the name of your DataGrid. `````` 2. Similar to how you would configure columns for a XAML `Grid` layout, you can add column definitions within your `DataGrid` control: ```xml ``` This will create two columns that can be adjusted by the user. ![datagrid-column-gif](Assets/datagrid-basic-columns.gif) Alternatively, you can use the `AutoGenerateColumns` attribute on your `DataGrid` control if you do not know how many columns your data will require. ```xml ``` 3. Format your rows in the same way as your columns or use a `DataTemplate` added as an attribute on the `DataGrid` control: ```xml ``` 4. Data can be added with data binding. First, add your `ItemsSource` as a property of your `DataGrid` control. ```xml ``` Then, set the binding on each column: ```xml ``` ### See a working example with data ![datagrid-full-sample](Assets/datagrid-full-sample.gif) A complete working sample with data is available on GitHub: [Uno Windows Community Toolkit DataGrid Sample](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WindowsCommunityToolkit/Version-7.x/UnoWCTDataGridSample) --- [!include[getting-help](includes/getting-help.md)] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-community-toolkit-v8.md --- uid: Uno.Development.CommunityToolkit.v8 --- # How to use Windows Community Toolkit - Version 8.x This tutorial will walk you through adding and implementing the `SettingsCard` control but the same steps can be followed for **other\*** Windows Community Toolkit controls version 8.x. **\* See the [non-Windows platform compatibility](xref:Uno.Development.CommunityToolkit#non-windows-platform-compatibility) section for more details.** > [!NOTE] > The complete source code that goes along with this guide is available in the [unoplatform/Uno.Samples](https://github.com/unoplatform/Uno.Samples) GitHub repository - [`SettingsCard` Sample](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WindowsCommunityToolkit/Version-8.x/UnoWCTSettingsCardSample) ## Prerequisites For a step-by-step guide to installing the prerequisites for your preferred IDE and environment, consult the [Get Started guide](xref:Uno.GetStarted). > [!TIP] > If you are unsure of the version of the Windows Community Toolkit to use between v7 and v8, make sure to read the details about the Windows Community Toolkit [migration guide](xref:Uno.Development.CommunityToolkit). ## NuGet Packages Uno Platform is now supported out of the box by the Windows Community Toolkit and Windows Community Toolkit Labs starting with version 8.x. > [!IMPORTANT] > If you are already using Windows Community Toolkit version 7.x in your Uno Platform project and want to update to version 8.x, note that Uno Platform has its [own fork](https://github.com/unoplatform/Uno.WindowsCommunityToolkit) of the Windows Community Toolkit for [version 7.x](xref:Uno.Development.CommunityToolkit.v7). > > In your project, these Windows Community Toolkit Uno packages were referenced behind a conditional to allow for use on Windows, Android, iOS, Linux, and WebAssembly. > > Conditional references are no longer necessary with version 8.x, you can remove the Uno Windows Community Toolkit references and all `Condition` statements around the packages. ## Referencing the Windows Community Toolkit When using the Uno Platform solution templates, add the following to your application: 1. Install the NuGet package(s) reference(s) that you need ### [Single Project Template [WinUI / WinAppSDK]](#tab/singleproj) 1. Edit your project file `PROJECT_NAME.csproj` and add the needed reference(s): ```xml ``` 1. Edit `Directory.Packages.props` and add the needed reference(s): ```xml ``` > [!NOTE] > Windows Community Toolkit version 8.x requires an update to Windows SDK **10.0.22621** and above, along with [Microsoft.WindowsAppSDK](https://www.nuget.org/packages/Microsoft.WindowsAppSDK) updated to the latest matching version. > > To override these versions within a single project structure, you can set the properties in the `Directory.Build.props` file or directly in your project's `csproj` file. For more detailed information, please see the [implicit packages details](xref:Uno.Features.Uno.Sdk#implicit-packages). > > For example, in `PROJECT_NAME.csproj`: > > ```xml > > > net9.0-windows10.0.22621; > > ``` > > ```xml > > 10.0.22621.38 > 1.5.240607001 > > ``` ### [Multi-Head Project Template (Legacy) [WinUI / WinAppSDK]](#tab/multihead-winui) Edit your project file `PROJECT_NAME.csproj` and add the needed reference(s): ```xml ``` > [!NOTE] > Windows Community Toolkit version 8.x requires an update to Windows SDK **10.0.22621** and above, along with [Microsoft.WindowsAppSDK](https://www.nuget.org/packages/Microsoft.WindowsAppSDK) updated to the latest matching version. ### [Shared Project (.shproj) Template (Legacy) [WinUI / WinAppSDK]](#tab/shproj-winui) 1. Select the following projects for installation and add the needed reference(s) to each of them: - `PROJECT_NAME.Windows.csproj` - `PROJECT_NAME.Wasm.csproj` - `PROJECT_NAME.Mobile.csproj` (or `PROJECT_NAME.iOS.csproj`, `PROJECT_NAME.Droid.csproj`, and `PROJECT_NAME.macOS.csproj` if you have an existing project) - `PROJECT_NAME.Skia.Gtk.csproj` - `PROJECT_NAME.Skia.WPF.csproj` ```xml ``` > [!NOTE] > Windows Community Toolkit version 8.x requires an update to Windows SDK **10.0.22621** and above, along with [Microsoft.WindowsAppSDK](https://www.nuget.org/packages/Microsoft.WindowsAppSDK) updated to the latest matching version. --- 1. Add the related needed namespace(s) In XAML: ```xmlns:controls="using:CommunityToolkit.WinUI.Controls"``` In C#: ```using CommunityToolkit.WinUI.Controls;``` ## Example with the SettingsCard Control SettingsCard is a control that can be used to display settings in your experience. It uses the default styling found in Windows 11 and is easy to use, meets all accessibility standards and will make your settings page look great! You can set the `Header`, `HeaderIcon`, `Description`, and `Content` properties to create an easy to use experience, like so: ```xml Option 1 Option 2 Option 3 ``` ### See a working sample with more examples ![settingscard-full-sample](Assets/settingscard-full-sample.gif) A complete working sample, along with additional examples, is available on GitHub: [Uno Windows Community Toolkit SettingsCard Sample](https://github.com/unoplatform/Uno.Samples/tree/master/UI/WindowsCommunityToolkit/Version-8.x/UnoWCTSettingsCardSample) ## Using Non-UI Elements from the CommunityToolkit: Converters The CommunityToolkit provides a collection of ready-to-use converters for various scenarios (e.g., `x:Bind` in XAML). These converters streamline development by offering implementations for commonly used functionality, eliminating the need to manually create basic converters. [List of CommunityToolkit Converters | Windows Toolkit Documentation](https://learn.microsoft.com/en-us/dotnet/communitytoolkit/windows/converters/) The implementation of these is similar to the example of the `SettingsControl` above, with some minor adjustments required to use them: 1. Install the NuGet package reference needed for the converters ### Single Project Template [WinUI / WinAppSDK] 1. Edit your project file `PROJECT_NAME.csproj` and add this additional needed reference: ```xml ``` 1. Edit `Directory.Packages.props` and add this additional needed reference: ```xml ``` 1. Add the related needed namespace(s) In XAML: ```xmlns:converters="using:CommunityToolkit.WinUI.Converters"``` In C#: ```using CommunityToolkit.WinUI.Converters;``` If you are developing an app using [C# Markup](xref:Uno.Extensions.Markup.Overview) and want to use the converters, you can refer to the [C# Markup Converters Documentation](xref:Uno.Extensions.Markup.Converters) for a detailed usage guide. The general import process is covered from this point onward. 1. XAML Definition Unlike the previously seen `SettingsCard` control example, it is standard practice to define a converter in the `Page.Resources` section as a `StaticResource` before using it. This approach ensures that converters, like controls, are properly declared with a namespace and can be easily reused throughout the page. ### [Example: StringToVisibilityConverter](#tab/string-visible-conv) The `StringToVisibilityConverter` is a converter that transforms a string value into a `Visibility` state, returning `Visibility.Visible` for non-empty strings and `Visibility.Collapsed` for null or empty strings. #### Define the Converter in Page Resources Add the converter to the `Page.Resources` section as a `StaticResource`: ```xml ``` #### Use the Converter in Page Content Here is an example of how to use the converter in your XAML content: ```xml ``` ### [Example: BoolToObjectConverter](#tab/bool-obj-conv) The `BoolToObjectConverter` allows you to convert a boolean value into a specific object by defining `TrueObject` and `FalseObject`. Depending on the boolean value, the converter will return the corresponding object. #### Define the Converter in Page Resources For example, you can use it to switch colors dynamically. Add the converter to the `Page.Resources` section as a `StaticResource`: ```xml ``` #### Use the Converter in Page Content Here is an example of how to use the converter in your XAML content: ```xml ``` In this example, the `TextBlock` background will be green when `IsValid` is `true` and red when `IsValid` is `false`. --- [!include[getting-help](includes/getting-help.md)] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-community-toolkit.md --- uid: Uno.Development.CommunityToolkit --- # How to use Windows Community Toolkit The [Windows Community Toolkit](https://learn.microsoft.com/windows/communitytoolkit/) is a collection of helper functions, custom controls, and app services. It simplifies and demonstrates common developer patterns when building experiences for Windows. Depending on the version of the Windows Community Toolkit that you want to use, these tutorials below will walk you through adding and implementing: - **[For WCT version 8.x](xref:Uno.Development.CommunityToolkit.v8):** The `SettingsCard` control, but the same steps can be followed for **other\*** Windows Community Toolkit components supported out of the box. - **[For WCT version 7.x](xref:Uno.Development.CommunityToolkit.v7):** The `DataGrid` control, but the same steps can be followed for **other\*** Uno ported Windows Community Toolkit components. **\* See the [non-Windows platform compatibility](#non-windows-platform-compatibility) section below for more details.** > [!IMPORTANT] > **Here is the [Migration Guide from v7 to v8 for Windows Community Toolkit](https://github.com/CommunityToolkit/Windows/wiki/Migration-Guide-from-v7-to-v8) for additional information on what changed lately between these versions.** > > For some controls (`DataGrid`, `Carousel`, ect...) you will need to use **version 7.x** for them as they are no longer available in the latest 8.x version of Windows Community Toolkit. The complete list of changes is available in the [migration guide](https://github.com/CommunityToolkit/Windows/wiki/Migration-Guide-from-v7-to-v8). > > For additional information, here are the releases notes for Windows Community Toolkit: > > - [Release notes for version 7.x](https://github.com/CommunityToolkit/WindowsCommunityToolkit/releases) > - [Release notes for version 8.x](https://github.com/CommunityToolkit/Windows/releases) ## Non-Windows platform compatibility ### Overview While all Windows Community Toolkit packages are supported on WinAppSDK, this is not the case for the other platforms Uno Platform supports. ### Unsupported Components Some components, like [Media](https://github.com/CommunityToolkit/Windows/tree/main/components/Media/src), rely heavily on Composition APIs that are not yet supported by Uno Platform on all platforms. As a result, the Media package does not have the Uno-powered [MultiTargets](https://github.com/CommunityToolkit/Windows/blob/main/components/Media/src/MultiTarget.props) enabled, as the component would be non-functional out of the box. In such cases, the Windows Community Toolkit prefers to disable the package for Uno Platform rather than enable it and have it not work. To address these functional gaps, we encourage contributing to Uno Platform to bridge the gaps for the missing supported APIs or to the [Windows Community Toolkit](https://github.com/CommunityToolkit/Windows) by seeking or helping to build Uno-compatible alternatives. ### Partial Support In limited cases, WCT packages may have partial support for Uno Platform where the TargetFramework is enabled, but not all Toolkit code works out of the box. Currently, the only package in this scenario is Animations. It has a special FrameworkLayer abstraction that enables `AnimationBuilder` and `CustomAnimation` on Uno-powered MultiTargets but does not extend to `ImplicitAnimationSet` or Connected Animations. See [CommunityToolkit/Windows #319](https://github.com/CommunityToolkit/Windows/issues/319) for tracking. ### Majority Support The majority of controls are supported on all platforms by default. If you find a package that doesn't work as expected on Uno Platform, please open an [issue](https://github.com/unoplatform/uno/issues/new/choose) or [discussion](https://github.com/unoplatform/uno/discussions) to let us know. ## Troubleshooting The features and support for Uno Platform and Windows Community Toolkit components are constantly evolving. Therefore, you may encounter some issues while building your application. We encourage you to report these [issues](https://github.com/unoplatform/uno/issues/new/choose) and engage in [discussions](https://github.com/unoplatform/uno/discussions) to help improve the platform. [!include[getting-help](includes/getting-help.md)] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-fluent-assets.md --- uid: Uno.Development.FluentAssets --- # Uno Fluent UI assets Starting from Uno.UI 4.7, Uno Platform provides a cross-platform fluent symbols font, provided by the [Uno.Fonts.Fluent](https://nuget.info/packages/Uno.Fonts.Fluent) NuGet package. When included in the Uno Platform heads (excluding WinUI head), the symbols fonts will be used to display any control that makes use of it, such as the "burger" menu icon in a `NavigationView`. ## Usage The symbol font is automatically used by built-in styles and templates. You can reference it in XAML using the `SymbolThemeFontFamily` resource. For example: ```xml ``` ## Upgrading to the Uno.Fonts.Fluent package from previous releases In your Uno Platform projects: - Add the [Uno.Fonts.Fluent](https://nuget.info/packages/Uno.Fonts.Fluent) package to all your app heads. - You will also need to make small modifications to individual platforms. - For all heads, in respective `.csproj` files, remove all font files named `winjs-symbols.ttf` or `uno-fluentui-assets.ttf`. - For iOS and macOS, the `info.plist` file should be updated for both platforms to remove the `UIAppFonts` block: ```xml UIAppFonts Fonts/uno-fluentui-assets.ttf ``` - For WebAssembly, remove the contents of `Font.css` related to `@font-face { font-family: "Symbols"; ...}`. ## Known issues On iOS and macOS, the indeterminate state for a CheckBox is not the right color. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-howto-create-a-repro.md --- uid: Uno.Development.Create-Repro --- # How to create a reproduction project (aka "repro") This documentation describes the steps needed to create a "repro" or reproduction project, which will help the community and maintainers troubleshoot issues that you may find when developing with Uno Platform. The goal of a repro app is to find the **smallest possible piece of code that demonstrates the problem**, with the least dependencies possible. This is needed to make the resolution as fast as possible, as the Uno Platform team and community members do not have access to your projects sources nor understand your own expertise domain. Some steps and questions to answer: 1. Make sure to test with the latest Uno Platform pre-release builds, the issue might have already been fixed. 1. Start from a new "blank uno app" from the Uno platform Visual Studio extension, or `dotnet new unoapp --preset=blank` app. 1. Attach a .zip file of that repro to the issue. > [!TIP] > Watch out for the size of zip created. Check the section below on reducing the sample size. 1. If you can, add a video or screenshots reproducing the issue. Github supports uploading `mp4` files in issues. ## Tips on how to create the simplest repro app - Find the smallest piece of API used by your app (XAML Control, method, type) and extract that code into the repro app - If it's impacting a control: - Try replicating the interactions as minimally as possible by cutting the ties with the rest of your original app - Try altering the properties of the control by either removing the styles, changing the styles, changing modes of the control if there are any. - If you can't repro in a separate app because there are too many dependencies in your app try, removing as much code as you can around the use of failing API or Control. This may include removing implicit styles, global initializations. - If the control offers events, try adding logging to Loading/Unloading/PropertyChanged/LayoutUpdated or other available events to determine if the Control or API is interacting with your code in expected ways. Sometimes adding a breakpoint in the handler of those events can show interesting stack traces. - When debugging data bindings: - Show the text version of the binding expression somewhere in the UI, to see the type of the bound data: - `` - `` - `` - Add an event handler to `DataContextChanged` in the code behind to see if and when the `DataContext` changed. - Analyze device and app logs for clues about the control's behavior. - You may enable [the controls debug logs](https://github.com/unoplatform/uno/blob/master/doc/articles/logging.md), if any. - To validate that logs are enabled and in Debug, those starting with `Windows`, `Microsoft`, or `Uno` should be visible in the app's output. If not, make sure to [setup the logging properly](xref:Uno.Development.MigratingFromPreviousReleases). - Logs on iOS may need to have the [OSLog logger](https://github.com/unoplatform/uno.extensions.logging) enabled when running on production devices. - Try on different versions of Visual Studio, iOS, Android, Linux, or browsers - If available, try the API on Windows (WinUI) and see if it behaves differently than what Uno Platform is doing - When issues occur, try breaking on all exceptions to check if an exception may be hidden and not reported. - Update Uno.WinUI or other dependencies to previous or later versions, using a [bisection technique](https://git-scm.com/docs/git-bisect). Knowing which version of a package introduced an issue can help orient the investigations. ## Creating a smaller zip file to upload to github > Yowza, that’s a big file Try again with a file smaller than 10MB. > -- Github If you get the above message when attempting to upload the zipped sample, thats usually because you have included, beside the source codes, needless build outputs inside `bin` and `obj` folders for each target heads. You can usually reduce this by performing `Build > Clean Solution` before zipping the entire solution folder. It also helps to manually delete the `bin\` and `obj\` folders under each project heads that you've compiled. However, sometimes that still may not be enough. In such case, you can leverage the `git` tool and a `.gitignore` file to further reduce the size of the solution. ### [**Windows (Visual Studio)**](#tab/windows-vs) If you're inside of Visual Studio: - Open the solution - At the bottom of the IDE window, click the **Add to Source Control** button, then **git** - Select **Local only**, then **Create** - Wait a few seconds for the changes to be committed - Close visual studio - Open a command line prompt in your solution folder and type `git clean -fdx` Once done, you can zip the folder and send it to github in your issue or discussion. ### [**Windows (Console)**](#tab/windows-console) Using the command prompt: - Navigate to your sample's root folder - Type `dotnet new gitignore` - Type `git init` - Type `git add .` - Type `git commit -m "Initial sample commit"` - Type `git archive HEAD --format zip --output sample.zip` - Type `explorer /select,sample.zip` Once done, you can send the `sample.zip` to github in your issue or discussion. ### [**macOS / Linux**](#tab/nix) Using a terminal: - Navigate to your sample's root folder - Type `wget https://raw.githubusercontent.com/github/gitignore/main/VisualStudio.gitignore -O .gitignore` - Type `git init` - Type `git add .` - Type `git commit -m "Initial sample commit"` - Type `git clean -fdx` Once done, you can zip the folder and send it to github in your issue or discussion. --- --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/uno-internals-android.md --- uid: Uno.Contributing.Android --- # How Uno works on Android This article explores Android-specific details of Uno's internals, with a focus on information that's useful for contributors to Uno. For an overview of how Uno works on all platforms, see [this article](uno-internals-overview.md). Some particulars of Android: ## Some classes are written in Java Several base classes and helper classes are written in native Java code. These are located in [Uno.UI.BindingHelper.Android](https://github.com/unoplatform/uno/tree/master/src/Uno.UI.BindingHelper.Android/Uno/UI). The Xamarin.Android framework gives complete access to the Android API from managed C#, so why write anything in Java? The reason is performance. The interop between Java and C# can be costly, and instrumented profiling identified that certain virtual methods when overridden in C# and called in heavily-used paths (eg measure and arrange) imposed a measurable performance penalty. Over time, these 'hot' methods have been lowered to Java classes, particularly the `UnoViewGroup` class. The `Uno.UI.BindingHelper.Android` project builds these Java types, and wraps them in a [Xamarin binding library](https://learn.microsoft.com/xamarin/android/platform/binding-java-library/), making them available via C#. ## UIElement inherits from ViewGroup `UIElement` in Uno is a native view on Android, inheriting from the general `ViewGroup` type. To elaborate, `UIElement`'s base classes are the following: `Android.Views.View` → `Android.Views.ViewGroup` → `Uno.UI.UnoViewGroup` → `Uno.UI.Controls.BindableView` → `Windows.UI.Xaml.UIElement` Recall that `UIElement` implements `DependencyObect` [as an interface](uno-internals-overview.md) in Uno. ## Layouting Uno's measure and arrange logic is triggered from the native Android layout cycle. For a schematic of the control flow, see [Layouting in Android](Uno-UI-Layouting-Android.md). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/uno-internals-hotreload.md --- uid: Uno.Contributing.Internals.HotReload --- # Hot Reload Phases _This page details the internals of Hot Reload. To use Hot Reload, [head over here](xref:Uno.Features.HotReload)._ When a change is made to XAML or a C# code file, it's immediately picked up by compiler. However the updates aren't immediately sent to the app until the file is saved (assuming "Hot Reload on Save" is enabled) or the Hot Reload button is clicked in Visual Studio. When Hot Reload is triggered, the changes, along with any associated metadata, is propagated to the running application. There are two types of updates that can be sent: - Incremental - these are deltas that are applied to existing types. For example a method can be modified, and the next time the method is invoked it will execute the new code - Type Replacement - when a type has been attributed with the CreateNewOnMetadataUpdate attribute, instead of changes being sent as deltas, a whole new type is added. So for example if a change is made to MainPage, a new type, MainPage#1, is created and is available within the executing application. After Hot Reload has propagated changes to the running application, it will look for any types that have been registered using the MetadataUpdateHandler attribute. If a type is found, it will attempt to run the UpdateApplication static method, passing in the types that have been modified. In the case of incremental updates, the types will be original types found within the application but they'll have been updated with the deltas that have been sent. In the case of type replacement updates, the types will contain the newly created types. The meta data on these types can be interrogated to determine the original type that they're replacing. Uno core already registers a class with the MetadataUpdateHandler and has an UpdateApplication method that gets invoked when Hot Reload is triggered. This application does two things: - for Type Replacement updates, it adds, or updates, values in mapping dictionaries it manages so that it's possible to translate between an original type and it's (current) replacement, and from a replacement type, back to the original type. - it triggers an update to the UI (a UI Update) which walks the visual tree looking for elements where the type has been replaced. If an element is of a type that has been replace, a new element is created and used to replace the original element in the tree. ## Intercepting the UI Update The main extensibility point for developers wanting to integrate with Hot Reload for Uno Platform applications is via the UI Update. The UI Update is the phase of Hot Reload where the visual tree is traversed and elements are updated according to the updated type information. To intercept the UI Update the first thing to do is to create a static class with static methods that will be invoked at different points in the UI Update. The static class needs to be registered using the ElementMetadataUpdateHandler attribute. In this example, the FrameUpdateHandler is registered as a handler for the Frame class. As the visual tree is traversed, when a Frame is encountered the appropriate methods on the FrameUpdateHandler will be invoked. ```csharp [assembly:ElementMetadataUpdateHandler(typeof(Frame), typeof(FrameUpdateHandler))] ``` In this example, the VisualTreeHandler is registered as a handler without specifying a particular element type. Only the methods on the VisualTreeHandler that aren't specific to individual elements will be invoked, for example the BeforeVisualTreeUpdate and AfterVisualTreeUpdate method. The following methods (at least one) can be implemented by the static class registered using the ElementMetadataUpdateHandler: ```csharp static void BeforeVisualTreeUpdate(Type[]? updatedTypes); static void AfterVisualTreeUpdate(Type[]? updatedTypes); static void ReloadCompleted(Type[]? updatedTypes, bool uiUpdated); static void ElementUpdate(FrameworkElement, Type[]?); static void BeforeElementReplaced(FrameworkElement, FrameworkElement, Type[]?); static void AfterElementReplaced(FrameworkElement, FrameworkElement, Type[]?); ``` ## Pausing / Resuming UI Update Pausing and resuming UI Update is done by calling `TypeMappings.Pause()` and `TypeMappings.Resume()` Note that pausing UI Updates doesn't stop the Hot Reload process. It only prevents the UI Update from running until UI Updates are resumed. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/uno-internals-ios.md --- uid: Uno.Contributing.iOS --- # How Uno works on iOS This article explores iOS-specific details of Uno's internals, with a focus on information that's useful for contributors to Uno. For an overview of how Uno works on all platforms, see [this article](uno-internals-overview.md). ## UIElement inherits from UIView `UIElement` in Uno is a native view on iOS, inheriting from the general `UIView` type. To elaborate, `UIElement`'s base classes are the following: `UIKit.UIView` → `Uno.UI.Controls.BindableUIView` → `Windows.UI.Xaml.UIElement` Recall that `UIElement` implements `DependencyObject` [as an interface](uno-internals-overview.md) in Uno. ## Layouting Uno's measure and arrange logic is triggered from the native iOS layout cycle. For a schematic of the control flow, see [Layouting in iOS](Uno-UI-Layouting-iOS.md). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/uno-internals-macos.md --- uid: Uno.Contributing.macOS --- # How Uno works on macOS This article explores macOS-specific details of Uno's internals, with a focus on information that's useful for contributors to Uno. For an overview of how Uno works on all platforms, see [this article](uno-internals-overview.md). ## UIElement inherits from NSView `UIElement` in Uno is a native view on macOS, inheriting from the general `NSView` type. To elaborate, `UIElement`'s base classes are the following: `AppKit.NSView` → `Uno.UI.Controls.BindableNSView` → `Windows.UI.Xaml.UIElement` Recall that `UIElement` implements `DependencyObect` [as an interface](uno-internals-overview.md) in Uno. ## Similarities with iOS Since the iOS and macOS UI frameworks bear substantial resemblances, the same or very similar code can frequently be used to do the same thing on both platforms, which Uno takes advantage of where possible. Partial class definitions that are shared between iOS and macOS can be identified by the `*.iOSmacOS.cs` suffix. Since Uno's iOS support predates its macOS support, in some cases internal methods have been added to make macOS' API appear still closer to that of iOS and make code reuse easier, such as the `SizeThatFits()` method or the `SetNeedsLayout()` extension method. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/uno-internals-overview.md --- uid: Uno.Contributing.Overview --- # How Uno Platform works This article explores how Uno works in detail, with a focus on information that's useful for contributors to Uno. ## What Uno Platform does Uno Platform is a cross-platform projection of Microsoft's WinUI framework (and its preview iteration, UWP). Uno mirrors WinUI types and supports the WinUI XAML dialect, as well as handling several additional aspects of the app contract, like assets and string resources. Thus, it allows app code written for WinUI to be built and run on Android, iOS, Linux, macOS, and in the browser via WebAssembly. > [!NOTE] > While WinUI supports authoring app code in C++ as well as C#, Uno Platform only supports C#. Broadly then, Uno Platform has two jobs to do: * Duplicate the types provided by WinUI, including views in the `Microsoft.UI.Xaml` namespace, and non-UI APIs such as `Windows.Foundation`, `Windows.Storage`, etc... * Perform compile-time tasks related to non-C# aspects of the WinUI app contract (parse XAML files, process assets to platform-specific formats, etc) Like WinUI, Uno Platform provides access to the existing .NET libraries, via [.NET](https://dotnet.microsoft.com/en-us/). Uno Platform aims to be a 1:1 match for WinUI, in API surface (types, properties, methods, events, etc), in appearance, and in behavior. At the same time, Uno Platform places an emphasis on native interoperability and making it easy to intermix purely native views with Uno/WinUI controls in the visual tree. ## Uno.WinUI as a class library Certain aspects of the framework are not tied in any way to the platform that Uno happens to be running on. These include support for the [`DependencyProperty` system and data-binding](https://learn.microsoft.com/windows/uwp/xaml-platform/dependency-properties-overview), and style and resource resolution. The code that implements these features is fully shared across all platforms. Other parts of the framework are implemented using a mix of shared and platform-specific code, such as view types (ie types inheriting from [`UIElement`](https://learn.microsoft.com/uwp/api/windows.ui.xaml.uielement)). There is a tendency for high-level controls, which are typically built by composition of simpler visual primitives, to be implemented mainly by shared code - [`NavigationView`](https://github.com/unoplatform/uno/tree/master/src/Uno.UI/UI/Xaml/Controls/NavigationView) is a good example. The primitives themselves, such as [`TextBlock`](https://github.com/unoplatform/uno/tree/master/src/Uno.UI/UI/Xaml/Controls/TextBlock), [`Image`](https://github.com/unoplatform/uno/tree/master/src/Uno.UI/UI/Xaml/Controls/Image), or [`Shape`](https://github.com/unoplatform/uno/tree/master/src/Uno.UI/UI/Xaml/Shapes), contain a much higher proportion of platform-specific code as they need to call into per-platform rendering APIs. The layouting system is implemented in shared code as much as possible, for cross-platform consistency; however it's nonetheless tied into the underlying native layout cycle on each platform. APIs for non-UI features, for example [`Windows.System.Power`](../features/windows-system-power.md) or [`Windows.Devices.Sensors`](../features/windows-devices-sensors.md), incorporate a large fraction of platform-specific code to interact with the associated native APIs. ### Generated `NotImplemented` stubs WinUI has a very large API surface area, and not all features in it have been implemented by Uno Platform. We want pre-existing WinUI apps and libraries that reference these features to still be able to at least compile on Uno Platform. To support this, an [internal automated tool](https://github.com/unoplatform/uno/tree/master/src/Uno.UWPSyncGenerator) inspects the WinUI framework, compares it to authored code in Uno Platform, and generates stubs for all types and type members that exist in WinUI but are not implemented on Uno. For example: ```csharp #if __ANDROID__ || __IOS__ || __TVOS__ || IS_UNIT_TESTS || __WASM__ [global::Uno.NotImplemented] public bool ExitDisplayModeOnAccessKeyInvoked { get { return (bool)this.GetValue(ExitDisplayModeOnAccessKeyInvokedProperty); } set { this.SetValue(ExitDisplayModeOnAccessKeyInvokedProperty, value); } } #endif ``` Notice the platform conditionals, since a member may be implemented for some platforms but not others. The `[NotImplemented]` attribute flags this property as not implemented and a code analyzer surfaces a warning if it is referenced in app code. ### Platform-specific details For more details on how Uno Platform runs on each platform, see platform-specific information for: * [Android](uno-internals-android.md) * [iOS](uno-internals-ios.md) * [WebAssembly](uno-internals-wasm.md) ## Uno.WinUI build-time tooling ### Parsing XAML to C# code This is the most substantial compile-time task that Uno Platform carries out. Whenever an app or class library is built, all contained XAML files are parsed and converted to C# files, which are then compiled in the usual way. (Note that this differs from WinUI, which parses XAML to XAML Binary Format (.xbf) files which are processed by the WinUI runtime.) Uno Platform uses existing libraries to parse a given XAML file into a XAML object tree, then Uno-specific code is responsible for interpreting the XAML object tree as a tree of visual elements and their properties. Most of this takes place within the [`XamlFileGenerator`](https://github.com/unoplatform/uno/blob/master/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs) class. ### DependencyObject implementation generator On [Android](uno-internals-android.md), [iOS](uno-internals-ios.md), and [macOS](uno-internals-macos.md), `UIElement` (the base view type in WinUI) inherits from the native view class on the respective platform. This poses a challenge because `UIElement` inherits from the `DependencyObject` class in UWP/WinUI, which is a key part of the dependency property system. Uno makes this work by breaking from WinUI and having `DependencyObject` be an interface rather than a type. Class library authors and app authors sometimes inherit directly from `DependencyObject` rather than a more derived type. To support this scenario seamlessly, the [`DependencyObjectGenerator` task](https://github.com/unoplatform/uno/blob/master/src/SourceGenerators/Uno.UI.SourceGenerators/DependencyObject/DependencyObjectGenerator.cs) looks for such classes and [generates](https://github.com/unoplatform/Uno.SourceGeneration) a partial implementation for the `DependencyObject` interface, ie, the methods that on UWP would be inherited from the base class. ### Formatting image assets Different platforms have different requirements for where bundled image files are located and how multiple versions of the same asset are handled (eg, to target different resolutions). The [asset retargeting task](https://github.com/unoplatform/uno/blob/master/src/SourceGenerators/Uno.UI.Tasks/Assets/RetargetAssets.cs) copies the image assets located in the shared project to the appropriate location and format for the target platform. ### Formatting string resources As with images, different platforms have different requirements for the location and formatting of localized string resources. The [ResourcesGenerationTask](https://github.com/unoplatform/uno/blob/master/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/ResourcesGenerationTask.cs) reads the strings defined in WinUI's `*.resw` files in the shared project, and generates the appropriate platform-specific file. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/uno-internals-wasm.md --- uid: Uno.Contributing.Wasm --- # How Uno works on WebAssembly Native This article explores WebAssembly-specific details of Uno's internals, with a focus on information that's useful for contributors to Uno. For an overview of how Uno works on all platforms, see [this article](uno-internals-overview.md). ## What is WebAssembly actually? > [WebAssembly is a new type of code](https://developer.mozilla.org/en-US/docs/WebAssembly) that can be run in modern web browsers — it is a low-level assembly-like language with a compact binary format that runs with near-native performance and provides languages such as C/C++ and Rust with a compilation target so that they can run on the web. It is also designed to run alongside JavaScript, allowing both to work together. WebAssembly (Wasm) allows .NET code, and hence Uno, to run in the browser. It's supported by all major browsers, including mobile browser versions. Wasm in the browser runs in the same security sandbox as JavaScript does, and has exactly the same capabilities and constraints. Note that for now there's no means of accessing browser APIs, including the DOM, directly from Wasm. All communication to and from the DOM must be done by interop with JavaScript. ## UIElements map to DOM elements There is for the most part a 1:1 mapping between managed XAML elements and DOM elements. The element tag associated with a XAML type is set by a `UIElement` constructor overload which takes the tag as a string, with "div" as the default. ## Typescript layer Part of Uno for WASM is defined in Typescript (which transpiles to JavaScript), since going through JavaScript is currently the only way to manipulate the DOM and access other browser APIs from WebAssembly. The TypeScript layer is located in the Uno.UI.Wasm project. The most important class here is `WindowManager.ts`. ## JavaScript interop in Uno Calls into JavaScript from C# generally access methods in the `WindowManagerInterop` .NET class, which calls methods on the `WindowManager` TypeScript class using the `WebAssemblyRuntime.InvokeJS()` method. Callbacks into C# from JavaScript can be defined using the `mono_bind_static_method` wrapper. C# methods that will be called from JavaScript must be added to the [LinkerDefinition](https://github.com/unoplatform/uno/blob/master/src/Uno.UI/LinkerDefinition.Wasm.xml) file. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/uno-islands.md --- uid: Uno.Tutorials.UnoIslands --- # Uno Islands With Uno Islands, you can host Uno Platform XAML controls in an WPF application, next to existing WPF content. This feature enables you to enhance the look, feel, and functionality of your existing WPF application with the latest Windows UI features provided by their implementation within Uno Platform. ## How to use Uno Islands with existing WPF app The most common scenario is to add Uno Islands into an existing WPF app. First, **add a Shared project** into your WPF app solution by right-clicking the solution node in Solution explorer and choosing **Add -> New Project...** and searching for "Shared Project" in the dialog. This project will be used to host our Uno Platform XAML files. ![Adding a Shared project](../Assets/guides/uno-islands/add-shared.png) ### Shared project contents In this project, we need to add the Uno Islands Application and a page to be displayed. The easiest way to do this is to copy these files from [UnoIslandsSamplesApp in Uno.Samples GitHub repository](https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoIslandsSampleApp/UnoIslandsSampleApp.Shared). Copy and include `App.xaml`, `App.xaml.cs`, `MainPage.xaml`, and `MainPage.xaml.cs` files in the shared project, and the `Assets` folder to include the Uno Platform icon font. ### Updating the WPF application project To light-up the Uno Islands feature, we need to reference several Uno Platform NuGet packages, reference the shared project, and include the Uno Platform icon font. Double-click the WPF project and add the following: ```xml ``` ### Adding an Uno Island Now we can add an Uno Island into our WPF app content. Open a WPF XAML file and add the following namespace declaration to the root element: ```xml xmlns:xamlHost="clr-namespace:Uno.UI.XamlHost.Skia.Wpf; assembly=Uno.UI.XamlHost.Skia.Wpf" ``` And now use the `UnoXamlHost` control to host the Uno Platform island: ```xml ``` ![Hello, world! example](../Assets/guides/uno-islands/hello-world.png) ## Data-binding The WPF `DataContext` is automatically propagated to the Uno Island-hosted controls, which makes it possible to use an MVVM-based approach. Suppose we update the `MainWindow.xaml.cs` as follows: ```csharp public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = "friends"; } } ``` Now we can use the data in the `MainPage.xaml`: ```xml ``` ![Data binding example](../Assets/guides/uno-islands/hello-friends.png) ## How to use Uno Islands in blank Uno app The starting point for creating an Uno Islands-enabled application is to create a blank Uno Platform app. ### Preparing solution In the new solution, feel free to remove targets that are not needed for your purposes, but make sure to keep at least the Shared project and WPF project. ![XamlHost Solution layout](../Assets/guides/uno-islands/solution-layout.png) Right-click the solution node in Solution Explorer and select `Manage NuGet Packages for Solution...`. In the NuGet Package Manager window, search for `Uno.WinUI.XamlHost`. ![XamlHost NuGet packages](../Assets/guides/uno-islands/xamlhost-packages.png) Install the `XamlHost` package in all projects and the `XamlHost.Skia.Wpf` package in the WPF project. ### Set up `XamlApplication` Uno Islands require a special type of `Application` class to get discovered properly. Open the `App.xaml.cs` file and make your application derive from `Uno.UI.XamlHost.XamlApplication`: ```csharp public sealed partial class App : Uno.UI.XamlHost.XamlApplication { ... } ``` In `App.xaml` you also need to adjust the root element accordingly: ```xml ... ``` > Note that you can create a separate `XamlApplication`-derived class for Islands purposes and keep the existing `Application` class for "full" Uno Application purposes, if you want to develop a self-standing and island-hosted application simultaneously. ### Hosting Uno Platform content in WPF app You can now host any Uno Platform content next to classic WPF content using the `Uno.UI.XamlHost.Skia.Wpf.UnoXamlHost` control. The `InitialTypeName` attribute allows you to specify the type that should be loaded in it. For example, we can host the `MainPage` in `MainWindow.xaml` as follows: ```xml ``` Make sure to update the `MainWindow.xaml.cs` as follows to remove the initialization used by full-window Uno apps: ```csharp public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } ``` ![Hello, world! example](../Assets/guides/uno-islands/hello-world.png) ## Limitations This feature is in early preview and some functionality is not enabled yet, including: - Focus management - Drag and drop - Keyboard event handling ## See Uno Islands in action Full working sample application is available in the [Uno Samples repository](https://github.com/unoplatform/Uno.Samples/tree/master/UI). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-notimplemented-types.md --- uid: Uno.Development.NotImplemented --- # The member/type is not implemented If you're visiting this page after having clicked on a link in your application's debug log or exception view, this means you're using directly or indirectly an API that is not implemented. Uno Platform is built around providing the full APIs provided by WinRT and WinUI, by replicating the available surface to be used in Uno Platform apps. This WinUI and WinRT surface is very large. We covered a great portion of it since 2013, to the level of even publicly-listed enterprises deploying apps with it. To prioritize the remainder of unimplemented WinUI & WinRT API surface, we need the help of the community to add support for APIs that are marked as "Not Implemented". Multiple directions are available: - Make sure that you are using the latest available stable packages for Uno Platform (Uno.WinUI or Uno.UI) - Find the API (Type, method or property) in the [Issues list](https://github.com/unoplatform/uno/issues) or [Pull Requests](https://github.com/unoplatform/uno/pulls) to vote on it with GitHub reactions, and if it's not already present, create one so the team knows you're trying to use it. Make sure to let us know your use case as it may drive priorities. - If you're up for it, you can contribute an implementation for this API The Uno Platform team [offers professional support](https://platform.uno/support/) to get issues sorted out faster. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-platform-status-troubleshooting.md --- uid: Uno.Development.UnoPlatformStatus --- [!INCLUDE [uno-platform-status](includes/uno-platform-status-inline.md)] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-platform-status.md --- uid: Uno.UnoPlatformStatus --- [!INCLUDE [uno-platform-status](includes/uno-platform-status-inline.md)] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-android.md --- uid: uno.publishing.android --- # Publishing Your App for Android ## Preparing For Publish - [Performance Profiling](xref:Uno.Tutorials.ProfilingApplications) ## Building your app ### Packaging your app using the CLI To build your app from the CLI, on Windows, Linux, or macOS: - Open a terminal, command line, or powershell - Navigate to your `csproj` folder - Publish the app using: ```shell dotnet publish -f net9.0-android -c Release -o ./publish ``` - Once the build is done, the output `.apk` and `.aab` files are located in the `./publish` folder. ## Publishing your Android App Publishing an Uno Platform app uses the same steps as .NET for Android-based technologies. Your app can be published: - Through a market – There are multiple Android marketplaces that exist for distribution, with the most well-known being [Google Play](https://developer.android.com/distribute/googleplay/publish/index.html), or [Amazon](https://www.developer.amazon.com/docs/app-submission/submitting-apps-to-amazon-appstore.html). - Via a website – An Uno Platform app can be made available for download on a website, from which users may then install the app by clicking on a link. - Using [`adb`](https://learn.microsoft.com/en-us/dual-screen/android/emulator/adb) on the command line, with `adb install your.apk`. In Visual Studio 2022/2026, you can open a shell with `adb` available in the `PATH` with the **Tools**, **Android**, **Android Adb Command Prompt** menu. Publishing an Uno Platform also uses the same steps as a MAUI app, which is based on .NET for Android. You can follow these [steps and links](https://learn.microsoft.com/dotnet/maui/android/deployment/?view=net-maui-8.0) to publish your app. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-desktop-macos-advanced.md --- uid: uno.publishing.desktop.macos.advanced --- # Publishing Your App for macOS - Advanced Topics ## App Bundle (.app) Customization ### Custom `Info.plist` If your application requires extraneous permissions from macOS to execute some operations, e.g. using the camera, then you need to customize the `Info.plist` file of your app bundle. You can create a basic `Info.plist` file yourself, using any text editor. The content should be like: ```xml CFBundleDevelopmentRegion CFBundleDisplayName CFBundleExecutable CFBundleIconFile CFBundleIdentifier CFBundleName CFBundleShortVersionString CFBundleVersion ``` You can edit the `Info.plist` file, add any required entries (for permissions), and leave other fields empty. The basic, empty fields will be filled automatically by the `msbuild` task based on your project. Then from the CLI run: ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=app -p:UnoMacOSCustomInfoPlist=path/to/Info.plist ``` ### Hardened Runtime [Hardened Runtime](https://developer.apple.com/documentation/security/hardened-runtime) is `true` by default as it is **required** for [notarization](https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution). If needed you can turn it off by providing `-p:UnoMacOSHardenedRuntime=false` on the CLI. ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=app -p:UnoMacOSHardenedRuntime=false ``` ### Custom Entitlements [Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements) grants permission to your executable. If nothing is specified the default entitlements required for a notarization-compatible dotnet-based application will be included automatically. ```xml com.apple.security.cs.allow-jit ``` You can provide your own entitlement file if needed using `-p:UnoMacOSEntitlements=/path/to/entitlements.plist` on the CLI. ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=app -p:UnoMacOSEntitlements=/path/to/entitlements.plist ``` ### Trimming App bundles that are distributed should be self-contained applications that depend only on the OS to execute. However bundling the dotnet runtime, base class libraries, and Uno Platform libraries produce a rather large application size. To reduce the size of the app bundle you can enable dotnet's [trimming](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options#enable-trimming) when publishing the app, using `-p:PublishTrimmed=true`. The full command from the CLI would be: ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=app -p:PublishTrimmed=true ``` > [!IMPORTANT] > Your code and dependencies need to be [trimmer-aware](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/prepare-libraries-for-trimming) and the trimmed app bundle should be carefully tested to ensure the code removed by the trimmer does not affect its functionality. ### Optional files `dotnet publish` includes several files that are not strictly required to execute your application. To reduce the app bundle size most of those files are **not** included, by default, inside the app bundles. #### Including dotnet `createdump` tool Although useful for debugging, the `createdump` executable is rarely used by the application's consumers and, by default, is not included in the app bundle. If you wish to include `createdump` inside your app bundle add the `-p:UnoMacOSIncludeCreateDump=true` on the CLI. ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=app -p:UnoMacOSIncludeCreateDump=true ``` #### Including `libclrgc.dylib` extraneous GC An alternate garbage collection (GC) library is included by `dotnet publish`. It is, by default, removed from the app bundle since it would not be used at runtime. If you wish to include this extra GC library inside your app bundle add the `-p:UnoMacOSIncludeExtraClrGC=true` on the CLI. ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=app -p:UnoMacOSIncludeExtraClrGC=true ``` #### Including `libmscordaccore.dylib` and `libmscordbi.dylib` debugging support Extraneous debugging support libraries are included by `dotnet publish`. They are, by default, removed from the app bundle since it's unlikely to be used for debugging. If you wish to include the extra debugging libraries inside your app bundle add the `-p:UnoMacOSIncludeNativeDebugging=true` on the CLI. ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=app -p:UnoMacOSIncludeNativeDebugging=true ``` #### Including assemblies debugging symbols (.pdb) files dotnet debugging symbols (`.pdb`) are generally included in released applications since they help to provide better stack traces and help developers resolve issues. As such, they are, by default, included inside the app bundle. If you wish to remove them anyway, you can do so by adding the `-p:UnoMacOSIncludeDebugSymbols=false` on the CLI. ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=app -p:UnoMacOSIncludeDebugSymbols=false ``` ## Disk Image (.dmg) Customization ### Symlink to /Applications By default, the produced disk image will contain a symlink to `/Applications` so users can drag-and-drop the app bundle inside it. If you do not want the symlink to be present inside the disk image you can add `-p:UnoMacOSIncludeSymlinkToApplications=false` on the command line. ```bash dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=dmg -p:UnoMacOSIncludeSymlinkToApplications=false -p:CodesignKey={{identity}} -p:DiskImageSigningKey={{identity}} ``` ### Additional Customization Further disk image customization is possible but can be tricky since it requires modification to the `.DS_Store` binary file inside the disk image (many trials and errors). If more control is required (e.g. icon positioning, background image...) we recommend using 3rd party tools created specifically for this purpose. Some free/open-source examples are: - [create-dmg](https://github.com/sindresorhus/create-dmg) - [dmgbuild](https://dmgbuild.readthedocs.io/en/latest/) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-desktop-macos.md --- uid: uno.publishing.desktop.macos --- # Publishing Your App for macOS There are several options to publish your macOS application to your customers. They all start with creating an [app bundle](https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html) (.app). > [!IMPORTANT] > Publishing for macOS is only supported on macOS ## Create an app bundle (.app) The most basic app bundle can be created with: ```bash dotnet publish -f net9.0-desktop -r {{RID}} -p:PackageFormat=app ``` Where `{{RID}}` is either `osx-x64` or `osx-arm64`. The resulting app bundle, which is a directory, will be located at `bin/Release/net9.0-desktop/{{RID}}/publish/{{APPNAME}}.app`. > [!NOTE] > The [structure of the app bundle](https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html) requires a [custom native host](https://learn.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting) to run the app. As such, starting with Uno 6.1, the app bundles are **always** built as a self-contained executable, even if the `SelfContained` property is not set to `true` inside the project. ### Code Signing > [!IMPORTANT] > The code signing process requires access to the Internet to retrieve a secure timestamp. To ensure the integrity of the app bundle Apple requires you to digitally sign your code. The key difference to producing a signed app bundle is to add `-p:CodesignKey={{identity}}` to specify which identity should be used to produce the signature. ```bash dotnet publish -f net9.0-desktop -r {{RID}} -p:PackageFormat=app -p:CodesignKey={{identity}} ``` You can use the special identity `-` to produce an ad-hoc signature. This basically tells macOS's [Gatekeeper](https://support.apple.com/en-us/102445) that the file is safe to use **locally**, however, it does not help distribute the app bundle. > [!NOTE] > Besides needed access to the Internet the code signing process slows down the builds. For local testing of your app, you do not need to sign the app bundle. #### How to find your identity If you have not already, you need to create your [developer certificates](https://developer.apple.com/help/account/create-certificates/create-developer-id-certificates/). Once you have created them, on your Mac computer, you can find your identities from the CLI, by running: ```bash security find-identity -v ``` This will show you every **valid** identity available on your Mac. ```text 1) 8C8D47A2A6F7428971A8AA5C6D8F7A30D344E93C "Apple Development: John Appleby (XXXXXXXXXX)" 2) F84D25AAF30BAFA988D8B4CE8A0BA3BE891199D8 "Developer ID Installer: John Appleby (XXXXXXXXXX)" 3) 0357503C3CF78B093A764EA382BF10E7D3AEDA9A "Apple Distribution: John Appleby (XXXXXXXXXX)" 4) A148697E815F6090DE9698F8E2602773296E2689 "Developer ID Application: John Appleby (XXXXXXXXXX)" 4 valid identities found ``` To properly sign an app bundle for publishing you need to use the `"Developer ID Application: *"` or its thumbprint (long hex number) entry as the identity. Both ```bash dotnet publish -f net9.0-desktop -r {{RID}} -p:PackageFormat=app -p:CodesignKey="Developer ID Application: John Appleby (XXXXXXXXXX)" ``` and ```bash dotnet publish -f net9.0-desktop -r {{RID}} -p:PackageFormat=app -p:CodesignKey=A148697E815F6090DE9698F8E2602773296E2689 ``` are functionally identical and will produce a signed app bundle. ## Distributing the app bundle An app bundle is a directory and, as such, is not easy to distribute. Most macOS applications are distributed using one of the following methods. ### Installer (.pkg) You can easily create an installer package for your app bundle. This will produce a single, compressed executable file that can be shared (if signed and notarized) with anyone using a Mac computer. From the CLI run: ```bash dotnet publish -f net9.0-desktop -r {{RID}} -p:PackageFormat=pkg -p:CodesignKey={{identity}} -p:PackageSigningKey={{installer_identity}} ``` Where the following changes to the previous command are: - modifying `PackageFormat` to `pkg` to produce the package. This package will include the app bundle inside it, so the `CodesignKey` argument is still required; - adding `-p:PackageSigningKey={{installer_identity}}` to specify which identity should be used to sign the package. Unlike app bundles, signing requires a `Developer ID Installer: *` identity. The resulting installer will be located at `bin/Release/net9.0-desktop/{{RID}}/publish/{{APPNAME}}.pkg`. > [!IMPORTANT] > The installer can behave weirdly locally (or on CI) since the app bundle name is known to macOS and it will try to update the application, where it was built or copied, instead of installing a copy of it under the `/Applications/` directory. Ensure you are testing your package installer on a different Mac or inside a clean virtual machine (VM). #### Notarize the package Having both the app bundle (.app) and installer (.pkg) signed is insufficient. As the package is binary and you'll share it with customers, Apple must also notarize it. The first step is to store your Apple Account credentials inside the key store. This makes all the further commands (and notarization) much simpler. From the CLI run: ```bash xcrun notarytool store-credentials {{notarytool-credentials}} --apple-id john.appleby@platform.uno --team-id XXXXXXXXXX --password aaaa-bbbb-cccc-dddd ``` where - `{{notarytool-credentials}}` is the name of your credentials inside the key store. - `--apple-id` provides the email address used for your [Apple Account](https://developer.apple.com/account). - `--team-id` provides your team ID, a 10-character code. [How to find it](https://developer.apple.com/help/account/manage-your-team/locate-your-team-id). - `--password` is an [app specific password](https://support.apple.com/en-us/102654) created specifically for `notarytool` > [!NOTE] > Since Apple Accounts requires two factors authentication (2FA) you will need to [create an app-specific password](https://support.apple.com/en-us/102654) for `notarytool`. ```text This process stores your credentials securely in the Keychain. You reference these credentials later using a profile name. Validating your credentials... Success. Credentials validated. Credentials saved to Keychain. To use them, specify `--keychain-profile "notarytool-credentials"` ``` Once this (one-time) setup is done, you can notarize the disk image while building the app. From the CLI run: ```bash dotnet publish -f net9.0-desktop -r {{RID}} -p:SelfContained=true -p:PackageFormat=dmg -p:CodesignKey={{identity}} -p:PackageSigningKey={{installer_identity}} -p:UnoMacOSNotarizeKeychainProfile={{notarytool-credentials}} -bl ``` where - `{{notarytool-credentials}}` is the name of your credentials inside the key store - `-bl` will create a binary log of your build. This will include information about the notarization process. > [!NOTE] > Running this command might [take a while](https://developer.apple.com/documentation/security/customizing-the-notarization-workflow) as it will wait for the notarization process to complete on Apple servers. Once completed you can distribute the package installer. ### Disk Image (.dmg) Another common way to distribute your macOS software is to create a disk image (.dmg). This will produce a single, compressed disk image that can be shared (if signed and notarized) with anyone using a Mac computer. To create a disk image from the CLI run: ```bash dotnet publish -f net9.0-desktop -r {{RID}} -p:SelfContained=true -p:PackageFormat=dmg -p:CodesignKey={{identity}} -p:DiskImageSigningKey={{identity}} ``` Where the following changes to the original command are - modifying `PackageFormat` to `dmg` to produce the disk image. This image will include the app bundle inside it, so the `CodesignKey` argument is still required; - adding `-p:DiskImageSigningKey={{identity}}` to specify which identity should be used to sign the package. Like app bundles, the signing step requires using a `Developer ID Application: *` identity. The resulting disk image will be located at `bin/Release/net9.0-desktop/{{RID}}/publish/{{APPNAME}}.dmg`. #### Notarize the disk image Like an installer (.pkg) a disk image is the outermost container that you'll share with customers and, as such, needs to be notarized by Apple. The first step is to store your Apple Account credentials inside the key store. This makes all the further commands (and notarization) much simpler. From the CLI run: ```bash xcrun notarytool store-credentials {{notarytool-credentials}} --apple-id john.appleby@platform.uno --team-id XXXXXXXXXX --password aaaa-bbbb-cccc-dddd ``` where - `{{notarytool-credentials}}` is the name of your credentials inside the key store. - `--apple-id` provides the email address used for your [Apple Account](https://developer.apple.com/account). - `--team-id` provides your team ID, a 10-character code. [How to find it](https://developer.apple.com/help/account/manage-your-team/locate-your-team-id). - `--password` is an [app specific password](https://support.apple.com/en-us/102654) created specifically for `notarytool` > [!NOTE] > Since Apple Accounts requires two factors authentication (2FA) you will need to [create an app-specific password](https://support.apple.com/en-us/102654) for `notarytool`. ```text This process stores your credentials securely in the Keychain. You reference these credentials later using a profile name. Validating your credentials... Success. Credentials validated. Credentials saved to Keychain. To use them, specify `--keychain-profile "notarytool-credentials"` ``` Once this (one-time) setup is done, you can notarize the disk image while building the app. From the CLI run: ```bash dotnet publish -f net9.0-desktop -r {{RID}} -p:SelfContained=true -p:PackageFormat=dmg -p:CodesignKey={{identity}} -p:DiskImageSigningKey={{identity}} -p:UnoMacOSNotarizeKeychainProfile={{notarytool-credentials}} -bl ``` where - `{{notarytool-credentials}}` is the name of your credentials inside the key store - `-bl` will create a binary log of your build. This will include information about the notarization process. > [!NOTE] > Running this command might [take a while](https://developer.apple.com/documentation/security/customizing-the-notarization-workflow) as it will wait for the notarization process to complete on Apple servers. Once completed you can distribute the notarized disk image. ### Mac App Store > [!IMPORTANT] > Applications distributed on the Mac App Store are required to execute under a [sandbox](https://developer.apple.com/documentation/security/app-sandbox?language=objc), which imposes additional limits on how applications can interact with the computer. An app bundle (.app) can be submitted to Apple's [App Store](https://www.apple.com/app-store/) using the [transporter app](https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds) from a computer running macOS. > [!NOTE] > Notarization of the app bundle is **not** required as the Apple App Store will be taking care of your app binary distribution. ## Troubleshooting ### Apple Developer Account An active Apple Developer Account is **required** for code signing and notarization. An error, such as the one below, means that the Apple Developer Account is not active or the necessary agreements have not been signed. ```text Uno.Sdk.Extras.Publish.MacOS.targets(75,3): error : Failed to submit tmpcZQgA4.zip to Apple's notarization service. Exit code: 1: Error: HTTP status code: 403. A required agreement is missing or has expired. This request requires an in-effect agreement that has not been signed or has expired. Ensure your team has signed the necessary legal agreements and that they are not expired. ``` Try logging into your [Apple Developer Account](https://developer.apple.com/account) to see if any action is required to activate your account. Once re-enabled, it might take a few minutes (for the update to propagate) before you can sign or notarize your app bundle. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-desktop.linux.md --- uid: uno.publishing.desktop.linux --- # Publishing Your App for Linux ## Snap Packages We support creating .snap packages on **Ubuntu 20.04** or later. ### Requirements The following must be installed and configured: ```bash sudo apt-get install -y snapd sudo snap install core22 sudo snap install multipass sudo snap install lxd sudo snap install snapcraft lxd init --minimal sudo usermod --append --groups lxd $USER # In order for the current user to use LXD ``` > [!NOTE] > In the above script, replace `core22` with `core20` if building on Ubuntu 20.04, or `core24` if building on Ubuntu 24.04. > [!NOTE] > Docker may interfere with Lxd causing network connectivity issues, for solutions see: > https://documentation.ubuntu.com/lxd/en/stable-5.0/howto/network_bridge_firewalld/#prevent-connectivity-issues-with-lxd-and-docker ### Generate a Snap file To generate a snap file, run the following: ```shell dotnet publish -f net9.0-desktop -p:SelfContained=true -p:PackageFormat=snap ``` The generated snap file is located in the `bin/Release/netX.0-desktop/linux-[x64|arm64]/publish` folder. Uno Platform generates snap manifests in classic confinement mode and a `.desktop` file by default. If you wish to customize your snap manifest, you will need to pass the following MSBuild properties: - `SnapManifest` - `DesktopFile` You may use absolute or relative (to the `.csproj`) paths. The `.desktop` filename MUST conform to the [Desktop File](https://specifications.freedesktop.org/desktop-entry-spec/latest) spec. If you wish, you can generate a default snap manifest and desktop file by running the command above, then tweak them. > [!NOTE] > .NET 9 publishing and cross-publishing are not supported as of Uno 5.5, we will support .NET 9 publishing soon. #### CI Restrictions When building in a CI environment, security restrictions may prevent LXD and Multipass from running properly. In such cases, and if your environment is built using single-use environments like Azure DevOps Hosted Agents, you can enable the Snap [destructive mode](https://snapcraft.io/docs/explanation-architectures#destructive-mode) with the following parameter to the `dotnet publish` command: ```bash -p:UnoSnapcraftAdditionalParameters=--destructive-mode ``` > [!IMPORTANT] > Using this mode will make destructive changes to your environment, make sure that you will use this mode on a single-use virtual environment (e.g. Docker or Azure DevOps Hosted Agents). ### Publish your Snap Package You can install your app on your machine using the following: ```bash sudo snap install MyApp_1.0_amd64.snap --dangerous --classic ``` You can also publish your app to the [Snap store](https://snapcraft.io/store). ## Limitations - NativeAOT is not yet supported - R2R is not yet supported - Single file publishing is not yet supported > [!NOTE] > Publishing is a [work in progress](https://github.com/unoplatform/uno/issues/16440) ## Links - [Snapcraft.yaml schema](https://snapcraft.io/docs/snapcraft-yaml-schema) - [Desktop Entry Specification](https://specifications.freedesktop.org/desktop-entry-spec/latest) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-desktop.md --- uid: uno.publishing.desktop --- # Publishing Your App For Desktop ## Preparing For Publish - [Profile your app with Visual Studio](https://learn.microsoft.com/en-us/visualstudio/profiling) - [Profile using dotnet-trace and SpeedScope](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-trace) ## Publish Using Visual Studio - In the debugger toolbar drop-down, select the `net9.0-desktop` or `net10.0-desktop` target framework - Once the project has reloaded, right-click on the project and select **Publish** - Select the **Folder** target for your publication then click **Next** - Select the **Folder** target again then **Next** - Choose an output folder then click **Finish** - The profile is created, you can now **Close** the dialog - In the opened editor, click `Show all settings` - Set **Configuration** to `Release` - Set **Target framework** to `net9.0-desktop` or `net10.0-desktop` - You can set **Deployment mode** to either `Framework-dependent` or `Self-contained` - If `Self-contained` is chosen and you're targeting Windows, **Target runtime** must match the installed .NET SDK runtime identifier as cross-publishing self-contained WPF apps (e.g. win-x64 to win-arm64) is not supported for now. - You can set **Target runtime**, make sure it honors the above limitation, if it applies. - Click **Save** - Click **Publish** ## Publish Using The CLI On Windows/macOS/Linux, open a terminal in your `csproj` folder and run: ```shell dotnet publish -f net10.0-desktop ``` If you wish to do a self-contained publish, run the following instead: ```shell dotnet publish -f net10.0-desktop -r {{RID}} -p:SelfContained=true -p:TargetFrameworks=net10.0-desktop ``` Where `{{RID}}` specifies [the chosen OS and Architecture](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog) (e.g. win-x64). When targeting Windows, cross-publishing to architectures other than the currently running one is not supported. > [!IMPORTANT] > Due to changes in the .NET SDK, when providing an `{{RID}}` you will also need to add the following parameter `-p:TargetFrameworks=net10.0-desktop` for the publish command to succeed. ### Single-file publish [Single file](https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=cli) publishing is supported with the following parameters: ```shell dotnet publish -f net10.0-desktop -r {{RID}} -p:SelfContained=true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeAllContentForSelfExtract=true ``` Same as above, make sure to replace the `{{RID}}` with [a valid value](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog). The `IncludeNativeLibrariesForSelfExtract` and `IncludeAllContentForSelfExtract` properties can also be set in a `PropertyGroup` in the `.csproj`. ### Windows ClickOnce Uno Platform supports publishing desktop apps using **ClickOnce** to Windows environments. To publish your app that targets `net10.0-desktop` in your `.csproj`, you'll need to create a `.pubxml` file using Visual Studio, or use the file below: # [**Using a Sample Profile**](#tab/windows) Create a file named `Properties\PublishProfiles\ClickOnceProfile.pubxml` in your project with the following contents: ```xml 0 1.0.0.* True Release False true True Disk True False True False x64 ClickOnce False False win-x64 True (none) False false net10.0-desktop False Foreground False Publish.html bin\Release\net10.0-desktop\win-x64\app.publish\ bin\publish\ true .NET Desktop Runtime 10.0.1 (x64) ``` # [**Using the Wizard**](#tab/vs-wizard) > [!NOTE] > An existing Visual Studio issue prevents the **Publish** context menu from being active > if iOS/Android are present in the TargetFrameworks list. In order to create > the file, you can temporarily remove those target frameworks from `TargetFrameworks` in > order to create the `.pubxml` file generated. To use the Visual Studio publishing wizard: - Select the `netX.0-desktop` target framework in the debugger drop-down - In the Solution Explorer, right click on your project then select **Publish** - Click the **+ New profile** button - Select **ClickOnce**, then **Next** - Configure your app publishing in all the following wizard pages - In the **Configuration** section, make sure to select **Portable** for the **Target runtime** - Click **Finish**. The `Properties\PublishProfiles\ClickOnceProfile.pubxml` file will be created. *** Once done, you can use the following command in your CI environment, or using a **Developer Command Prompt for Visual Studio**: ```shell msbuild /m /r /target:Publish /p:Configuration=Release /p:PublishProfile="Properties\PublishProfiles\ClickOnceProfile.pubxml" /p:TargetFramework=net9.0-desktop ``` The resulting package will be located in the `bin\publish` folder. You can change the output folder using `/p:UnoClickOncePublishDir=your\output\directory`. Depending on your deployment settings, you can run the `Setup.exe` file to install the application on a machine. > [!IMPORTANT] > At this time, publishing with the [Visual Studio Publishing Wizard](https://learn.microsoft.com/visualstudio/deployment/quickstart-deploy-using-clickonce-folder?view=visualstudio) > is not supported for multi-targeted projects. Using the command line above is required. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-ios.md --- uid: uno.publishing.ios --- # Publishing Your App for iOS ## Preparing For Publish - [Performance Profiling](xref:Uno.Tutorials.ProfilingApplications) ## Building your app ### Packaging your app using the CLI > [!IMPORTANT] > Publishing for iOS is only supported on macOS First, you'll need to setup to be able to build iOS apps. You can follow [these steps for publishing .NET iOS apps](https://learn.microsoft.com/dotnet/maui/ios/deployment/?view=net-maui-8.0). Then, you'll need to setup your `csproj` to include the signing information: ```xml iPhone Distribution ios-arm64 ``` To build your app from the CLI on macOS: - Open a terminal, command line, or powershell - Navigate to your `csproj` folder - Publish the app using: ```shell dotnet publish -f net9.0-ios -c Release -o ./publish ``` The output `.ipa` file will be in the `publish` folder. ## Publishing your app on the App Store Publishing your app is done through [the transporter app](https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds) on macOS. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-overview.md --- uid: uno.publishing.overview --- # Publishing Your App (App Packaging) Uno Platform provides **integrated, automated packaging** for every supported platform, covering desktop, mobile, web, and embedded, with no third-party tools or extra setup required. Packaging is part of the standard `.NET publish` workflow, so you can go from code to distributable packages in a single command. ## Why It Matters App packaging is the bridge between a working build and an installable application. Each OS has unique signing, metadata, and distribution requirements, which can make deployment complex for cross-platform projects. Typical tasks include: - Building and publishing binaries - Generating assets and manifests - Applying code signing and notarization - Assembling installable formats (MSIX, .app, APK, IPA, etc.) - Preparing for distribution or app store submission Traditionally, .NET developers rely on custom scripts or third-party tools to manage this complexity. Uno Platform automates it out of the box. ## The Broader Platform Packaging Ecosystem | Platform | Formats | Signing | Distribution | Complexity | |-----------|----------|----------|---------------|-------------| | **Windows** | MSIX, MSI, ClickOnce | Certificates | Microsoft Store, Direct | Multiple formats; Store validation | | **macOS** | .app, .pkg, .dmg | Apple certs + notarization | App Store, Direct | Mandatory notarization; complex signing | | **Linux** | Snap, AppImage, DEB, RPM | Optional | Snap Store, Direct | Multiple package managers | | **Android** | APK, AAB | Keystore | Google Play, Direct | AAB for Play; Keystore management | | **iOS** | IPA | Provisioning profiles | App Store, TestFlight | Strict signing; Profile management | | **WebAssembly** | Static files, PWA | HTTPS / CSP | Web hosting | Service workers; PWA manifest | ## What Uno Platform Provides Out of the Box Uno Platform simplifies all of this with a unified, automated approach: | Platform | Package Formats | Code Signing | Store Ready | Status | |-----------|----------------|---------------|-------------|---------| | **Windows** | MSIX, ClickOnce | ✅ | ✅ Microsoft Store | ✅ Available | | **macOS** | .app, .pkg, .dmg | ✅ | ✅ App Store | ✅ Available | | **Linux** | Snap | ✅ | ✅ Snap Store | ✅ Available | | **Android** | APK, AAB | ✅ | ✅ Google Play | ✅ Available | | **iOS** | IPA | ✅ | ✅ App Store | ✅ Available | | **WebAssembly** | Static files, PWA | ✅ | ✅ Web hosting | ✅ Available | ## Key Features - **Native `dotnet publish` Integration** – No separate tools required. Works with your CI/CD pipelines. - **Cross-Platform Build Support** – Build Windows packages from Linux or macOS, and vice versa. - **Advanced Publishing Options** – Self-contained deployments, single-file packaging, Native AOT (where supported). - **Automated Everything** – Manifest generation, asset resizing, signing, and platform-specific optimization. Example command for Android AAB: ```bash dotnet publish -f net9.0-android -p:AndroidPackageFormat=aab ``` The same command pattern applies to Windows, macOS, Linux, iOS, and WebAssembly. ## Preparing Before publishing, make sure your app is optimized: - [Configure the IL Linker](xref:uno.articles.features.illinker) - [Enable XAML and Resource Trimming](xref:Uno.Features.ResourcesTrimming) - [Improve Performance](xref:Uno.Development.Performance) ## Platform-Specific Guides - [Packaging for Desktop](xref:uno.publishing.desktop) (`netX.0-desktop`) - [Packaging for WebAssembly](xref:uno.publishing.webassembly) (`netX.0-browserwasm`) - [Packaging for iOS](xref:uno.publishing.ios) (`netX.0-ios`) - [Packaging for Android](xref:uno.publishing.android) (`netX.0-android`) - [Packaging for Windows App SDK](xref:uno.publishing.windows) (`netX.0-windows10.yyy`) ## Continuous Integration Uno Platform provides built-in [CI integrations](xref:Uno.GettingStarted.UsingWizard#11-ci-pipeline) for Azure DevOps and GitHub Actions, included as part of the Uno Platform project templates. These pipelines include ready-to-use packaging steps for all supported platforms. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-webassembly.md --- uid: uno.publishing.webassembly --- # Publishing Your App for WebAssembly ## Preparing For Publish - [Configure deep linking](xref:UnoWasmBootstrap.Features.DeepLinking) - [Configure WebAssembly AOT modes](xref:Uno.Wasm.Bootstrap.Runtime.Execution) - [Profile the memory of your app](xref:Uno.Wasm.Bootstrap.Profiling.Memory) You can view more on the [WebAssembly Bootstrapper](xref:UnoWasmBootstrap.Overview) options. ## Packaging ### Packaging your app using Visual Studio 2022/2026 To build your app for WebAssembly: - In the debugger toolbar drop-down, select the `net9.0-browserwasm` target framework - Once the project has reloaded, right-click on the project and select **Publish** - Select the appropriate target for your publication, this example will use the **Folder**, then click **Next** - Choose an output folder for the published output, then click **Close**. - In the opened editor, on the top right, click the **Publish** button - Once the build is done, the output is located in the `wwwroot` folder Once done, you can head over to [publishing section](xref:uno.publishing.webassembly#publishing). ### Packaging your app using the CLI To build your app from the CLI, on Windows, Linux, or macOS: - Open a terminal, command line, or powershell - Navigate to your `csproj` folder - Publish the app using: ```shell dotnet publish -f net9.0-browserwasm -c Release -o ./publish ``` - Once the build is done, the output is located in the `./publish/wwwroot` folder Once done, you can head over to [publishing section](xref:uno.publishing.webassembly#publishing). ## Publishing your WebAssembly App Publishing your app can be done to different servers and cloud providers. - [How to host a WebAssembly App](xref:Uno.Development.HostWebAssemblyApp) - [Publishing to Azure Static Apps](xref:Uno.Tutorials.AzureStaticWebApps) - [Server locally using dotnet-serve](https://github.com/natemcmaster/dotnet-serve) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-windows-packaged-signed.md --- uid: uno.publishing.windows.sideload.packaged.signed --- # Build a signed packaged app This guide will show how to create a signed packaged app using Windows App SDK. > [!IMPORTANT] > Building your app requires using the msbuild command (`dotnet build` is not compatible as of WinAppSDK 1.5). ## Package signed the app This guide uses a self-signed certificate. To package your app: - Create a self-signed certificate: - Open the solution in Visual Studio - Ensure that the active debugging target framework is `net10.0-windows10.0.xxxxx` - Double-click on the `Package.appxmanifest` file - Navigate to the `Packaging` tab - Click the **Choose certificate** button - Click the **Create** button, then set a **publisher common name**, then OK. Do not set a password. - Close the **Choose a Certificate** window by clicking OK. - Click the **Save file** button in the Visual Studio toolbar - Navigate to the folder of the app's `.csproj` (Building at the solution level is not supported) - Build the app on the command line with the following command: ```shell # For .NET 9: msbuild /r /p:TargetFramework=net9.0-windows10.0.26100 /p:Configuration=Release /p:Platform=x64 /p:GenerateAppxPackageOnBuild=true /p:AppxBundle=Never /p:UapAppxPackageBuildMode=Sideloading /p:AppxPackageDir="C:/temp/output/" /p:AppxPackageSigningEnabled=true # For .NET 10: msbuild /r /p:TargetFramework=net10.0-windows10.0.26100 /p:Configuration=Release /p:Platform=x64 /p:GenerateAppxPackageOnBuild=true /p:AppxBundle=Never /p:UapAppxPackageBuildMode=Sideloading /p:AppxPackageDir="C:/temp/output/" /p:AppxPackageSigningEnabled=true ``` To package your app for the Microsoft App Store, the process is similar to creating a self-signed app package with just a minor difference: - Instead of linking to a self-signed certificate, associate your project with a Microsoft Store Application by right-clicking on your project in the solution explorer, then the **Publish**, **Associate App with Store...** menu item. - Build the app on the command line with the following command: ```shell msbuild /r /p:TargetFramework=net9.0-windows10.0.26100 /p:Configuration=Release /p:Platform=x64 /p:GenerateAppxPackageOnBuild=true /p:AppxBundle=Never /p:UapAppxPackageBuildMode=StoreUpload /p:AppxPackageDir="C:/temp/output/" ``` In order to build for additional platforms, change the `Platform` parameter to `x86` or `arm64` to create additional MSIX files. > [!IMPORTANT] > Single package msix bundling is [not yet supported from msbuild the command line](https://learn.microsoft.com/windows/apps/windows-app-sdk/single-project-msix?tabs=csharp#automate-building-and-packaging-your-single-project-msix-app). The individual msix packages can be assembled after creation using Microsoft's `makeappx.exe` tool installed with the Windows SDK in 'Windows Kits' folder, for example `C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\makeappx.exe`. To bundle the individual msix packages, move them all to a common folder, for example, "C:\Temp\Output\MyApp", and run the following command: ```shell "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\makeappx.exe" bundle /d "C:\Temp\Output\MyApp" /p "C:\Temp\Output\MyApp.msixbundle" ``` > [!TIP] > The `makeappx.exe` tool is also available from the environment when opening a [**Developer Command Prompt for VS 2022**](https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022) ## Considerations for solutions with class library projects If your app references multiple library projects, you will need to split the above build command into two parts, one to restore NuGet packages, and the other one to create the package. To build your solution: - Add the following to your app's csproj: ```xml true Never Sideloading true ``` - Run this command to restore the NuGet packages: ```shell msbuild /r /t:Restore /p:Configuration=Release ``` - Then run this command: ```shell msbuild /p:TargetFramework=net9.0-windows10.0.26100 /p:Configuration=Release /p:Platform=x64 /p:PublishSignedPackage=true /p:AppxPackageDir="C:/temp/output/" ``` Notice that this command does not contain the `/r`. ## Install the signed Windows app To install the app: - Install the certificate on the machine: - In the file explorer, right-click on the `.msix` file, then **Show More Options** on Windows 11, then **Properties** - Open the **Digital signatures** tab - Click on your certificate then **Details** - Click the **View Certificate** button - Click the **Install Certificate** button - Select **Local Machine** then **Next** - Click **Place all certificates in the following store** then **Browse** - Select **Trusted People** then **OK** - Click **Next**, then **Finish** - Close all the opened properties windows. - Install the `.msix` by double-clicking on it The app will start automatically once installed. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-windows-packaged-unsigned.md --- uid: uno.publishing.windows.sideload.packaged.unsigned --- # Build an unsigned packaged app This guide will show how to create an unsigned packaged app using Windows App SDK. > [!IMPORTANT] > Building your app requires using the msbuild command (`dotnet build` is not compatible as of WinAppSDK 1.5). ## Package the unsigned app Packaging the app without a code signature allows for installing the app on a machine without having to install the signer's certificate. This portion of the guide is derived from the [official Windows App SDK documentation](https://learn.microsoft.com/en-us/windows/msix/package/unsigned-package). To package your app: - Update the `Package.appxmanifest` file with the following `Identity` node to include the following `OID`: ```xml ``` - Navigate to the folder of the app's `.csproj` (Building at the solution level is not supported) - Build your app using the following command: ```pwsh msbuild /r /p:TargetFramework=net9.0-windows10.0.26100 /p:Configuration=Release /p:Platform=x64 /p:GenerateAppxPackageOnBuild=true /p:AppxBundle=Never /p:UapAppxPackageBuildMode=Sideloading /p:AppxPackageDir="C:/temp/output/" /p:AppxPackageSigningEnabled=false ``` In order to build for additional platforms, change the `Platform` parameter to `x86` or `arm64` to create additional MSIX files. ## Considerations for solutions with class library projects If your app references multiple library projects, you will need to split the above build command into two parts, one to restore NuGet packages, and the other one to create the package. To build your solution: - Add the following to your app's csproj: ```xml true Never Sideloading false ``` - Run this command to restore the NuGet packages: ```pwsh msbuild /r /t:Restore /p:Configuration=Release ``` - Then run this command: ```pwsh msbuild /p:TargetFramework=net9.0-windows10.0.26100 /p:Configuration=Release /p:Platform=x64 /p:PublishUnsignedPackage=true /p:AppxPackageDir="C:/temp/output/" ``` Notice that this command does not contain the `/r`. ## Install the unsigned Windows app To install the app: - Start an elevated PowerShell command prompt (Search for PowerShell in the start menu, right-click on it then Run as administrator): - In the folder containing the `.msix` file, execute the following command : ```pwsh Add-AppPackage -AllowUnsigned ".\MyApp.appx" ``` For more information, see the [official documentation](https://learn.microsoft.com/en-us/windows/msix/package/unsigned-package#install-an-unsigned-package). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-windows-unpackaged.md --- uid: uno.publishing.windows.sideload.unpackaged.unsigned --- # Publish an unpackaged app This guide will show you how to create an unpackaged app using Windows App SDK. > [!IMPORTANT] > Building your app requires using the msbuild command (`dotnet build` is not compatible as of WinAppSDK 1.5). > [!NOTE] > Uno Platform also supports building apps for using the `net9.0-desktop` target framework, using Uno Platform's own Skia Desktop implementation. ## Build the app for publishing Packaging the app without a code signature allows the app to be installed on a machine without installing the signer's certificate. This guide portion is derived from the [official Windows App SDK documentation](https://learn.microsoft.com/en-us/windows/msix/package/unsigned-package). To publish your app: 1. Navigate to the folder of the app's `.csproj` (Building at the solution level is not supported) 2. Build your app using the following command: ```pwsh msbuild /r /t:publish /p:TargetFramework=net9.0-windows10.0.26100 /p:Configuration=Release /p:Platform=x64 /p:PublishDir=c:\temp\myoutput ``` In order to build for additional platforms, change the `Platform` parameter to `x86` or `arm64` to create additional MSIX files. ## Publish the Windows app Publishing your app can be done through different means: - [ClickOnce](https://learn.microsoft.com/visualstudio/deployment/quickstart-deploy-using-clickonce-folder?view=vs-2022) - Using a Zip file, then running the app using `[yourapp].exe` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-publishing-windows.md --- uid: uno.publishing.windows --- # Publishing Your App for Windows App SDK ## Preparing For Publish ## Building your app Using the Windows App SDK, it's possible to side-load an app using the following: - [Build an unsigned packaged app](xref:uno.publishing.windows.sideload.packaged.unsigned) - [Build a signed packaged app](xref:uno.publishing.windows.sideload.packaged.signed) - [Build an unpackaged app](xref:uno.publishing.windows.sideload.unpackaged.unsigned) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-toolchain-telemetry.md --- uid: Uno.Development.ToolchainTelemetry --- # Uno Platform Build tools telemetry The [Uno Platform SDK](https://github.com/unoplatform/uno) includes a [telemetry feature](https://github.com/unoplatform/uno.devtools.telemetry) that collects usage information. It is important that the Uno Platform Team understands how the build tools are used so they can be improved. The collected data is anonymous. The telemetry behavior is based on the [.NET Core telemetry feature](https://learn.microsoft.com/dotnet/core/tools/telemetry). ## Scope The build tooling is used to generate XAML from code during the compilation of an Uno Platform project. This step collects telemetry. The application resulting of that build **does not collect telemetry**. ## How to opt out The Uno Platform SDK telemetry feature is enabled by default. Opt out of the telemetry feature by setting a global environment variable `UNO_PLATFORM_TELEMETRY_OPTOUT` set to `1` or `true`, or with an msbuild property named `UnoPlatformTelemetryOptOut` set to `1` or `true`. ## Data points The feature collects the following data: * Timestamp of invocation * The step invoked * The duration of the step * The exception type if the generation fails * If the build is running under a CI (Travis, Azure Devops, AppVeyor, Jenkins, GitHub Actions, BitBucket, Build kite, Codebuild, Drone, MyGet, Space, TeamCity) * Operating system name, version, kernel version, and architecture * The current culture * The current Uno Platform nuget package version * Target frameworks * Hashed (SHA256) current working directory * Hashed (SHA256) MAC address: a cryptographically anonymous and unique ID for a machine. The feature doesn't collect personal data, such as usernames or email addresses. It doesn't scan your code and doesn't extract sensitive project-level data, such as name, repo, or author. The data is sent securely to Microsoft servers using Microsoft Azure Application Insights technology, held under restricted access, and published under strict security controls from secure Azure Storage systems. The Uno Platform team wants to know how the build tools are used and if they're working well, not what you're building with the Uno Platform. If you suspect that the telemetry is collecting sensitive data or that the data is being insecurely or inappropriately handled, file an issue in the [unoplatform/uno](https://github.com/unoplatform/uno/issues) repository for investigation. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/contributing/guidelines/updating-dependencies.md --- uid: Uno.Contributing.UpdatingDependencies --- # Guidelines for updating dependencies We use Dependabot to notify the team of any updates to dependencies. Once a week, the robot will scan our dependencies and raise a pull-request if a new version is found. If an existing open pull-request is found for a dependency, it will be closed and replaced with a new pull-request.. ## Internal dependencies The following dependencies don't change the public API surface and are typically safe to merge and we could potentially [configure mergify to automatically merge them if CI passes](https://docs.mergify.com/workflow/automerge/): - BenchmarkDotNet - [FluentAssertions](https://github.com/unoplatform/uno/pull/1196) - [NUnit3TestAdapter](https://github.com/unoplatform/uno/pull/1455) - [NUnit.Runners](https://github.com/unoplatform/uno/pull/1122) - [Microsoft.AppCenter](https://github.com/unoplatform/uno/pull/1175) - [Microsoft.SourceLink.GitHub](https://github.com/unoplatform/uno/pull/1204) - [Microsoft.NET.Test.Sdk](https://github.com/unoplatform/uno/pull/1203) - [MSTest.TestAdapter](https://github.com/unoplatform/uno/pull/1126) - [MSTest.TestFramework](https://github.com/unoplatform/uno/pull/1128) - Moq The following dependencies require manual adjustments before merging: - [docfx.console](https://github.com/unoplatform/Uno/pull/1082/commits/c222caf8c23b35e19f6b33cd624cbfa714250bfe) - `Microsoft.CodeAnalysis.*`. Those dependencies need to be aligned with the source generation task package, for which the dependency cannot be be explicitly provided. - `Xamarin.GooglePlayServices.*`. Those dependencies are added per TargetFramework (Android SDK version), not updated. ## Public dependencies Updating public dependencies will require consumers to upgrade their dependencies and as such need consideration on a case by case basis is required before merging. ## additional care required The following dependencies require care and human testing: - [Microsoft.CodeAnalysis.*](https://github.com/unoplatform/uno/pull/1169) children packages needs to be aligned with the other `Microsoft.CodeAnalysis` packages. - [Microsoft.Build.*](https://github.com/unoplatform/uno/pull/1169) children packages needs to be aligned with the other `Microsoft.Build` packages. - [Microsoft.Extensions.Logging.*](https://github.com/unoplatform/uno/pull/1108/files#r300432589) child packages needs to be aligned with the other `Microsoft.Extensions.Logging` packages. Currently can't be upgraded because most recent versions are using thread, which are not supported on Wasm. - [Microsoft.UI.Xaml](https://github.com/unoplatform/uno/pull/1503): This dependency is needs to be aligned with the currently supported API set found in Uno. - [Microsoft.Extensions.Logging.Console](https://github.com/unoplatform/Uno/pull/894#issuecomment-495046929): Compatibility of this dependency should be confirmed against WebAssembly. ## chatops You can trigger Dependabot actions by commenting on the pull-request: ```text @dependabot recreate will recreate this PR, overwriting any edits that have been made to it @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself) @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) ``` Please do not use any of the `rebase|merge|squash and merge` chatops commands as they bypass our merging pull-request guidelines and `ready-to-merge` workflow. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/updating-to-winui3.md --- uid: Uno.Development.UpdatingToWinUI3 --- # Updating an Uno application to WinUI 3.0 Uno Platform supports authoring apps using [WinUI 3's API](uwp-vs-winui3.md). This article details the changes required when migrating an application from the UWP API set to the WinUI 3 API set. [Read more about WinUI 3 and Uno Platform.](uwp-vs-winui3.md) ## Migrating an app to WinUI 3.0 - **NuGet updates:** - `Uno.UI` becomes `Uno.WinUI` - `Uno.UI.DevServer` becomes `Uno.WinUI.DevServer` - `Uno.UI.Lottie` becomes `Uno.WinUI.Lottie` - `Uno.UI.Foldable` becomes `Uno.WinUI.Foldable` - **String replacements:** - `Windows.UI.Xaml` becomes `Microsoft.UI.Xaml` - `Windows.UI.Composition` becomes `Microsoft.UI.Composition` - **Update `App.xaml.cs`:** - If your solution was created with an older version of the Uno app template, you'll need to update `App.xaml.cs` for compatibility with WinUI 3/Project Reunion. Fixes to apply: - Ensure `Window` doesn't fall out of scope ([diff](https://github.com/unoplatform/uno/commit/0d5418dada17561f857cf13750762468b77dfbf0)) - Fix invalid defines ([diff](https://github.com/unoplatform/uno/commit/a4c3d3f5ec65071041a7b93f64d7175fbde189ac)) ## API Changes ### Changed or removed controls - `MapControl` is missing - `MediaPlayerElement` is missing - `WebView` is now `WebView2` For a full list of unavailable controls and visual features, as well as timelines for restoration in some cases, consult the [WinUI 3 Feature Roadmap](https://github.com/microsoft/microsoft-ui-xaml/blob/master/docs/roadmap.md#winui-30-feature-roadmap). ### WinRT API changes for Desktop apps Some WinRT APIs are unsupported in WinUI 3 Desktop apps, notably `CoreDispatcher`, `CoreWindow`, and `ApplicationView`. Consult [this guide](https://github.com/microsoft/microsoft-ui-xaml/blob/master/docs/winrt-apis-for-desktop.md) for supported alternatives to those APIs. `DispatcherQueue`, the replacement for `CoreDispatcher` in WinUI 3, is supported by Uno Platform. ## Creating an application from the templates Instructions are available in [Getting started with WinUI 3](get-started-winui3.md) for creating a new Uno Platform application targeting WinUI 3. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/upgrading-nuget-packages.md --- uid: Uno.Development.UpgradeUnoNuget --- # How to upgrade Uno Platform NuGet Packages Upgrading packages in your applications is done differently, depending on how your solution has been created. - If your Uno Platform `.csproj` files start with ` [!IMPORTANT] > In Visual Studio 2022/2026, once the Uno Version is updated, a banner will ask to restart the IDE. Once the solution is reopened the changes will take effect. > > At this time, the NuGet package Manager does not parse or manage Sdks provided by NuGet. If you would like to see this feature added, please be sure to provide your [feedback or upvote this issue](https://github.com/NuGet/Home/issues/13127). You can also browse the available versions of the Uno.Sdk using [Nuget Package Explorer](https://nuget.info). ## Projects without the Uno.Sdk To upgrade NuGet packages without the Uno.Sdk, you can use the [Nuget Package Manager](https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio) coming from Visual Studio. Choose the latest stable versions of Uno Platform's NuGet packages. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/upri-trimming.md --- uid: Uno.Features.StringResourceTrimming --- # String Resource Trimming Uno Platform provides a set of controls that are localized in many cultures, which may not be required for your app. String resource trimming is an optional feature used to reduce the final payload size of an Uno Platform application by removing unused localization languages throughout the app. ## Using String Resource Trimming To enable resources trimming, you need to declare which culture(s) your application uses. For example, in your csproj add: ```xml ``` You do not need to include parent cultures (`en` and `fr` in the previous example), they are automatically kept because they may be used as a fallback. Make sure to update [Uno.Wasm.Bootstrap](https://www.nuget.org/packages/Uno.Wasm.Bootstrap) to the latest 7.0.x or 8.0.x version. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-il-linker-webassembly.md --- uid: uno.articles.features.illinker --- # Using the IL Linker > [!NOTE] > This article is about the .NET IL Linker, you can also view information about [XAML and Resources Trimming](xref:Uno.Features.ResourcesTrimming). ## Support for features In order to improve the size of the application, some platforms are providing the ability to unconditionally disable features if the app is known not to use them. |Feature|MSBuild property|Description| |-----|----|---| |External Drag and Drop|`UnoDragDropExternalSupport`|Enables or disables drag and dropping content from **outside** the app using this property. Drag and Drop **inside** the app is always available when disabled.| For example, to disable external drag and drop support on WebAssembly, add the following to your csproj: ```xml false ``` ## WebAssembly The [linker step](https://github.com/dotnet/linker/tree/main/docs) (also known as tree shaking, or IL Trimming) is responsible for the detection and removal of code that may not be used at runtime. This step is particularly important when targeting WebAssembly or native code in general, to reduce significantly the final package size. The linker is generally efficient at removing code but in some cases it may remove too much code, making some assemblies fail to work properly. In particular, assemblies or features that rely on reflection don't work by default with the linker enabled. `JSON.NET` is a good example of this, as it relies on reflection very heavily. To handle cases where the default linker behavior removes too much code, the linker can be manually configured using the `LinkerConfig.xml` file in Uno projects. When parts of an application fail to work, you can: - Add full assembly names to the `LinkerConfig.xml` file: ```xml ``` - Add namespaces for the linker to ignore: ```xml ``` As a troubleshooting step to determine if the linker is causing your code to break, you can also disable the linker completely by adding the following to your `csproj` file: ```xml false ``` Note that disabling the linker is not recommended as it can force the compiler to generate very large WebAssembly modules AOT process, and go over the browser's size limits. You can find additional information about the linker step in Uno Platform in the [Linker configuration documentation](https://github.com/unoplatform/Uno.Wasm.Bootstrap/blob/main/doc/linker-configuration.md). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-linux-framebuffer.md --- uid: Uno.Skia.Linux.Framebuffer --- # Using the Linux FrameBuffer and `libinput` Uno Platform supports the [Linux FrameBuffer](https://www.kernel.org/doc/html/latest/fb/framebuffer.html) and [libinput](https://wayland.freedesktop.org/libinput/doc/latest/what-is-libinput.html) as a target, in the case where your target device does not provide a Window Manager. There are some restrictions for the support for the FrameBuffer: - The mouse is supported through pointer events, but Uno Platform does not show the pointer for your app. You'll need to display one using the pointer events provided by Uno Platform (also in the `CoreWindow` class). - It is only supported on Linux where `/dev/fbXX` is available. ## Get started with the FrameBuffer - Follow the [getting started guide](xref:Uno.GetStarted.vscode) Create a new app using: ```dotnetcli dotnet new unoapp -o MyApp ``` In the `Platforms/Desktop/Program.cs` file, the `UnoPlatformHostBuilder` can be configured to use the Framebuffer support, in case X11 support is detected first: ```csharp var host = UnoPlatformHostBuilder.Create() .App(() => new App()) .UseX11() .UseLinuxFrameBuffer() .UseMacOS() .UseWindows() .Build(); ``` Each platform support is evaluated in order for availability and definition in builder. X11 is chosen when the `DISPLAY` variable is present. ## Running the app You can build and run this app by navigating to the `MyApp` and type the following: ```dotnetcli dotnet run -f net9.0-desktop ``` The app will start and display on the first available framebuffer device. To change the active framebuffer, set the device name in the `FRAMEBUFFER` environment variable. By default, the `Debug` configuration is used, which will show logging information in the current terminal and may overwrite the UI content. To read the logging information, either: - Launch the application from a different terminal (through SSH, for instance) - Launch the app using `dotnet run -f net9.0-desktop > logging.txt 2>&1`, then launch `tail -f logging.txt` in another terminal. Once the application is running, you can exit the application with: - `Ctrl+C` - `F12`, a key configuration found in the `Program.cs` file of your project which invokes `Application.Current.Exit()` ## Creating a standalone app You can create a standalone publication folder using the following: ```dotnetcli dotnet publish -c Release -f net9.0-desktop -r linux-x64 --self-contained true ``` > [!NOTE] > When using the `Release` configuration, logging is disabled for performance considerations. You can restore logging in the `App.xaml.cs` file. Documentation on other hardware targets is [available here](https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md). ## DPI Scaling support Whenever possible, the `FrameBufferHost` will try to detect the actual DPI scale to use when rendering the UI, based on the physical information provided by the FrameBuffer driver. If the value cannot be determined, a scale of `1.0` is used. The automatic scaling can be overridden in two ways: - Set a value using `FrameBufferHost.DisplayScale`. - Set a value through the `UNO_DISPLAY_SCALE_OVERRIDE` environment variable. This value has precedence over the value specified in `FrameBufferHost.DisplayScale`. ## Additional dependencies If your device is significantly trimmed down for installed packages, you'll need to install: - `libfontconfig` - `libfreetype` - `libinput` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-markup.md --- uid: uno.development.using.markup --- # UI Markup Uno Platform provides two ways for defining your UI: WinUI XAML or [C# Markup](xref:Uno.Extensions.Markup.Overview). You can choose either one for developing your application, based on your preferences. > [!NOTE] > At this time, [Hot Design](xref:Uno.HotDesign.Overview) only supports designing XAML markup files. ## XAML Markup XAML is an XML based UI definition declarative language, and Uno Platform uses the WinUI 3 flavor. Elements such as `Grid`, `StackPanel` and `TextBlock` can be used to defined your user interface. For more information about XAML, see the [Microsoft documentation](https://learn.microsoft.com/en-us/windows/apps/design/layout/) on the topic. ## C# Markup C# Markup is a declarative, fluent-style syntax for defining the layout of an application in C#. With C# Markup, you can define both the layout and the logic of your application using the same language. C# Markup leverages the same underlying object model as XAML, meaning that it has all the same capabilities, such as data binding, converters, and access to resources. You can use all the built-in controls, any custom controls you create, and any 3rd party controls, all from C# Markup. For more information, see our overview of [C# Markup](xref:Uno.Extensions.Markup.Overview). ## Related documentation - [WinUI Development topics](xref:Uno.Development.WinUIDevelopmentDoc) - [WinUI Design](xref:Uno.Development.WinUIDesignDoc) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-native-rendering.md --- uid: uno.features.renderer.native --- # The Native Renderer The native renderer is our oldest backend, which uses the native components and APIs to render the UI. Each supported platform (iOS, Android, and WebAssembly) has its own set of platform interactions, listed below, allowing for deep integration of native components into the visual tree. Each `UIElement` has a corresponding native element (`div` on WebAssembly, `UIView` on iOS, `ViewGroup` on Android). This renderer uses the native input controls of the platforms, providing the best access to accessibility and IME features. This renderer supports [integrating native views](xref:Uno.Development.NativeViews). ## Web (WebAssembly) On WebAssembly, XAML elements are translated into HTML elements: - Panels and layout containers are materialized as `
` - Leaf controls like `TextBlock`, `Image` are materialized as semantic elements like `

`, ``, etc. This rendering integrates with CSS and DOM APIs, enabling UI behavior consistent with web standards. ## iOS - All `FrameworkElement` types are backed by native `UIView` instances. - Controls like `Image` implicitly create native `UIImageView` subviews. - Native input, layout, and accessibility features are utilized. ## Android - All `FrameworkElement` types inherit from native `ViewGroup`. - Controls like `Image` wrap native `ImageView` instances. - Leverages Android’s native rendering, accessibility, and gesture systems. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-skia-desktop.md --- uid: Uno.Skia.Desktop --- # Using the Skia Desktop Uno Platform supports running applications using a common Skia Desktop shell, which is automatically used based on the running platform, using a single build output using the `net9.0-desktop` target framework from the [Uno.Sdk](xref:Uno.Features.Uno.Sdk). The currently supported targets and platforms are: - Linux X11 - [Linux Framebuffer](xref:Uno.Skia.Linux.Framebuffer) - Windows (Using Win32 shell) - [macOS (Using an AppKit shell)](xref:Uno.Skia.macOS) The set of supported platforms can be defined by using the `UnoPlatformHostBuilder`, introduced in Uno Platform 5.2 and the [Single Project support](xref:Uno.Development.MigratingToSingleProject). ## Get started with the Skia Desktop head Follow the getting started guide for [VS Code](xref:Uno.GetStarted.vscode) or [Visual Studio](xref:Uno.GetStarted.vs2022), making sure to use the latest Uno Platform templates. Once created, in the `Platforms/Desktop/Program.cs` file, you'll find the following builder: ```csharp var host = UnoPlatformHostBuilder.Create() .App(() => new App()) .UseX11() .UseLinuxFrameBuffer() .UseMacOS() .UseWin32() .Build(); host.Run(); ``` This builder allows us to configure the SkiaHost and setup which platforms will be supported at runtime. The builder evaluates the platform's availability one by one, in the order of definition. ### Additional setup #### [**Linux**](#tab/linux) [!include[linux-setup](../includes/additional-linux-setup-inline.md)] --- ### Troubleshooting OpenGL integration Enabling debug logging messages for the Skia Host can help diagnose the render surface type selection. In your `App.xaml.cs` file, change the minimum log level to: ```csharp builder.SetMinimumLevel(LogLevel.Debug); ``` Then change the logging level of the Skia Host to `Information` or `Debug`: ```csharp builder.AddFilter("Uno.UI.Runtime.Skia", LogLevel.Information); ``` You may also need to initialize the logging system earlier than what is found in Uno.UI's default templates by calling this in `Main`: ```csharp YourAppNamespace.App.ConfigureFilters(); // Enable tracing of the Skia host ``` ## Upgrading to a later version of SkiaSharp By default, Uno Platform comes with a set of **SkiaSharp** dependencies. If you want to upgrade **SkiaSharp** to a later version, you'll need to specify all packages individually in your project as follows: ```xml ``` ## Windows Specifics ### RDP Hardware Acceleration The Uno Platform Skia Desktop runtime on Windows uses a WPF shell internally. By default, Uno Platform enables RDP hardware acceleration in order to get good performance, yet this feature is disabled by default in standard WPF apps with .NET 8. If you're having issues with the Windows support for Skia Desktop over RDP, add the following to your project: ```xml ``` ## X11 Specifics When running using X11 Wayland compatibility (e.g. recent Ubuntu releases), DPI scaling cannot be determined in a reliable way. In order to specify the scaling to be used by Uno Platform, set the `UNO_DISPLAY_SCALE_OVERRIDE` environment variable. The default value is `1.0`. The X11 support uses DBus for various interactions with the system, such as file selection. Make sure that dbus is installed. ## .NET Native AOT support Building an Uno Platform Skia Desktop app with .NET (7+) Native AOT requires Uno Platform 4.7 (or later). To build an app with this feature enabled: 1. Add the following property in your `.csproj`: ```xml true ``` 1. Add the following items in your `.csproj`: ```xml ``` 1. Build your app with: ```dotnetcli dotnet publish -c Release -f net9.0-desktop ``` > [!NOTE] > Cross-compilation support is not supported as of .NET 7. To build a Native AOT app for Linux or Mac, you'll need to build on the corresponding host. > [!NOTE] > .NET Native AOT on Windows is not yet supported as WPF does not support it at this time. For more information, see [the runtime documentation](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/reflection-in-aot-mode.md) and the [.NET Native AOT documentation](https://learn.microsoft.com/dotnet/core/deploying/native-aot/). --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-skia-hosting-native-controls.md --- uid: Uno.Skia.Embedding.Native --- # Embedding Native Elements in Skia Apps > [!NOTE] > This document describes Skia renderer native embedding, for other platforms/renderers see the [native views](xref:Uno.Development.NativeViews) documentation. In an Uno Platform app with a Skia renderer, i.e. using `net9.0-desktop` or adding `SkiaRenderer` to the `UnoFeatures` MSBuild property, you can embed native controls in your Skia app. This is useful if you want to use a native control for a specific task, for instance, to integrate an existing WPF control. Each target platform has its own idea of a native element. | Platform | Native element | Description | |---------------------------------|------------------------------------------------------------------------------------|----------------------------------------------| | Skia Desktop (Win32) | Uno.UI.NativeElementHosting.Win32NativeWindow | A native Windows window with a unique `Hwnd` | | Skia Desktop (WPF) | System.Windows.UIElement | A WPF control | | Skia Desktop (X11) | Uno.UI.NativeElementHosting.X11NativeWindow | A native X11 window with a unique `XID` | | Skia Desktop (macOS) | Not yet supported. | Not yet supported as of Uno Platform 6.0 | | WebAssembly with `SkiaRenderer` | [Uno.UI.NativeElementHosting.BrowserHtmlElement](xref:Uno.Interop.WasmJavaScript1) | An HTML element with a unique `id`. | | Android with `SkiaRenderer` | Android.Views.View | An Android view. | | Apple UIKit with `SkiaRenderer` | UIKit.UIView | An UIKit view. | The app developer is responsible for creating the native element and internal checks make sure that only a supported native element on the running platform is used. ## Using embedded native controls To embed a native element, you will need to set the native control as `Content` of a `ContentControl`, either via code or XAML. On desktop platforms, it's often more straightforward to create the native element via code since the parameters for creating the native element are not known ahead of time. For example, on Win32, you need to create a native Windows window first, get its `Hwnd` and then create a `Win32NativeWindow` instance with that `Hwnd` value. Do not set a `ContentTemplate` or a `ContentTemplateSelector` on the `ContentControl`. ## Features The layouting of native elements behaves mostly like regular `UIElement`s, using the native platform's measuring and arranging functions, e.g. `UIKit.UIView.SizeThatFits` on Apple UIKit, if they are present and defaulting to taking the entire available space on targets that don't have corresponding native measuring and arranging methods. On targets that don't have native measuring methods and expand to fill all available space, make sure that the wrapping `ContentControl` is not given infinite width or height when being measured, for example, by being put in a StackPanel. In those cases, limit the layout bounds by, for example, setting `MaxWidth`/`MaxHeight`/`Width`/`Height`. > [!NOTE] > `ContentControl` contains a `ContentPresenter` which hosts the actual native content. In the default `ContentControl` template, the `HorizontalAlignment` and `VerticalAlignment` of the `ContentPresenter` are bound to the `HorizontalContentAlignment` and `VerticalContentAlignment`, respectively, of the wrapping `ContentControl`, which are set by default to `Top` and `Left`, respectively. As a result, if your layout logic relies on the alignment/stretching of the `ContentControl`, you will likely want to set `ContentAlignment` to match `Alignment`. Furthermore, native elements blend and overlap naturally with Uno controls and respect Z-axis ordering. For example, if you open a popup on top of a native element, the popup will show on top of the element. Native-managed blending is not limited to rectangular boundaries and elements clipped with arbitrary paths work as expected. For example, elements with rounded corners that are placed on a native element will not show up as rectangles but behave as usual with rounded corners. Setting the `Opacity` of the wrapping `ContentControl` will also set the opacity of the hosted native element. Likewise, setting the `Visibility` of the wrapping `ContentControl` will flow to the native element and hide/show it. > [!NOTE] > As of Uno Platform 6.0, setting the opacity of native elements is not supported on X11. ## Limitations The native control is rendered by the native windowing system and cannot be styled by Uno Platform styles. While setting the transparency of native elements is supported, native elements don't alpha-blend. In other words, if a partially-transparent Uno control is placed on top of a native element, the native element will not be visible underneath the Uno control. Instead, the transparent area will behave as if the native element is not there and will only show managed Uno controls underneath. Focus and pointer/keyboard input work as expected most of the time, but, depending on the platform, you might find some quirks with the way inputs are handled. Placing Uno Controls outside of their layout bounds to be on top of native elements using `RenderTransform` or similar techniques will not clip correctly. The clipping of Uno controls is used to calculate which areas are painted by managed controls and how they overlap with native elements. If the clip bounds of a control are unbounded (i.e. the control isn't clipped at all), the clip bounds for managed-native overlapping purposes will be the layout rectangle of the control. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-skia-macos.md --- uid: Uno.Skia.macOS --- # Using the Desktop (Skia) on macOS ## Metal (Hardware Accelerated) Rendering All recent Mac computers support Metal. It has been required to run macOS 10.14 (Mojave). As such macOS hardware-accelerated [Metal](https://developer.apple.com/metal/) rendering is enabled by default. However, it's possible that under certain circumstances, like virtualization (including [GitHub CI](https://github.com/actions/runner-images/issues/1779)), Metal might not be available to applications. In this case, the host will **automatically** fall back to a software-based rendering. > [!NOTE] > Some Mac models released before 2012 did not support Metal. See Apple's support document [Support for Metal on Mac, iPad, and iPhone](https://support.apple.com/en-us/102894) for the list of devices that support Metal. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-skia-rendering.md --- uid: uno.features.renderer.skia --- # The Skia Renderer Available on iOS, Android, macOS, Windows, Linux and WebAssembly, based on the [Skia](https://skia.org) drawing library, the Skia Renderer is a cross-platform unified rendering component of Uno Platform which provides a single UI experience across all supported platforms. The whole UI Visual Tree is drawn on an hardware accelerated canvas, using Metal, OpenGL, and WebGL where applicable. Unlike Native rendering, Skia doesn’t rely on platform UI components. The Skia Rendering backend has a very cheap cost for creating UI elements, which makes it very efficient for large user interfaces. Starting with Uno.Sdk 6.0, **it is the default rendering engine** when creating a project from the templates. On **WebAssembly (Wasm)**, **Android**, and **iOS**, you can opt in to use the native rendering engine instead. This renderer supports [integrating native views](xref:Uno.Skia.Embedding.Native). > [!NOTE] > The **WinAppSDK** target is not provided by Uno Platform directly, so it only offers the **native rendering mode**. ## How Skia Rendering Works - The entire UI is drawn on a Skia canvas - There are **no native views**; all visuals are composed in Skia using vector graphics - A minimal native shell (like a window or web canvas) hosts the Skia surface As the Skia Renderer bypasses native UI components, Skia can offer pixel-perfect rendering and visual consistency. The same UI is offered by default, but platform-specific theming is possible using [Uno.Themes](xref:Uno.Themes.Overview). ## Benefits > [!TIP] > If you are building a custom drawing application, charts, or games in Uno Platform, Skia can offer more flexibility and uniform visuals across platforms. - **Consistent visuals**: Skia ensures pixel-perfect rendering across all supported platforms, making it ideal for applications where precise control over appearance is critical. - **Custom drawing**: Ideal for apps requiring advanced graphics, custom controls, or canvas-based rendering—Skia gives you low-level drawing access, such as with the [SKCanvasElement](xref:Uno.Controls.SKCanvasElement). - **Unified rendering pipeline**: Unlike native rendering, which varies by platform, Skia uses a single rendering backend, reducing platform-specific variations. - **Improved rendering performance on desktop**: On platforms like Linux/macOS, Skia is often faster and more efficient than native alternatives. - **Access to the full Composition API**: The Skia renderer provides access to the full [Composition API access for richer custom rendering](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/composition). - **Better control over visual updates**: You can fine-tune repainting behavior for animations, games, or dynamic content using Skia’s immediate mode rendering. - **Smaller dependency surface**: By avoiding native UI components, Skia can simplify deployment—especially in environments like Wasm or containerized desktop apps. ## Using Skia rendering for new apps You can use our [Visual Studio Wizard](xref:Uno.GettingStarted.UsingWizard) to create a new project. By default, the Wizard uses the Skia rendering engine, automatically setting up the necessary MSBuild properties and references for you. If you prefer to use native rendering instead, you can select it in the Wizard’s configuration options. You can find more details on how to use the Wizard here: [Creating a new project](xref:Uno.GettingStarted.UsingWizard). > [!NOTE] > If you're upgrading an existing project to Uno Platform 6.0, be sure to also check our migration guidance in [Migrating from previous releases](xref:Uno.Development.MigratingFromPreviousReleases). ## Using Skia rendering for existing apps To enable Skia rendering in your Uno Platform project, you must opt in using MSBuild properties and features. ### Using Skia Desktop On **macOS**, **Linux**, and **Windows**, using the `netX.0-desktop` target framework, Skia rendering is always used. However, when using **WinAppSDK**, the **native rendering engine** is always used, regardless of whether Skia or Native is enabled in `UnoFeatures`. > [!NOTE] > Starting with Uno Platform 6.0, **Mac Catalyst** is no longer present in templates, and we encourage users to move to `netX.0-desktop`, which runs on macOS using Skia for rendering. You can find more details in [Using the Skia Desktop](xref:Uno.Skia.Desktop). ### Upgrading to use Skia for iOS, Android, and WebAssembly > [!TIP] > If your project was created before Uno Platform 6.0 and you want to enable Skia rendering, [follow the upgrade guide](xref:Uno.Development.MigratingToUno6). ## Limitations Using Skia rendering might have some limitations compared to native rendering. Some of the known limitations include: - **Accessibility support**: Since Skia doesn't rely on native controls, accessibility tools (e.g., screen readers) are a work in progress. We're actively improving accessibility support in future releases. - **Text rendering differences**: Font rendering may not match platform-specific expectations due to differences in text shaping and anti-aliasing. - **IME support**: This portion of input support is also a work in progress, expect improvements in upcoming releases. - **Limited hardware acceleration on some platforms**: Depending on the platform, Skia may fall back to software rendering, affecting the overall performance. - Skia Rendering on WebAssembly is only supported on .NET 9 and later. - Removing `SkiaRenderer` from `UnoFeatures` inside the project's `.csproj` file to target native rendering, then setting it back after a new build will raise a runtime Exception. You will need to remove `bin` and `obj` folders, and clear site data of the browser app in order to avoid encountering this exception. Skia rendering is best suited for cross-platform scenarios where a unified appearance and customized graphics are key. Some native integration scenarios may not yet be supported. If you encounter any of such scenarios, make sure to let it be known by [opening an issue](https://github.com/unoplatform/uno/issues). ## Architecture In order to accommodate the inclusion of Skia rendering for all platforms, the Uno Platform internal structure uses two layers of "bait-and-switch" of reference assemblies. ### Publish-time switching When building in the `SkiaRenderer` node, an application compiles against "reference" versions of `Uno.UI`, `Uno.UI.Dispatching`, `Uno.UI.Composition`, `Uno`, and `Uno.Foundation`. When the application is being packaged, `Uno.UI` and `Uno.UI.Composition` are switched to the Skia-compatible versions. The `Uno.UI.Dispatching`, `Uno`, and `Uno.Foundation` are switched to their corresponding target platform versions. By doing so, any use of the APIs provided by `Uno.UI.Dispatching`, `Uno`, and `Uno.Foundation` is automatically redirected to the proper platform support, for instance, redirecting `GeoLocator` to use the proper APIs provided by the underlying platform. ### Implications for iOS/Android class libraries At this time, NuGet packages that provide UI features on iOS/Android may not be consumed by both native and Skia renderer projects under certain conditions. The reason for this limitation is caused by the fact that Native renderers expose a different API set for `Microsoft.UI.Xaml` types, therefore causing incompatibility issues when apps use such a library. Here are the different scenarios: - Given a library that uses `net9.0-ios` or `net9.0-android`, which does not have the `SkiaRenderer` set as an `UnoFeature`, but uses platform conditional code with `#if` blocks: - This package is only usable by both native and Skia apps if it also provides a `net9.0` TFM. In this case, for a native app, nothing changes. - For a `SkiaRenderer` enabled app, the `net9.0` variant of the library will be used and will not offer iOS/Android specific conditional code, but any code that uses Uno Platform provided APIs will work properly. - Given a library that uses `net9.0-ios` or `net9.0-android`, which does have the `SkiaRenderer` set as an `UnoFeature`, but uses platform conditional code with `#if` blocks: - This package is only usable by Skia-enabled apps. --- # Source: https://raw.githubusercontent.com/unoplatform/uno.wasm.bootstrap/refs/heads/main/doc/using-the-bootstrapper.md --- uid: UnoWasmBootstrap.Overview --- # Using the bootstrapper The Uno.Wasm.Bootstrap package provides a runtime bootstrapper of the `Microsoft.NET.Sdk.WebAssembly` SDK from .NET 9. This package only provides the bootstrapping features to run a .NET assembly and write to the javascript console, through `Console.WriteLine`. To write an app that provides UI functionalities, make sur to check out https://aka.platform.uno/get-started. This work is based on the excellent work from @praeclarum's [OOui Wasm MSBuild task](https://github.com/praeclarum/Ooui). ## Prepare your machine On the command line, type the following to install the WebAssembly workload: ```bash dotnet workload install wasm-tools ``` ## How to use the Bootstrapper with .NET 9 and later - Create a .NET 9 Console Application, and update it with the following basic definition: ```xml Exe net10.0 ``` - Add a main entry point: ```csharp class Program { static void Main(string[] args) { Console.WriteLine("Hello from C#!"); } } ``` - In Visual Studio 2022, press `F5` to start with the debugger - A browser window will appear with your application - The output of the Console.WriteLine will appear in the javascript debugging console ## How to use the Visual Studio 2022 Debugger To enable the debugging, make sure that the following line is present in your `Properties/launchSettings.json` file: ```json "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}" ``` in every profile section of the file, below each `"launchBrowser": true,` line. Press `F5` to start debugging. ## Alternate deployment methods Install the [`dotnet serve`](https://github.com/natemcmaster/dotnet-serve) tool: ```dotnetcli dotnet tool install -g dotnet-serve ``` Once installed, launch the server by using the following command: ```bash cd MyApp.Wasm dotnet publish -c Debug dotnet serve -d bin\Debug\net10.0\publish\wwwroot -p 8000 ``` You application will be available `http://localhost:8000`. ## Upgrading from previous versions of the Uno.Wasm.Bootstrap package Moving from version 8.x to 9.x may require changing the used MSBuild SDK for your project. - If your project contains `Sdk="Uno.Sdk"`, you will need to update the Uno.Sdk to 5.5 or later. - If your project contains `Sdk="Microsoft.NET.Sdk.Web"`, you'll need to change it to `Sdk="Microsoft.NET.Sdk.WebAssembly"`. Once done, make sure to install the WebAssembly tools from .NET: ```bash dotnet workload install wasm-tools ``` By default, the .NET runtime does not load all resource assemblies, but if you want to load all resources regardless of the user's culture, you can add the following to your project file: ```xml true ``` If you're not using the Uno.SDK and that you are using AOT with `WasmShellMonoRuntimeExecutionMode` set to `InterpreterAndAOT`, you'll also need to keep `WasmShellMonoRuntimeExecutionMode` and add the following: ```xml true ``` If not set, you may get the error `error MSB4036: The "MonoAOTCompiler" task was not found"`. ### Threading Microsoft’s runtime team [has made major changes](https://github.com/dotnet/runtime/issues/85592#issuecomment-2031876112) in .NET 9 to how threads interact with the DOM and JavaScript, aiming to improve stability. Since threading was, and continues to be an experimental feature, these changes now prevent managed code from running on the main JavaScript thread — something Uno Platform depends on. As a result, WebAssembly threading is currently not supported in Uno Platform apps. However, as Microsoft’s runtime team is working on it, we hope that the support for threading may return in future .NET 10 preview builds. ### IDBFS In version 8.x and earlier of the bootstrapper, IDBFS support was enabled by default. Moving the .NET 9, the default interpreter runtime does not enable it by default. Read this documentation in order to [restore IDBFS support](xref:UnoWasmBootstrap.Features.idbfs). ### Interop - `Module.mono_bind_static_method` is not available anymore, you'll need to use `Module.getAssemblyExports` instead. - .NET 9 upgrades to emscripten 3.1.56 for which `.bc` native files are not supported properly. Use `.a` or `.o` extensions instead for native dependencies. ### Build Errors #### UNOWA0001 This error happens when the .NET for WebAssembly workload has not been detected: ```text Native WebAssembly assets were detected, but the wasm-tools workload could not be located. Install it by running uno.check (https://aka.platform.uno/uno-check) or 'dotnet workload install wasm-tools'. ``` To fix this issue: - If you're building with net10.0, either use [uno.check](https://aka.platform.uno/uno-check), or use `dotnet workload install wasm-tools` in the folder of your app's `csproj`. - If you're building with net9.0 with the .NET SDK 10.0 installed, run [uno.check](https://aka.platform.uno/uno-check) then run `dotnet workload install wasm-tools-net9` in the folder of your app's `csproj`. You can also validate manually that this workload is installed by running `dotnet workload list` in the folder of your app's `csproj. ### Deprecated APIs - The `Uno.Wasm.Boostrap.DevServer` package is not needed anymore and can be removed - `WasmShellOutputPackagePath` has been removed. Use `$(PublishDir)` - `WasmShellOutputDistPath` has been removed. Use `$(PublishDir)` - `WasmShellBrotliCompressionQuality`, `WasmShellCompressedExtension` and `WasmShellGenerateCompressedFiles` have been removed, the compression is done by the .NET SDK - `WasmShellEnableAotGSharedVT` has been removed. - `WasmShellEnableEmscriptenWindows` has been removed, the .NET SDK manages emscripten - `WasmShellEnableLongPathSupport` has been removed, the .NET SDK manages the build - `WasmShellEnableNetCoreICU`has been removed, the .NET SDK manages localization - `WasmShellForceDisableWSL` and `WasmShellForceUseWSL` have been removed, Windows and Linux are supported natively by the .NET SDK. - `WashShellGeneratePrefetchHeaders` has been removed. - `WasmShellNinjaAdditionalParameters` has been removed, the .NET SDK manages the build - `WasmShellObfuscateAssemblies`, `WasmShellAssembliesExtension` and `AssembliesFileNameObfuscationMode` have been removed, the .NET SDK uses WebCIL to achieve the same result. - `WasmShellPrintAOTSkippedMethods` has been removed - `WasmShellPThreadsPoolSize` has been removed in favor of the official .NET SDK parameters - `MonoRuntimeDebuggerEnabled` has been removed, the .NET SDK manages the debugger - `WashShellUseFileIntegrity` has been removed, the .NET SDK manages the assets integrity ## Bootstrapper versions and .NET runtimes Each major version of the bootstrapper targets a different version of the .NET Runtime. - 2.x: Mono runtime (https://github.com/mono/mono) - 3.x: .NET 6 (https://github.com/dotnet/runtime/commits/release/6.0) - 7.x: .NET 7 (https://github.com/dotnet/runtime/commits/release/7.0) - 8.0: .NET 8 (https://github.com/dotnet/runtime/commits/release/8.0) - 9.0: .NET 9 (https://github.com/dotnet/runtime/commits/release/9.0) - 10.0: .NET 10 (https://github.com/dotnet/runtime/commits/release/10.0) > [!NOTE] > Between version 3.x and 8.x, the bootstrapper is using custom builds of the runtime, maintained here: https://github.com/unoplatform/Uno.DotnetRuntime.WebAssembly > > [!NOTE] > Bootstrapper builds version 4.x-dev were based on developments builds of .NET 7 and were later versioned 7.x-dev to match the appropriate runtime. ## Previous releases documentation - [8.0.x](https://github.com/unoplatform/Uno.Wasm.Bootstrap/tree/release/stable/8.0/doc) - [7.0.x](https://github.com/unoplatform/Uno.Wasm.Bootstrap/tree/release/stable/7.0/doc) - [3.x](https://github.com/unoplatform/Uno.Wasm.Bootstrap/tree/release/stable/3.3/doc) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/guides/using-the-server-project.md --- uid: Uno.Guides.UsingTheServerProject --- # The ASP.NET Core Server Project As part of the uno platform templates, the server option is provided to allow the hosting of both an API server as well as a WebAssembly app. This allows you to create an API and endpoints. It can also be used as the data server and you can also choose to implement the authentication server code in it. You will find [more information](xref:Uno.GettingStarted.UsingWizard#server) on how to use it from the solution wizard or `dotnet new` templates. When creating an app with the server option enabled, you'll get: - An app project, which contains a target framework with `net9.0-browserwasm` - A server project, which references the app project and will by default host it at its root ## Using the server project See below the specifics about the server project per IDE. ### Visual Studio To run the project, set the server project as "startup project", then press F5 to enable the debugging. > [!IMPORTANT] > See the section below on HTTPS to ensure that debugging works properly You can start debugging the app in the same way you would when starting the app project directly. ### VS Code In order to launch the server project in VS Code: - In a terminal, navigate to your `ReplaceMe.Server` folder - Type `dotnet run -f net9.0 --launch-profile ReplaceMe.Server` > [!IMPORTANT] > See the section below on HTTPS to ensure that debugging works properly Launching with the debugger is pending on [this issue](https://github.com/unoplatform/uno.templates/issues/1618). ### Rider - Select the "ReplaceMe.Server" project in the top right debugger selector - Start the app > ![IMPORTANT] > WebAssembly Debugging is [not yet supported](https://github.com/unoplatform/uno/issues/15226) in Rider. > [!IMPORTANT] > See the section below on HTTPS to ensure that debugging works properly ## Adjusting for HTTPS As the app will run with https by default, you will get an error about "Mixed Content" not being supported. To fix this when using Chrome or Edge: - When the browser window opens for the first time, click on the padlock or section at the left of the address bar ![The security popup window with security options](../Assets/uno-guide-server-mixed-content-enable.png) - Click the **Permissions for this site** option - In the window that opened, search for **Insecure content** then select **Allow**. This will enable Hot Reload and Hot Design for this specific url/port. ![Allow mixed content option](../Assets/uno-guide-server-mixed-content-allowed.png) - Close the browser window, ensure that the debugger has stopped in your IDE You may also need to [trust the developer certificates](https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-9.0&tabs=visual-studio%2Clinux-sles#trust-the-aspnet-core-https-development-certificate): ```text dotnet dev-certs https --trust ``` ## Enabling HTTPS for the app project If you want to enable for the app project, independently from the server project, you can modify your `Properties/launchSettings.json` file this way to use https first: ```json "applicationUrl": "https://localhost:5001;http://localhost:5000", ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-the-uno-mcps.md --- uid: Uno.Features.Uno.MCPs --- # The Uno Platform MCPs Uno Platform provides two [MCPs](https://modelcontextprotocol.io/docs/getting-started/intro): - The Uno Platform Remote MCP, providing prompts and up-to-date documentation - The Uno Platform Local App MCP, providing interactive access to your running application This document explains how to interact with both those MCPs. You can find further below descriptions of the provided tools and prompts. ## MCP (Remote) This is a remotely hosted publicly and provides: - A set of tools to search and fetch Uno Platform documentation - A set of prompts to create and develop Uno Platform applications. ### Predefined Prompts The prompts provided by the MCP are automatically registered in your environment when supported by your AI agent (e.g., Claude, Codex, Copilot, etc.). Here are the currently supported prompts: - `/new`, used to create a new Uno Platform app with the best practices in mind. - `/init`, used to "prime" your current chat with Uno's best practices. It's generally used in an existing app when adding new features. ### Sample Prompts for Uno MCP Servers You can find common prompts to use with agents in our [getting started](xref:Uno.BuildYourApp.AI.Agents) section. ### Uno MCP Tools The Uno MCP tools are the following: - `uno_platform_docs_search` used by Agents to search for specific topics. It returns snippets of relevant information. - `uno_platform_docs_fetch` used by Agents to get a specific document, grabbed through `uno_platform_docs_search`. - `uno_platform_agent_rules_init` used by Agents to "prime" the environment on how to interact with Uno Platform apps during development. - `uno_platform_usage_rules_init` used by Agents to "prime" the environment on how to Uno Platform's APIs in the best way possible Those tools are suggested to the agent on how to be used best. In general, asking the agent "Make sure to search the Uno Platform docs to answer" will hint it to use those tools. > [!NOTE] > You can unselect `uno_platform_agent_rules_init` and `uno_platform_usage_rules_init` in your agent to avoid implicit priming, and you can use the `/init` prompt to achieve a similar result. ## App MCP (Local) This MCP is running locally and provides agents with the ability to interact with a running app, in order to click, type, analyze or screenshot its content. These tools give "eyes" and "hands" to Agents in order to validate their assumptions regarding the actions they take, and the code they generate. > [!NOTE] > If using Visual Studio 2022/2026, sometimes the Uno App MCP does not appear in the Visual Studio tools list. See [how to make the App MCP appear in Visual Studio](xref:Uno.UI.CommonIssues.AIAgents#the-app-mcp-does-not-appear-in-visual-studio). ### App MCP Tools The Community license MCP app tools are: - `uno_app_get_runtime_info`, used to get general information about the running app, such as its PID, OS, Platform, etc... - `uno_app_get_screenshot`, used to get a screenshot of the running app - `uno_app_pointer_click`, used to click at an X,Y coordinates in the app - `uno_app_key_press`, used to type individual keys (possibly with modifiers) - `uno_app_type_text`, used to type long strings of text in controls - `uno_app_visualtree_snapshot`, used to get a textual representation of the visual tree of the app - `uno_app_element_peer_default_action`, used to execute the default automation peer action on a UI element - `uno_app_close`, used to close the running app The Pro license App MCP app tools are: - `uno_app_element_peer_action`, used to invoke a specific element automation peer action - `uno_app_get_element_datacontext`, used to get a textual representation of the DataContext on a FrameworkElement ## Troubleshooting MCP Servers You can find additional information about [troubleshooting AI Agents](xref:Uno.UI.CommonIssues.AIAgents) in our docs. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-the-uno-sdk.md --- uid: Uno.Features.Uno.Sdk --- # Using the Uno.Sdk Uno Platform projects use the Uno.Sdk package that is designed to keep projects simple, yet configurable. It imports the `Microsoft.Net.Sdk` (and the `Microsoft.Net.Sdk.Web` for WebAssembly). This document explains the many features of this SDK and how to configure its behavior. > [!TIP] > Uno.Sdk enabled projects are best experienced using the [MSBuild Editor Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=mhutch.msbuildeditor) to provide intellisense. ## Managing the Uno.Sdk version Updating the Uno.Sdk is [done through the global.json file](xref:Uno.Development.UpgradeUnoNuget). ## Uno Platform Features As Uno Platform can be used in many different ways, in order to reduce the build time and avoid downloading many packages, the Uno.Sdk offers a way to simplify which Uno Platform features should be enabled. You can use the `UnoFeatures` property in the `csproj` or `Directory.Build.props` as shown here: ```xml Material; Hosting; Toolkit; Logging; Serilog; MVUX; Configuration; Http; HttpRefit; HttpKiota; Serialization; Localization; Navigation; SkiaRenderer; ``` > [!IMPORTANT] > Once you have changed the features list, Visual Studio requires restoring packages explicitly, or building the app once for the change to take effect. This allows for the SDK to selectively include references to relevant sets of Nuget packages to enable features for your app. Here are the supported features: | Feature | Description | |----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `Authentication` | Adds the [Uno.Extensions](xref:Uno.Extensions.Overview) packages for Custom [Authentication](xref:Uno.Extensions.Authentication.Overview). | | `AuthenticationMsal` | Adds the [Uno.Extensions](xref:Uno.Extensions.Overview) packages for [Authentication](xref:Uno.Extensions.Authentication.Overview) using [Microsoft.Identity.Client](xref:Uno.Extensions.Authentication.HowToMsalAuthentication). | | `AuthenticationOidc` | Adds the [Uno.Extensions](xref:Uno.Extensions.Overview) packages for [Authentication](xref:Uno.Extensions.Authentication.Overview) using a custom [Oidc](xref:Uno.Extensions.Authentication.HowToOidcAuthentication) client. | | `Configuration` | Adds the [Uno.Extensions](xref:Uno.Extensions.Overview) packages for [Configuration](xref:Uno.Extensions.Configuration.Overview). | | `CSharpMarkup` | Adds support for [C# Markup](xref:Uno.Extensions.Markup.Overview). | | `Cupertino` | Adds support for the [Cupertino Design Theme](xref:Uno.Themes.Cupertino.GetStarted) library. If the `Toolkit` feature is also used, it will add support for the [Cupertino Design Toolkit](xref:Toolkit.GettingStarted.Cupertino) library. | | `Dsp` | Adds support for the [Uno.Dsp.Tasks packages](https://www.nuget.org/packages?q=uno.dsp.tasks). | | `Extensions` | Adds the most commonly used Extensions Packages for Hosting, Configuration, and Logging. | | `Foldable` | Adds a reference to [Uno.WinUI.Foldable](https://www.nuget.org/packages/Uno.WinUI.Foldable). | | `GLCanvas` | Adds support for the [OpenGL Canvas](xref:Uno.Controls.GLCanvasElement). | | `GooglePlay` | Adds support for [In App Reviews](xref:Uno.Features.StoreContext). For more information, see the [Store Context documentation](xref:Uno.Features.StoreContext). | | `Hosting` | Adds support for [Dependency Injection](xref:Uno.Extensions.DependencyInjection.Overview) using [Uno.Extensions.Hosting packages](https://www.nuget.org/packages?q=Uno.Extensions.Hosting). | | `Http` | Adds support for custom [Http Clients](xref:Uno.Extensions.Http.Overview) with [Uno.Extensions](xref:Uno.Extensions.Overview). | | `HttpRefit` | Adds support for strongly-typed REST API clients via [Refit](xref:Uno.Extensions.Http.Overview#refit) | | `HttpKiota` | Adds support for OpenAPI-generated clients via [Kiota](xref:Uno.Extensions.Http.Overview#kiota) | | `Localization` | Adds support for [Localization](xref:Uno.Extensions.Localization.Overview) using [Uno.Extensions](xref:Uno.Extensions.Overview). | | `Logging` | Adds support for [Logging](xref:Uno.Extensions.Logging.Overview) using [Uno.Extensions](xref:Uno.Extensions.Overview). | | `LoggingSerilog` | Adds support for [Serilog](https://github.com/serilog/serilog) using [Uno.Extensions](xref:Uno.Extensions.Overview). | | `Lottie` | Adds support for [Lottie animations](xref:Uno.Features.Lottie). | | `Material` | Adds support for the [Material Design Theme](xref:Uno.Themes.Material.GetStarted) library. If the `Toolkit` feature is also used, it will add support for the [Material Design Toolkit](xref:Toolkit.GettingStarted.Material) library. | | `MauiEmbedding` | Adds support for [embedding Maui controls in Uno Platform applications](xref:Uno.Extensions.Maui.Overview). | | `MediaPlayerElement` | Adds native references where needed to use [MediaPlayerElement](https://learn.microsoft.com/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.mediaplayerelement). | | `Mvvm` | Adds support for the [CommunityToolkit.Mvvm](https://www.nuget.org/packages/CommunityToolkit.Mvvm) package. | | `MVUX` | Adds support for [MVUX](xref:Uno.Extensions.Mvux.Overview). | | `Navigation` | Adds support for [Navigation](xref:Uno.Extensions.Navigation.Overview) using [Uno.Extensions](xref:Uno.Extensions.Overview). | | `Prism` | Adds [Prism](https://github.com/PrismLibrary/Prism) support for Uno Platform applications WinUI. | | `Serialization` | Adds support for [Serialization](xref:Uno.Extensions.Serialization.Overview) using [Uno.Extensions](xref:Uno.Extensions.Overview). | | `Skia` | Adds support for [SkiaSharp](https://github.com/mono/SkiaSharp). | | `SkiaRenderer` | Adds support for using Skia as the graphics rendering engine. For more details, see [Skia Rendering documentation](xref:uno.features.renderer.skia). | | `Storage` | Adds support for [Storage](xref:Uno.Extensions.Storage.Overview) using [Uno.Extensions](xref:Uno.Extensions.Overview). | | `Svg` | [SVG](xref:Uno.Features.SVG) support for iOS, and Android. This option is not needed when only targeting WebAssembly and WinAppSDK. | | `ThemeService` | Adds the [Uno.Extensions.Core.WinUI package](https://www.nuget.org/packages/Uno.Extensions.Core.WinUI). | | `Toolkit` | Adds support for the [Uno.Toolkit](xref:Toolkit.GettingStarted). | | `WebView` | Adds support for the [WebView2 control](xref:Uno.Controls.WebView2). ## Implicit Packages Uno Platform is composed of many required and optional NuGet packages. By default, the SDK automatically references the Uno.UI required packages based on the current target framework, using versions appropriate for the version of Uno Platform being used. It is possible to configure the version of those packages in two ways. The first is by using an explicit `PackageReference` to any of the Uno Platform packages, or by using the `*Version` properties supported by the SDK. These versions are used by the `UnoFeatures` defined for your app. Here are the supported properties: ## [**Uno Platform Packages**](#tab/uno-packages) | Property | NuGet Package(s) | Description | |----------------------------------|------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------| | `UnoCoreLoggingSingletonVersion` | [Uno.Core.Extensions.Logging.Singleton](https://www.nuget.org/packages/Uno.Core.Extensions.Logging.Singleton) | Provides a logging singleton pattern with helpers and extension methods for simplified logging. | | `UnoCSharpMarkupVersion` | [Uno.WinUI.Markup](https://www.nuget.org/packages/Uno.WinUI.Markup) and similar packages | Enables [C# Markup](xref:Uno.Extensions.Markup.Overview), the use of C# for building UI markup, similar to XAML but with C# syntax. | | `UnoDspTasksVersion` | [Uno.Dsp.Tasks](https://www.nuget.org/packages/Uno.Dsp.Tasks) and similar packages | Includes tasks for Uno DSP (Theme colors import) within Uno Platform projects. | | `UnoExtensionsVersion` | [Uno.Extensions.Storage.WinUI](https://www.nuget.org/packages/Uno.Extensions.Storage.WinUI) and similar packages | Extends the Uno Platform with additional methods and classes for more versatile application development. | | `UnoLoggingVersion` | [Uno.Extensions.Logging.OSLog](https://www.nuget.org/packages/Uno.Extensions.Logging.OSLog) and similar packages | Implements logging mechanisms to help with monitoring and debugging Uno Platform applications. | | `UnoResizetizerVersion` | [Uno.Resizetizer](https://www.nuget.org/packages/Uno.Resizetizer) | Provides tools for automatically resizing and managing image assets in Uno Platform projects. | | `UnoThemesVersion` | [Uno.Material.WinUI](https://www.nuget.org/packages/Uno.Material.WinUI) and similar packages | Supplies a variety of themes that can be applied to Uno Platform applications to enhance the UI. | | `UnoToolkitVersion` | [Uno.Toolkit.WinUI](https://www.nuget.org/packages/Uno.Toolkit.WinUI) and similar packages | Offers a collection of controls, helpers, and tools to complement the standard WinUI components. | | `UnoUniversalImageLoaderVersion` | [Uno.UniversalImageLoader](https://www.nuget.org/packages/Uno.UniversalImageLoader) | Facilitates the loading and displaying of images across different platforms supported by Uno. | | `UnoWasmBootstrapVersion` | [Uno.Wasm.Bootstrap](https://www.nuget.org/packages/Uno.Wasm.Bootstrap) and similar packages | Enables the bootstrapping of Uno Platform applications running on WebAssembly. | > [!NOTE] > In the 5.2 version of the Uno.Sdk you must provide a value for `UnoExtensionsVersion`, `UnoThemesVersion`, `UnoToolkitVersion`, and `UnoCSharpMarkupVersion` in order to use the packages associated with the UnoFeatures from these libraries as they are downstream dependencies of the Uno repository. ## [**Third Party Packages**](#tab/3rd-party-packages) | Property | NuGet Package(s) | Description | |-------------------------------------|----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| | `AndroidMaterialVersion` | [Xamarin.Google.Android.Material](https://www.nuget.org/packages/Xamarin.Google.Android.Material) | Implements Material Design components for Android using Xamarin bindings. | | `AndroidXActivityVersion` | [Xamarin.AndroidX.Activity](https://www.nuget.org/packages/Xamarin.AndroidX.Activity) | Provides classes to build Android activities with AndroidX libraries. | | `AndroidXAppCompatVersion` | [Xamarin.AndroidX.AppCompat](https://www.nuget.org/packages/Xamarin.AndroidX.AppCompat) | Offers backward-compatible versions of Android components with AndroidX. | | `AndroidXBrowserVersion` | [Xamarin.AndroidX.Browser](https://www.nuget.org/packages/Xamarin.AndroidX.Browser) | Contains components to implement browser features with AndroidX. | | `AndroidXCollectionVersion` | [Xamarin.AndroidX.Collection](https://www.nuget.org/packages/Xamarin.AndroidX.Collection) and similar packages | Provides AndroidX extensions for collections like sparse arrays and bundles. | | `AndroidXLegacySupportV4Version` | [Xamarin.AndroidX.Legacy.Support.V4](https://www.nuget.org/packages/Xamarin.AndroidX.Legacy.Support.V4) | Supports older Android versions with AndroidX compatibility libraries. | | `AndroidXSplashScreenVersion` | [Xamarin.AndroidX.Core.SplashScreen](https://www.nuget.org/packages/Xamarin.AndroidX.Core.SplashScreen) | Support for Android splash screen customization. | | `AndroidXNavigationVersion` | [Xamarin.AndroidX.Navigation.UI](https://www.nuget.org/packages/Xamarin.AndroidX.Navigation.UI) and similar packages | Facilitates navigation within an Android app using AndroidX. | | `AndroidXRecyclerViewVersion` | [Xamarin.AndroidX.RecyclerView](https://www.nuget.org/packages/Xamarin.AndroidX.RecyclerView) | Implements a flexible view for providing a limited window into large datasets with AndroidX. | | `AndroidXSwipeRefreshLayoutVersion` | [Xamarin.AndroidX.SwipeRefreshLayout](https://www.nuget.org/packages/Xamarin.AndroidX.SwipeRefreshLayout) | Provides a swipe-to-refresh UI pattern with AndroidX. | | `CommunityToolkitMvvmVersion` | [CommunityToolkit.Mvvm](https://www.nuget.org/packages/CommunityToolkit.Mvvm) | Delivers a set of MVVM (Model-View-ViewModel) components for .NET applications. | | `MicrosoftIdentityClientVersion` | [Microsoft.Identity.Client](https://www.nuget.org/packages/Microsoft.Identity.Client) | Provides an authentication library for Microsoft Identity Platform. | | `MicrosoftLoggingVersion` | [Microsoft.Extensions.Logging.Console](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) | Enables logging to the console with Microsoft's extensions. | | `PrismVersion` | [Prism.Uno.WinUI](https://www.nuget.org/packages/Prism.Uno.WinUI) and similar packages | Integrates the Prism library, which aids in building loosely coupled, maintainable, and testable applications. | | `SkiaSharpVersion` | [SkiaSharp.Skottie](https://www.nuget.org/packages/SkiaSharp.Skottie) and similar packages | Provides a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. | | `SvgSkiaVersion` | [Svg.Skia](https://www.nuget.org/packages/Svg.Skia) | Renders SVG files using the SkiaSharp graphics engine. | | `WinAppSdkBuildToolsVersion` | [Microsoft.Windows.SDK.BuildTools](https://www.nuget.org/packages/Microsoft.Windows.SDK.BuildTools) | Contains the tools required to build applications for the Microsoft Windows App SDK. | | `WinAppSdkVersion` | [Microsoft.WindowsAppSDK](https://www.nuget.org/packages/Microsoft.WindowsAppSDK) | Provides project templates and tools for building Windows applications. | | `WindowsCompatibilityVersion` | [Microsoft.Windows.Compatibility](https://www.nuget.org/packages/Microsoft.Windows.Compatibility) | Enables Windows desktop apps to use .NET Core by providing access to additional Windows APIs. | --- Those properties can be set from `Directory.Build.props` or may be set in the `csproj` file for your project. ```xml ... Material; Dsp; Hosting; Toolkit; Logging; MVUX; Configuration; Http; Serialization; Localization; Navigation; ThemeService; Mvvm; SkiaRenderer; 6.3.6 9.0.1 8.4.0 ``` In the sample above, we are overriding the default versions of the `UnoToolkit`, `MicrosoftLogging`, and `CommunityToolkitMvvm` packages. ## Disabling Implicit Uno Packages If you wish to disable Implicit package usage, add the following: ```xml true ``` to your `Directory.Build.props` file or `csproj` file. You will be then able to manually add the NuGet packages for your project. > [!NOTE] > When disabling Implicit Uno Packages it is recommended that you use the `$(UnoVersion)` to set the version of the core Uno packages that are versioned with the SDK as the SDK requires `Uno.WinUI` to be the same version as the SDK to ensure proper compatibility. ## Supported OS Platform versions By default, the Uno.Sdk specifies a set of OS Platform versions, as follows: | Target | `SupportedOSPlatformVersion` | |--------|----------------------------| | Android | 21 | | iOS | 14.2 | | macOS | 10.14 | | tvOS | 14.2 | | WinUI | 10.0.18362.0 | You can set this property in a `Choose` MSBuild block in order to alter its value based on the active `TargetFramework`. ```xml 21.0 14.2 10.14 14.2 10.0.18362.0 10.0.18362.0 ``` ## Visual Studio First-TargetFramework Workarounds Using a Single Project in Visual Studio requires the Uno Platform tooling to apply workarounds in order to have an acceptable debugging experience. For some of the platforms (Desktop, WinAppSDK, and WebAssembly), the corresponding target frameworks must be placed first in order for debugging and publishing to function properly. To address that problem, the Uno Platform tooling modifies the `csproj` file to reorder the `TargetFrameworks` property so that the list is accepted by Visual Studio. As a result, the csproj file is on disk and will show the file as modified in your source control, yet the automatic change can be reverted safely. If the behavior is impacting your IDE negatively, you can disable it by adding the following in your `.csproj` file: ```xml true ``` Note that we are currently tracking these Visual Studio issues, make sure to upvote them: - `net8.0-browserwasm` must be first for WebAssembly debugging to work ([Link](https://developercommunity.visualstudio.com/t/net80-must-be-first-for-WebAssembly-pub/10643720)) - [WinAppSDK Unpackaged profile cannot be selected properly when a net8.0 mobile target is active](https://developercommunity.visualstudio.com/t/WinAppSDK-Unpackaged-profile-cannot-be-s/10643735) ## Disabling Default Items The `Uno.Sdk` will automatically includes files that you previously needed to manage within your projects. These default items include definitions for including files within the `Content`, `Page`, and `PRIResource` item groups. Additionally, if you have referenced the `Uno.Resizetizer` it will add default items for the `UnoImage` allowing you to more easily manage your image assets. You may disable this behavior in one of two ways: ```xml false false ``` ## WinAppSdk PRIResource Workaround Many Uno projects and libraries make use of a `winappsdk-workaround.targets` file that corrects a [bug](https://github.com/microsoft/microsoft-ui-xaml/issues/8857) found in WinUI. When using the `Uno.Sdk` these targets now are provided for you out of the box. This extra set of workaround targets can be disabled by setting the following property: ```xml true ``` ## Cross Targeting Support By Default when using the Uno.Sdk you get the added benefit of default includes for an easier time building Cross Targeted Applications. The supported file extensions are as shown below: - `*.wasm.cs` (WebAssembly) - `*.desktop.cs` (Desktop) - `*.iOS.cs` (iOS) - `*.tvOS.cs`(tvOS) - `*.UIKit.cs`, `*.Apple.cs` (iOS & tvOS) - `*.Android.cs` (Android) - `*.WinAppSDK.cs` (Windows App SDK) For class libraries we also provide: - `*.reference.cs` (Reference only) - `*.crossruntime.cs` (WebAssembly, Desktop, or Reference) > [!NOTE] > For backwards compatibility, using `.skia.cs` is currently equivalent to `.desktop.cs`. This might change in the future, so we recommend using the suffixes above instead. As discussed above setting `EnableDefaultUnoItems` to false will disable these includes. > [!TIP] > When you need to exclude specific files from a particular target framework (such as WebAssembly), you can use a custom MSBuild target: > > ```xml > > > > > > > ``` > > This approach allows you to selectively remove pages from specific target frameworks while maintaining them in others. ## Apple Privacy Manifest Support Starting May 1st, 2024, Apple requires the inclusion of a new file, the [Privacy Manifest file](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files) (named `PrivacyInfo.xcprivacy`), in app bundles. This file is crucial for complying with updated privacy regulations. For projects using the Uno.Sdk (version 5.2 or later), the `Platforms/iOS/PrivacyInfo.xcprivacy` file is automatically integrated within the app bundle. An example of this manifest file can be found in the [Uno.Templates](https://aka.platform.uno/apple-privacy-manifest-sample) repository. For more information on how to include privacy entries in this file, see the [Microsoft .NET documentation](https://learn.microsoft.com/dotnet/maui/ios/privacy-manifest) on the subject, as well as [Apple's documentation](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files). > [!NOTE] > If your application is using the Uno Platform 5.1 or earlier, or is not using the Uno.Sdk, you can include the file using the following: > > ```xml > > > > ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno.check/refs/heads/main/doc/using-uno-check.md --- uid: UnoCheck.UsingUnoCheck --- # Setup your environment with uno-check [`uno-check`](https://github.com/unoplatform/uno.check) is a dotnet command-line tool that runs a suite of automated check-ups on your dev environment, making sure you have all the prerequisites installed to successfully develop an Uno Platform application. The tool is available on Windows, Linux, and macOS. If it finds something missing, out of date, or misconfigured, it will either offer to automatically fix it, or else direct you to instructions to manually fix the problem. ![uno-check running](https://github.com/unoplatform/uno/raw/master/doc/articles/Assets/uno-check-running.gif) ## Install and run uno-check # [**Windows**](#tab/windows) 1. Make sure you have the [.NET SDK installed](https://dotnet.microsoft.com/download). 1. Open a command-line prompt, Windows Terminal if you have it installed, or else Command Prompt or Windows Powershell from the Start menu. 1. Setup uno.check by: - Installing the tool: ```dotnetcli dotnet tool install -g uno.check ``` - Updating the tool, if you previously installed it: ```dotnetcli dotnet tool update -g uno.check ``` 1. Run the tool from the command prompt with the following command: ```bash uno-check ``` 1. Follow the instructions indicated by the tool. 1. If you get any errors or warnings, run the provided fix or follow the provided instructions. Run `uno-check` again to verify that the fixes worked. 1. Once `uno-check` gives you the green light, you can [get started](https://platform.uno/docs/articles/get-started.html)! # [**Linux**](#tab/linux) 1. Open a Terminal 1. If `dotnet --version` returns `command not found`: - Follow the [official directions](https://learn.microsoft.com/dotnet/core/install/linux?WT.mc_id=dotnet-35129-website#packages) for installing .NET. > [!IMPORTANT] > If your distribution is Ubuntu and you want to develop for Android, make sure to use the directions to install the Microsoft feed and not the Ubuntu official feed. The latter does not contain Android workloads. 1. Then, setup uno.check by: - Installing the tool: ```dotnetcli dotnet tool install -g uno.check ``` - Updating the tool, if you previously installed it: ```dotnetcli dotnet tool update -g uno.check ``` 1. Run the tool from the command prompt with the following command: ```bash uno-check ``` If the above command fails, use the following: ```bash ~/.dotnet/tools/uno-check ``` 1. Follow the instructions indicated by the tool 1. If you get any errors or warnings, run the provided fix or follow the provided instructions. Run `uno-check` again to verify that the fixes worked. 1. Once `uno-check` gives you the green light, you can [get started](https://platform.uno/docs/articles/get-started.html)! # [**macOS**](#tab/macos) 1. Make sure you have the [.NET SDK installed](https://dotnet.microsoft.com/download). 1. Open a Terminal. 1. Setup uno.check by: - Installing the tool: ```dotnetcli dotnet tool install -g uno.check ``` - Updating the tool, if you previously installed it: ```dotnetcli dotnet tool update -g uno.check ``` 1. Run the tool from the command prompt with the following command: ```bash uno-check ``` If the above command fails, use the following: ```bash ~/.dotnet/tools/uno-check ``` 1. Follow the instructions indicated by the tool 1. If you get any errors or warnings, run the provided fix or follow the provided instructions. Run `uno-check` again to verify that the fixes worked. 1. Once `uno-check` gives you the green light, you can [get started](https://platform.uno/docs/articles/get-started.html)! *** ## Common uno-check command lines ### Run uno-check in verbose mode ```bash uno-check -v ``` This command shows additional logs for each running check. ### Run uno-check for a specific platforms ```bash uno-check --target desktop --target web # or ios, android, windows ``` This command avoids installing tooling that is not needed. See [Command line arguments](xref:UnoCheck.Configuration#command-line-arguments) for more details ### Run uno-check in readonly mode on Windows ```bash cmd /c "set __COMPAT_LAYER=RUNASINVOKER && uno-check --ci --non-interactive" ``` This command only checks for missing tooling and report the results. ### Run uno-check in readonly mode on macOS or Linux ```bash uno-check -v --ci --non-interactive ``` This command only checks for missing tooling and report the results. ### Run uno-check to list available checks ```bash uno-check list ``` This command lists checks that can be skipped using `--skip` ### Run uno-check with specific checks skipped ```bash uno-check --skip androidsdk ``` This command skips specified checks and runs the rest. --- # Source: https://raw.githubusercontent.com/unoplatform/uno.resizetizer/refs/heads/main/doc/using-uno-resizetizer.md --- uid: Uno.Resizetizer.GettingStarted --- # How-To: Get Started with Uno.Resizetizer Uno.Resizetizer is a set of MSBuild tasks designed to manage an application's assets. With this package, there's no need to worry about creating and maintaining various image sizes or setting up a splash screen. Simply, provide an SVG file, and the tool will handle everything else. > [!TIP] > To create an app, make sure to visit [our getting started tutorials](xref:Uno.GetStarted). ## How it works Resizetizer uses an `svg` or `png` file as input. If an `svg` file is used, it will be re-scaled for different resolutions. The `UnoImage`, on iOS, for example, will use the x2 and x3 corresponding sizes and add them to your project for you. If a `png` file is used, it will not be resized, but it will be added to your project and used as one size image. If you want to know all the scales that are used, you can check this [Table of scales](https://platform.uno/docs/articles/features/working-with-assets.html#table-of-scales). For `UnoIcon` and `UnoSplashScreen`, the generated sizes will be the same as the ones used by the platform. As `svg` has the ability to scale without losing quality, we strongly encourage the usage of `svg` files, to take most of the benefits of the tool. In the rest of the docs, you can assume that we are using `svg` files. > [!TIP] > You can use the `Resize` property on `UnoImage` to force the resize of a `png` file. But be aware that the quality can be affected. ## Manual Installation Uno.Resizeter is delivered [through NuGet](https://www.nuget.org/packages/Uno.Resizetizer). In order to install it, you can either install it in your project using your IDE (this will be shown in the next steps) or added directly on your `.csproj` as shown in the [NuGet page](https://www.nuget.org/packages/Uno.Resizetizer/). > [!NOTE] > If you're using the new template, you can skip this step because it is already included by default with Uno Platform 4.8 and later. ### 1. Installing Uno.Resizetizer * Open your favorite IDE, in this case, it will be Visual Studio, after that open the Manage NuGet packages window. * Search for `Uno.Resizetizer` and install it over your projects. > [!NOTE] > Uno.Resizetizer is compatible with projects running .NET 6 and later. ## Usage Uno.Resizetizer can handle: * Images used in the application * The App icon * The splash screen The next sections will show how to use it for each use case. > [!WARNING] > All the assets used by Uno.Resizetizer should be lower case and don't have special characters. You can use `_` to separate words. > This is because the assets are used on different platforms and some of them have limitations on the characters that can be used. ### UnoImage `UnoImage` is the build action used for images that will be part of the app. ### 2. Configure the project to use generated Images * In the App Class library, create a folder called `Assets` (if doesn't exist) and then create a folder called `Images`. We now need to add assets to this folder. > [!TIP] > Those folder names are examples. It is possible to create folders with any name and how many levels are needed. Make sure that the build assets are configured to be `UnoImage`. In the `csproj`, to make all files inside the `Assets\Images` folder to be automatically configured to be `UnoImage`, add the following: ```xml ``` You can also make specific files to be `UnoImage` using Visual Studio, by right-clicking on the file, selecting `Properties`, then `Build Action`, and selecting `UnoImage`. The image below shows what it looks like: ![UnoImage Build Action](Assets/UnoImage_BuildAction.png) ### 3. Using the assets on the project * `UnoImage` assets can now be used just like any regular image. For example: ```xml ``` > [!TIP] > Make sure to add the `.png` at the end of the file name ## UnoIcon `UnoIcon` is the build action for the app icon. There should only be one per application. The `UnoIcon` accepts two assets, one that represents the `Foreground` and another that represents the `Background`. During the generation phase, those files will be merged into one `.png` image. During the creation of your `svg` file, please remember to make the `ViewBox` bigger than the `Foreground` and `Background` images, not adding an extra space could cause the app icon to not look good on some platforms. We recommend to add a 30% extra space on each side. This will be enough for Resizetizer to work with padding and margins. ### 4. Configuring the project to use generated app icon # [**Single Project Based Solution**](#tab/singleproject) * When you create a new Uno Platform application, an `Icons` folder is automatically generated under the `Assets` directory. This folder contains `icon.svg` and `icon_foreground.svg` files. * You can simply replace these files with your custom icons while retaining the file names, or you can customize the icon configuration using SDK properties if different names or additional configurations are needed. * This configuration automatically applies across all target platforms included in the single project structure. ## Utilizing SDK Properties The Uno Platform SDK exposes several properties that simplify the customization of your app icon. These properties allow you to easily adjust key aspects like the base size, color, and icon files without detailed XML changes, making your development process more streamlined. * `UnoIconBackgroundFile`: Sets the background image file for the icon. * `UnoIconForegroundFile`: Sets the foreground image file for the icon. * `UnoIconForegroundScale`: Adjusts the scaling of the icon's foreground. * `UnoIconBackgroundColor`: Sets the background color of the icon. For basic adjustments, such as changing the icon's foreground color or applying a common modification across platforms, you can use SDK properties: ```xml Assets\Icons\customicon.svg #FF0000 ``` This setup ensures that the icon settings are centralized, simplifying the maintenance and updating process. # [**Class Library Based Solution**](#tab/classlib) * Create an `Icons` folder inside the Base project, and add the files related to the app icon there. * Now open the `base.props` file, inside the `MyApp.Base` folder project and add the following block: ```xml ``` We recommend adding the `UnoIcon` on `base.props` because this file is imported by all head projects, that way, you don't need to add the same configuration in each head project. If you want, you can see our sample project in [Uno.Resizetizer GitHub repository](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Base/base.props#L13-L16) where this step is configured. > [!TIP] > If the icon doesn't look good, you can use the `ForegroundScale` property which will re-scale the `Foreground` image for all platforms. If you want to re-scale for a specific platform, you can use the specific property for that platform. For more information, see [Resizetizer Properties](xref:Overview.Uno.Resizetizer.Properties). # [**Shared Project Based Solution**](#tab/sharedproject) * Create an `Icons` folder inside the Shared project, and add the files related to the app icon there. * In each of your project heads (iOS, Android, WebAssembly, ...), add the following block to the `csproj` file: ```xml ``` You can also make specific files to be `UnoIcon` using Visual Studio, by right-clicking on the file, selecting `Properties`, then `Build Action`, and selecting `UnoIcon`. The image below shows what it looks like: ![UnoIcon Build Action](Assets/UnoIcon_BuildAction.png) ----- Next, some adjustments are needed on `Android`, `Windows (WinUI)`, `WebAssembly`, `mac-catalyst`, and `iOS`. # [**Android**](#tab/Android) * Open the [`Main.Android.cs` file](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Mobile/Android/Main.Android.cs) (or the file that has the `Android.App.ApplicationAttribute`), and change the `Icon` property, in that attribute, to be the name of the file used in the `Include` property of `UnoIcon`, in our case will be: ```csharp [global::Android.App.ApplicationAttribute( Label = "@string/ApplicationName", Icon = "@mipmap/iconapp", //... )] ``` > [!TIP] > You can remove the old assets related to the app icon from the `Android` project. # [**Windows (WinUI)**](#tab/Windows) > [!NOTE] > Uno.Resizetizer is currently only supported on WinUI, UWP is not supported." * Open the [`Package.appxmanifest` file](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Windows/Package.appxmanifest) and look for the `Application` tag * Remove everything that's related to the application icon (BackgroundColor, Square and Wide property inside the `uap:DefaultTile` attribute). It should look like this: ```xml ``` * In a multi-window environment, you need to call 'SetWindowIcon' for each new window created to show the app icon on the app bar: ```c# using System; using Uno.Resizetizer; newwindow = new Window(); newwindow.SetWindowIcon(); newwindow.Activate(); ``` # [**Web Assembly (Wasm)**](#tab/Wasm) > [!NOTE] > You will only need to configure this platform if you want to deploy it as a PWA. * Open the [`manifest.webmanifest` file](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Wasm/manifest.webmanifest) and look for the `icons` tag and remove all the values inside it. You should be seeing an empty array like this: ```json { "background_color": "#ffffff", "description": "UnoResApp1", "display": "standalone", "icons": [ ], } ``` > [!NOTE] > In some projects, the file is named `manifest.json` instead of `manifest.webmanifest`. If so, you can either adjust your project to use `manifest.webmanifest` or keep it as `manifest.json`. > > [!NOTE] > Uno.Resizetizer will support comments on your json file, but they will be ignored on the final generated file. # [**iOS**](#tab/iOS) * For `mac-catalyst` and `iOS`, open the [`info.plist` file](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Mobile/iOS/Info.plist), find the `XSAppIconAsset` key, and change its value to `Assets.xcassets/iconapp.appiconset`. > [!NOTE] > If your app icon has a another name than `iconapp`, use it instead. > > [!TIP] > You can delete the old assets related to the app icon from the project. ----- ## UnoSplashScreen `UnoSplashScreen` is the build action for the splash screen. There should only be one per application. The `UnoSplashScreen` has two more properties that you can use to adjust your asset, which are: * `BaseSize`: It's the size that will be used to perform the scaling of the image. The default value is the size of the asset. So, if you feel that your SplashScreen doesn't look right, you can tweak this value. * `Color`: It's the background color that will be used to fill the empty space on the final SplashScreen asset. The default value is `#FFFFFF` (white). ### 5. Configuring the project to use generated splash screen # [**Single Project Based Solution**](#tab/singleproject) * When you create a new Uno Platform application, a `Splash` folder is automatically generated under the `Assets` directory. This folder contains `splash_screen.svg` file. * You can simply replace these files with your custom splash screen while retaining the file names, or you can customize the splash screen configuration using SDK properties if different names or additional configurations are needed. * This configuration automatically applies across all target platforms included in the single project structure. ## Utilizing SDK Properties The Uno Platform SDK exposes several properties that simplify the customization of your splash screen. These properties allow you to easily adjust key aspects like the base size, color, and icon files without detailed XML changes, making your development process more streamlined. * `UnoSplashScreenFile`: Specifies the image file for the splash screen. * `UnoSplashScreenBaseSize`: Sets the base size for the splash screen image. * `UnoSplashScreenColor`: Determines the background color of the splash screen. To facilitate easier customization, such as adjusting the base size or color of the splash screen, you can leverage SDK properties: ```xml Assets\SplashScreen\custom_splash_screen.svg 128,128 #512BD4 ``` This setup ensures that the splash screen settings are centralized, simplifying the maintenance and updating process. # [**Class Library Based Solution**](#tab/classlib) * Create a `SplashScreen` folder inside the Base project, and add the file related to the splash screen there. * Now, open the `base.props` file inside the `MyApp.Base` folder project and add the following block: ```xml ``` We recommend adding the `UnoSplashScreen` on `base.props` because this file is imported by all head projects, that way, you don't need to add the same configuration on each head project. If you want, you can see our sample project in [Uno.Resizetizer GitHub repository](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Base/base.props#L17-L21). # [**Shared Project Based Solution**](#tab/sharedproject) * Create a `SplashScreen` folder inside the Shared project, and add the file related to the splash screen there. * In each of your project heads (iOS, Android, WebAssembly, ...), add the following block to the `csproj` file: ```xml ``` You can also make specific files to be `UnoSplashScreen` using Visual Studio, by right-clicking on the file, selecting `Properties`, then `Build Action`, and selecting `UnoSplashScreen`. The image below shows what it looks like: ![UnoSplashScreen Build Action](Assets/UnoSplashScreen_BuildAction.png) *** Next, some adjustments are needed on `Android`, `Windows`, and `iOS`. # [**Android**](#tab/Android) * Open the [`style.xml` file](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Mobile/Android/Resources/values/Styles.xml), look for the `Theme` that is been used by the application and add the following line: ```xml ``` > [!NOTE] > The `uno_splash_image` and `uno_splash_color` are generated by the build process. # [**Windows (WinUI)**](#tab/Windows) * Open the [`Package.appxmanifest` file](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Windows/Package.appxmanifest) and look for the `Application` node, inside it, look for the `uap:SplashScreen` node. Delete the `Image` property and its value, the `Application` tag should be like this: ```xml ``` # [**Web Assembly (Wasm)**](#tab/Wasm) * No additional adjustments are needed on Wasm. # [**iOS**](#tab/iOS) * Open the [`info.plist` file](https://github.com/unoplatform/uno.resizetizer/blob/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate/Resizetizer.Extensions.Sample.Mobile/iOS/Info.plist) and look for the `UILaunchStoryboardName` key, delete it and its value. > [!TIP] > Feel free to delete the `LaunchScreen.storyboard` file. > [!NOTE] > Feel free to delete old assets related to the splash screen. ----- ## Platform-Specific Customization The Uno Resizetizer SDK allows for detailed control over how assets are rendered on different platforms. This can be particularly useful for properties such as icon and splash screen backgrounds, which may need to vary between platforms due to design or visibility concerns. ### Customizing Background Colors Per Platform For properties like BackgroundColor, which might need different values per platform (for example, transparent backgrounds on Windows and WASM but a solid color on iOS and Android), you can specify platform-specific properties in your project file: ```xml #FFFFFF #000000 #FF0000 Transparent Transparent ``` This setup demonstrates setting a default background color that is overridden on specific platforms. Adjust the conditions to match your project's target frameworks as defined in your project files or SDK documentation. #### Applying Platform-Specific Scale Similarly, if you want to apply different scaling factors for the icon foreground across platforms, use the platform-specific properties: ```xml 0.5 0.6 0.4 0.3 0.55 ``` ## Using SVG Images vs PNG Images with SVG underneath The Uno Platform allows for flexible image handling through direct SVG use or through asset generation via Uno.Resizetizer. Understanding when to use each approach can optimize your app's performance and visual quality. ### Direct SVG Usage #### When to Use: * You require vector graphics to be scalable without loss of quality. * Your app needs to dynamically change aspects of the image, such as color or size, at runtime. #### How to Implement: * Add a folder named `Svg` in `Assets` and add your SVG file. * Set the build action of your SVG file to `Content`. * Reference the SVG file directly in the Image control's Source property. ```xml ``` [Using Svg Images](https://platform.uno/docs/articles/features/svg.html?tabs=singleproject) ### Using Uno.Resizetizer for SVG to PNG Conversion #### When to Use: * You need raster graphics to optimize performance on platforms where SVG rendering might be less efficient. * Your app targets multiple platforms and requires consistent image rendering across all. #### How to Implement: * Set the build action of your SVG file to UnoImage. * Uno.Resizetizer will generate PNG assets at various scales. * Reference the generated PNG in the Image control's Source property. ```xml ``` [Using Uno Resizetizer ](https://platform.uno/docs/articles/external/uno.resizetizer/doc/using-uno-resizetizer.html?tabs=classlib%2CAndroid#unoimage) Choosing between direct SVG usage and PNG conversion with Uno.Resizetizer depends on your specific application needs. Consider factors such as platform target, performance requirements, and how you plan to manipulate the images within your app. ## Sample App Example A sample app is available [here](https://github.com/unoplatform/uno.resizetizer/tree/7ad1199ea1a256e171d88e694486e9a8c341c8a2/samples/NewTemplate) as an example for all the previous steps detailed above. ## Troubleshooting ### Windows (WinUI) In some cases, the OS caches the app icon and your changes might not be applied. To fix this issue, first uninstall your app and then use one of the following options: 1. In the run dialog (Win + R) execute `ie4uinit.exe -ClearIconCache` 2. Restart `explorer.exe` process (in **Task Manager - Details** select `explorer.exe` in the list and click on **Restart task**). 3. Reboot your PC Afterward, try to deploy the app again and your icons should be updated correctly. ### Icon Assets The Icon Extension generation will not succeed if the project cannot find `/Assets/Icons/icon.svg` and `/Assets/Icons/icon_foreground.svg`. You can find the related GitHub issue [here](https://github.com/unoplatform/uno.resizetizer/issues/289). Without these icon assets, a reference error will occur: _CS0234: The type or namespace name 'Resizetizer' does not exist in the namespace 'Uno' (are you missing an assembly reference?)_. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/using-uno-ui.md --- uid: Uno.Development.Overview --- # Developing with Uno Platform Write applications once in XAML and/or C# and deploy them to [any target platform](getting-started/requirements.md). ## About Uno * [What is Uno Platform?](xref:Uno.Documentation.Intro) * [How does Uno Platform work?](xref:Uno.Development.HowItWorks) * [Supported target platforms](xref:Uno.GettingStarted.Requirements) * [Supported .NET versions by platform](xref:Uno.Development.NetVersionSupport) ## Mastering the basics The WinUI application API which Uno Platform uses is extensively documented by Microsoft. We've [selected some articles from Microsoft](winui-doc-links.md) which will jump-start your Uno Platform development. Here are some articles which cover the basics of cross-platform Uno development: * [The structure of an Uno Platform codebase](uno-app-solution-structure.md) * Platform-specific code: [C#](platform-specific-csharp.md) and [XAML](platform-specific-xaml.md) * [Best practices for developing Uno Platform applications](best-practices-uno.md) ## WinUI features These articles cover general WinUI features in Uno Platform, discussing what's supported and which platform-specific constraints exist. * [Accessibility](features/working-with-accessibility.md) * [Assets in shared code](features/working-with-assets.md) * [Custom fonts](features/custom-fonts.md) * [Shapes & Brushes](features/shapes-and-brushes.md) * [Handling user input](features/pointers-keyboard-and-other-user-inputs.md) * [Using Fluent styles in legacy apps](features/using-winui2.md) ## WinUI controls Uno Platform provides support for a large number of WinUI controls, panels, and visual primitives - see [a complete list](implemented-views.md) in the Reference documentation. The 'WinUI controls' section in the Table of Contents on the left covers platform-specific constraints and extensions for selected controls. ## WinRT features (non-visual APIs) Uno Platform supports a number of non-visual APIs from Windows Runtime namespaces on non-Windows platforms, like [clipboard management](features/windows-applicationmodel-datatransfer.md) and [sensor access](features/windows-devices-sensors.md). [!include[Inline table of contents](includes/winrt-features-inline-toc.md)] ## Features unique to Uno * [VisibleBoundsPadding - manage 'safe' area on notched devices](features/VisibleBoundsPadding.md) * [ElevatedView - apply a shadow effect on all platforms](features/ElevatedView.md) * [Uno.Material - Material Design on all platforms](external/uno.themes/doc/material-getting-started.md) * [Uno.Cupertino](external/uno.themes/doc/cupertino-getting-started.md) ## Core functionality * [Enable and configure logging](logging.md) * [Configure build telemetry](uno-toolchain-telemetry.md) * [Add native views to the visual tree](native-views.md) * [Enable native control styles (Android and iOS)](native-styles.md) ## Common development tasks * [Migrating single-platform WinUI/UWP code](howto-migrate-existing-code.md) * [Creating a cross-targeted library](migrating-libraries.md) * [Upgrading from an older Uno.UI releases](migrating-from-previous-releases.md) ## Debugging Uno Platform applications * [Hot Reload](xref:Uno.Features.HotReload) * [Troubleshooting build errors](uno-builds-troubleshooting.md) * [Debugging C# on WASM](debugging-wasm.md) --- # Source: https://raw.githubusercontent.com/unoplatform/uno.uitest/refs/heads/master/doc/using-uno-uitest.md --- uid: Uno.UITest.GetStarted --- # Using Uno.UITest Uno.UITest is a framework to enable **unified UI Testing** of [Uno Platform apps](https://github.com/unoplatform/uno), using [NUnit 3.x](https://github.com/nunit/nunit). This library provides a set of APIs to interact with an app, and assess its behavior using device simulators and browsers. The API set is based on [Xamarin.UITest](https://docs.microsoft.com/en-us/appcenter/test-cloud/uitest/), which makes the migration and patterns very familiar. The testing is available through : - Selenium for WebAssembly apps, using Chrome - [Xamarin.UITest](https://docs.microsoft.com/en-us/appcenter/test-cloud/uitest/) and [AppCenter](https://appcenter.ms/apps) for iOS and Android apps. The following target platforms are not yet supported: - SkiaSharp backends (GTK, WPF and Tizen ) - Xamarin.macOS - Windows ## How to use Uno.UITest with an Uno Platform app > [!TIP] > UI Testing setup is already integrate in Uno Platform 4.8 and later, see our [getting started](xref:Uno.GetStarted) to create your Uno Platform app. - Make sure [Chrome is installed](https://www.google.com/chrome) - In Visual Studio for Windows, [create an application](https://platform.uno/docs/articles/getting-started-tutorial-1.html) using the Uno Platform templates - Add the following code to each `.csproj` files (iOS, Android and WebAssembly), at the end before the closing `` tag: ```xml True $(DefineConstants);USE_UITESTS ``` - In the iOS project, add a reference to the `Xamarin.TestCloud.Agent` nuget package (0.21.8 or later) - In the `OnLaunched` method of `App.xaml.cs`, add the following at the beginning: ```csharp #if __IOS__ && USE_UITESTS // Launches Xamarin Test Cloud Agent Xamarin.Calabash.Start(); #endif ``` - Install the Uno Platform `dotnet new` templates: ```sh dotnet new -i Uno.ProjectTemplates.Dotnet ``` - Navigate to your `.sln` folder using a command line: - Create a folder named `YourAppName\YourAppName.UITests` - Then run : ``` cd YourAppName.UITests dotnet new unoapp-uitest ``` The new project will be added automatically to your solution. If you get "No templates found matching: 'unoapp-uitest'." error, please see [dotnet new templates for Uno Platform](https://platform.uno/docs/articles/get-started-dotnet-new.html) article. - In the new UI Tests project, edit the `Constants.cs` file with values that match your project - In your application, add the following XAML: ```XAML ``` > Note that `AutomationProperties.AccessibilityView="Raw"` is only required for `ContentControl` based controls to allow for `cb1` to be selectable instead of the text `Test 1`. - Then following test can be written: ```csharp using NUnit.Framework; using Uno.UITest.Helpers.Queries; using System.Linq; // Alias to simplify the creation of element queries using Query = System.Func; public class CheckBox_Tests : TestBase { [Test] public void CheckBox01() { Query checkBoxSelector = q => q.Marked("cb1"); App.WaitForElement(checkBoxSelector); Query cb1 = q => q.Marked("cb1"); App.WaitForElement(cb1); var value1 = App.Query(q => cb1(q).GetDependencyPropertyValue("IsChecked").Value()).First(); Assert.IsFalse(value1); App.Tap(cb1); var value2 = App.Query(q => cb1(q).GetDependencyPropertyValue("IsChecked").Value()).First(); Assert.IsTrue(value2); } } ``` This sample is provided through the [`Sample.UITests` project](https://github.com/unoplatform/Uno.UITest/tree/master/src/Sample/Sample.UITests) in this repository. ### Running the tests for WebAssembly - To test in Chrome, first deploy the WebAssemly app using `Ctrl+F5`, take note of the Url of the app - Update the `Constants.WebAssemblyDefaultUri` property in `Constants.cs` - Change the `Constants.CurrentPlatform` to `Platform.Browser` - [Launch a test](https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019) by right clicking on the test in the Test Explorer, or in the test code itself. - A Chrome browser window will open in automated mode, and the test will execute. ### Running the tests for Android - Build and deploy the app on a simulator - Update the `Constants.AndroidAppName` property in `Constants.cs` to the value set in your app manifest - Change the `Constants.CurrentPlatform` to `Platform.Android` - [Launch a test](https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019) by right clicking on the test in the Test Explorer, or in the test code itself. - The application will start on the emulator, and the test will execute ### Running the tests for iOS > testing for iOS is only available through Visual Studio for Mac, where the simulators can run. - Open your solution in Visual Studio for mac - Build and deploy the app on an iOS simulator - Update the `Constants.iOSAppName` property in `Constants.cs` to the value specified in your `info.plist` file - Change the `Constants.CurrentPlatform` to `Platform.iOS` - [Launch a test](https://docs.microsoft.com/en-us/visualstudio/mac/testing?view=vsmac-2019) - The application will start on the emulator, and the test will execute This sample is provided through the [`Sample.UITests` project](https://github.com/unoplatform/Uno.UITest/tree/master/src/Sample/Sample.UITests) in this repository. ### Validating the currently running environment ```csharp if(AppInitializer.GetLocalPlatform() == Platform.Android) { Assert.Ignore(); } ``` ## UI Testing in a CI environment One of the design goal of the `Uno.UITest` library is to enable UI Testing in Pull Request builds, so that the UI testing is not an afterthought, and is part of the development flow. You can find some scripts examples to enable such testing, using [Azure Devops hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops): - [Android UI Testing in a Simulator](https://github.com/unoplatform/Uno.UITest/blob/master/build/android-uitest-run.sh) using Linux - [WebAssembly UI Testing](https://github.com/unoplatform/Uno.UITest/blob/master/build/wasm-uitest-run.sh) using Linux - [iOS UI Testing in an simulator](https://github.com/unoplatform/Uno.UITest/blob/master/build/ios-uitest-run.sh) using macOS --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-winrt.md --- uid: uno.features.uno.winrt --- # Non-UI Cross-Platform API - Using Uno.WinRT Uno.WinRT is the non-UI layer of Uno Platform. It is composed of APIs that have been present since the beginning of Uno Platform to provide cross-platform access to non-UI features such as generic filesystem, sensors, file/image/video picking, networking, and devices like MIDI, flashlight, geolocation, Game Pads, and dozens more. These APIs can be used in a NuGet package directly, without depending on UI features. For a list of available APIs, browse the tree on the side of this document. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/using-winui2.md --- uid: Uno.Features.WinUI2 --- # Using Fluent styles in legacy apps > This article is only relevant for migration of **legacy UWP-based Uno Platform applications**. Modern template has Fluent styles included by default. ## Enabling Fluent styles 1. In the `UWP` head project of your solution, install the [WinUI 2 NuGet package](https://www.nuget.org/packages/Microsoft.UI.Xaml). 1. There's no extra package to install for non-Windows head projects - the WinUI 2 controls are already included in the `Uno.UI` NuGet package which is installed with the default Uno Platform template. 1. Open the `App.xaml` file inside one of the Head project used by all platform heads. Add the `XamlControlsResources` resource dictionary to your application resources inside `App.xaml`. ```xml ``` Or, if you have other existing application-scope resources, add `XamlControlsResources` at the top (before other resources) as a merged dictionary: ```xml ``` 1. Now you're ready to use WinUI 2 controls in your application. Sample usage for the `NumberBox` control: ```xml ``` --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/getting-started/wizard/using-wizard.md --- uid: Uno.GettingStarted.UsingWizard --- # The Uno Platform Solution Template > [!Video https://www.youtube-nocookie.com/embed/s_QbZbPIeWY] ## Solution Structure Both the Visual Studio Template Wizard, which comes with the [Uno Platform Visual Studio extension](https://marketplace.visualstudio.com/items?itemName=unoplatform.uno-platform-addin-2022), and the `dotnet new` [unoapp template](xref:Uno.GetStarted.dotnet-new) create a Uno Platform application with the same solution structure. In this guide, we'll explain the different options that can be used to configure the solution that gets generated. The options will be discussed in the groups they appear in the wizard. ## Preset selection [!INCLUDE [Startup](includes/startup.md)] --- ### 1. Framework [!INCLUDE [Framework](includes/framework.md)] --- ### 2. Platforms [!INCLUDE [Platforms](includes/platforms.md)] --- ### 3. Presentation [!INCLUDE [Presentation](includes/presentation.md)] --- ### 4. Markup [!INCLUDE [Markup](includes/markup.md)] --- ### 5. Theme [!INCLUDE [Theme](includes/themes.md)] --- ### 6. Extensions [!INCLUDE [Extensions](includes/extensions.md)] --- ### 7. Features [!INCLUDE [Features](includes/features.md)] --- ### 8. Authentication [!INCLUDE [Authentication](includes/authentication.md)] --- ### 9. Application [!INCLUDE [Application](includes/application.md)] --- ### 10. Testing [!INCLUDE [Testing](includes/testing.md)] --- ### 11. CI Pipeline [!INCLUDE [CI Pipeline](includes/cipipeline.md)] --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uwp-vs-winui3.md --- uid: Uno.Development.UwpVsWinUI3 --- # WinUI 3 and Uno Platform WinUI 3 is the [next generation of Microsoft's Windows UI library](https://learn.microsoft.com/windows/apps/winui/). It succeeds the UWP XAML framework as Microsoft's actively developed native UI platform for Windows. WinUI 3 supports Windows Desktop apps through [Windows AppSDK](https://learn.microsoft.com/windows/apps/windows-app-sdk/). > [!TIP] > If you just want to add Fluent styles to legacy Uno Platform projects, [check the guide here](features/using-winui2.md). ## How does WinUI 3 differ from UWP XAML? WinUI 3 differs in minor ways from UWP XAML in terms of API, and in more substantial ways in its technical comportment. ### API The main difference between WinUI 3 and UWP XAML is the change of namespace. UWP XAML namespaces begin with 'Windows' - `Windows.UI.Xaml`, `Windows.UI.Composition`, and so on. WinUI 3 namespaces begin with 'Microsoft' - `Microsoft.UI.Xaml`, `Microsoft.UI.Composition`, and so on. Aside from that change, the API surface is very similar. Some of the remaining differences are listed in our [guide to upgrading to WinUI 3](updating-to-winui3.md). ### Technical Below the surface, the differences are more substantial. The UWP XAML stack is part of the Windows OS. The WinUI 3 stack is decoupled from the Windows OS. This means application developers can use the newest features without worrying that they might not be supported on the end user's system. WinUI 3 is also decoupled from the application model. The UWP XAML stack is only compatible with the 'UWP model' in which the application runs in a secure sandbox. WinUI 3 is compatible both with the 'UWP model' and with the traditional 'Win32' or 'desktop' application model in which the application has largely-unrestricted access to the rest of the OS. ## How does this affect Uno Platform? Uno Platform is only affected by the API change - the technical changes don't apply on non-Windows platforms. When you create a new Uno Platform application, you can choose to create a WinUI 3-compatible application (using the WinUI 3 API, and building with WinUI 3 on the Windows head project) instead of a UWP XAML-compatible application [using the `dotnet new` templates](get-started-dotnet-new.md#uno-platform-blank-application-for-winappsdk---winui-3). ### Do you plan to publish on Windows? If Windows is one of your target platforms, then the [technical differences](#technical) discussed above apply. Probably the key question is, can your application run in the sandboxed 'UWP model', or is it better served by the unrestricted 'Win32 model'? ### Do you depend on features that haven't yet migrated to WinUI 3? [Check the WinUI 3 roadmap](https://github.com/microsoft/microsoft-ui-xaml/blob/master/docs/roadmap.md#winui-30-feature-roadmap) for a list of features that won't be available in the initial supported release, like `InkCanvas`. ## Further reading * [Create a new WinUI 3-flavored Uno Platform app with Project Reunion support](get-started-winui3.md) * [Migrate an existing Uno Platform app to WinUI 3](updating-to-winui3.md) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/vscode-advanced-mobile-debugging.md --- uid: uno.vscode.mobile.advanced.debugging --- # Advanced Topics for VS Code for Mobile Targets Starting from Uno 4.8.26, the Uno Platform solution templates contains the appropriate support to debug Mobile applications. See below for adjusting projects. ## Supported Features ### SourceLink and Sources embedded inside PDB Both [Source Link](https://github.com/dotnet/designs/blob/main/accepted/2020/diagnostics/source-link.md) and "Sources embedded inside PDB" features are used by Uno Platform and are supported by the extension. However, only Android includes the `.pdb` of the referenced assemblies inside debug builds for net6.0. This makes the features unusable for iOS and macOS, see [issue](https://github.com/xamarin/xamarin-macios/issues/11879#issuecomment-1279452073). This situation [should be](https://github.com/dotnet/sdk/issues/1458#issuecomment-1244736464) fixed with net7.0. A workaround for .NET 6 mobile projects is to install [Cymbal](https://github.com/SimonCropp/Cymbal). ### Remote SSH VS Code can [connect to a remote computer](https://code.visualstudio.com/docs/remote/ssh) (using `ssh`) to develop and debug projects. Note that all the sources, build and debugging are done on the remote computer, where the Uno Platform extension is being executed. ### Logpoints [Logpoints](https://code.visualstudio.com/blogs/2018/07/12/introducing-logpoints-and-auto-attach#_introducing-logpoints) are functionally similar to adding `Console.WriteLine` but without modifying the sources. ## Converting existing projects Existing Uno Platform projects requires a few simple changes to work properly with multiples TargetFrameworks inside VS Code. ### launch.json You can add a default entry for all mobile targets by adding the following JSON block inside your `launch.json`. ```json { "name": "Uno Platform Mobile", "type": "Uno", "request": "launch", // any Uno* task will do, this is simply to satisfy vscode requirement when a launch.json is present "preLaunchTask": "Uno: net7.0-android | Debug | android-x64" }, ``` This will ask the `Uno` debug provider how to build and launch the application. The Target Framework Moniker (TFM) selected in VS Code's status bar, e.g. `net7.0-ios`, and the target platform, e.g. `iossimulator-x64`, will be used automatically. > [!NOTE] > Uno Platform's [templates](https://www.nuget.org/packages/uno.templates/) already include this change. ## Debugging with the Windows Subsystem for Android You first need to [connect](https://learn.microsoft.com/windows/android/wsa/#connect-to-the-windows-subsystem-for-android-for-debugging) to the Windows Subsystem for Android (WSA) in order to use it for debugging. From the command-line type: ```bash adb connect 127.0.0.1:58526 ``` and you should then be able to see the WSA device inside VSCode. You can also confirm it's connected from the command-line: ```bash $ adb devices -l List of devices attached 127.0.0.1:58526 device product:windows_arm64 model:Subsystem_for_Android_TM_ device:windows_arm64 transport_id:1 ``` ## Settings ### Unoplatform › Debugger: Exception Options You can choose to break execution on specific exceptions, either always or if the exception is unhandled. Note: Those settings do not apply when debugging Windows (WinUI) or macOS (AppKit) application since it use the CoreCLR debugger. ### Unoplatform › Debugger › Ios › Mlaunch: Extra Arguments For example you can add `-vvvvv` to get more verbosity from `mlaunch`. This can be useful if you run into issues deploying your application to an iOS device. ### Unoplatform › Debugger › Ios › Mlaunch: Path By default the version of `mlaunch` associated with the currently iOS workload will be used to launch application to iOS devices. You can override the path to the `mlaunch` tool to be used. For example you could set the path to `/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/bin/mlaunch` to use the version from the legacy (pre-net6.0) Xamarin.iOS SDK. This can be useful when a new Xcode is released, requiring an update to `mlaunch`, while allowing you to use the current stable SDK version for development. ### Unoplatform › Debugger › Ios › Simulator: X64 By default the simulators are listed for both `arm64` and `x64` on Apple Silicon Macs. `x64` simulators are provided using Rosetta emulation and is required if `arm64` support is missing for some dependencies (e.g. SkiaSharp). This can be useful if your project has dependencies that are not available yet for the `arm64` architecture. ## Environment Variables ### Xcode override The Uno extension uses `xcrun` to find the active Xcode version to use. You can override this version of Xcode by setting the `DEVELOPER_DIR` environment variable. More information can be found running `man xcrun` inside the terminal. ## Advanced Debugger Configuration It is possible to create advanced `launch.json` and `tasks.json` entries if additional customization is needed for a project. ### Editing `launch.json` The extension provides default launch configurations for supported platforms, without the need to define them inside the `launch.json` file. If you need to define launches or modify the defaults then you can can create your own. 1. Press the `Shift+Cmd+P` keys to open the **Command Palette** 1. Select the `Debug: Select and Start Debugging` item 1. Select the `Add Configuration...` item 1. Select `.NET Custom Launch Configuration for Uno Platform` item 1. This will insert a JSON block that looks like the following: ```json { "comment1": "// name: unique name for the configuration, can be identical to preLaunchTask", "name": "Uno: net6.0-android | Debug | android-x64", "comment2": "// type: 'Uno' for mono-based SDK, 'coreclr' for desktop targets", "type": "Uno", "request": "launch", "comment3": "// preLaunchTask format is 'Uno: {tfm} | {config}[ | {rid]}]' where ", "comment4": "// * {tfm} is the target framework moniker, e.g. net6.0-ios", "comment5": "// * {config} is the build configuration, e.g. 'Debug' or 'Release'", "comment6": "// * {rid} is the optional runtime identifier, e.g. 'osx-arm64'", "comment7": "// E.g. 'Uno: net6.0-ios | Debug | iossimulator-x64', 'Uno: net6.0 | Debug' for desktop", "preLaunchTask": "Uno: net6.0-android | Debug | android-x64" }, ``` 1. Follow the comments to construct the launch required by your target platform, for example: ```json { "name": "net7.0-ios | simulator | x64", "type": "Uno", "request": "launch", "preLaunchTask": "Uno: net7.0-ios | Debug | iossimulator-x64" }, ``` If you follow the `Uno: {tfm} | {config}[ | {rid]}]` convention then there is no need to add entries inside the `tasks.json` file, the extension already provides them. ### Customizing tasks.json The extension provides default build tasks for most platforms without the need to define them inside the `tasks.json` file. If you need to define tasks or something that the default built-in tasks do not provide, you can create your own. 1. Press the `Shift+Cmd+P` keys to open the **Command Palette**. 1. Select the `Tasks: Configure Tasks` item. 1. Pick the `Uno: *` task that is the closest to your need. 1. Edit the `args` section but avoid changing the other values (besides the `label`) to keep automation working. See [VS Code documentation](https://code.visualstudio.com/docs/editor/tasks) for more information. #### Example ```json { "label": "custom-mac-build", "command": "dotnet", "type": "process", "args": [ "build", "${workspaceFolder}/unoapp/unoapp.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary", // specify the target platform - since there's more than one inside the mobile.csproj "/property:Configuration=Debug", // this is to workaround both an OmniSharp limitation and a dotnet issue #21877 "/property:UnoForceSingleTFM=true" // other custom settings that you need ], "problemMatcher": "$msCompile" }, ``` #### Tips * Most of the build settings should be done (or changed) inside the `.csproj` file. This way only a simple `dotnet build` is needed to create the applications. * The easiest way to create a custom task is to look at the build logs and see what is normally provided, by default, to build for a specific target platform. * You will also need a custom launch target that will use the `label` name for it's `preLaunchTask`. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/wasm-appmanifest.md --- uid: Uno.Development.WasmAppManifest --- # AppManifest for WebAssembly head project The `[AppName]` project in your solution typically includes a manifest file containing settings for the WebAssembly application. This file is typically generated for you under `Platforms/WebAssembly/WasmScripts/AppManifest.js`. ## AppManifest properties This app manifest file allows you to customize certain aspects of the WebAssembly application, including its loading screen. This loading UI is often referred to as the "splash screen" in documentation. For more information, see [How to manually add a splash screen](xref:Uno.Development.SplashScreen#5-webassembly). ## Add a missing manifest file If you created an application without using the default Uno [templates](xref:Uno.GetStarted.dotnet-new), you may need to add the manifest file manually. To do this, create a folder named `Platforms/WebAssembly/WasmScripts` in your `[AppName]` project, with a file containing the JavaScript code below (e.g. `AppManifest.js`). If the project is not using the [Uno.Sdk](xref:Uno.Features.Uno.Sdk), Set the manifest file's build action to `Embedded resource`, and edit the contents of this file to resemble the following: ```javascript var UnoAppManifest = { splashScreenImage: "Assets/SplashScreen.scale-200.png", splashScreenColor: "transparent", displayName: "SplashScreenSample" } ``` ## See also - [WebAssembly: Supported AppManifest properties](xref:Uno.Development.SplashScreen#5-webassembly) - [Deep-dive: How Uno works on WebAssembly](xref:Uno.Contributing.Wasm#web-webassembly) - [Get Started: Get the Uno Platform templates](xref:Uno.GetStarted) --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/interop/wasm-javascript-1.md --- uid: Uno.Interop.WasmJavaScript1 --- # Embedding Existing JavaScript Components Into Uno-WASM - Part 1 ## HTML5 is a Rich and Powerful Platform Uno Platform fully embraces HTML5 as its display backend when targeting WebAssembly, for both Native and Skia renderers. As a result, it is possible to integrate with almost any existing JavaScript library to extend the behavior of an app. ## Embedding assets In the HTML world, everything running in the browser is assets that must be downloaded from a server. To integrate existing JavaScript frameworks, they can be either downloaded from another location on the Internet (usually from a CDN service) or embedded and deployed with the app. The Uno Bootstrapper can automatically embed any asset and deploy it with the app. Some of them (CSS & JavaScript) can also be loaded with the app. Here's how to declare them in a *Uno Wasm* project: 1. **JavaScript files** should be in the `Platforms/WebAssembly/WasmScripts` folder. They will be copied to the output folder and loaded automatically by the bootstrapper when the page loads. 2. **CSS Style files** should be in the `Platforms/WebAssembly/WasmCSS` folder. They will be copied to the output folder and referenced in the *HTML head* of the application. 3. **Asset files** can be placed in the `Assets` folder. These files will be copied to the output folder and will preserve the same relative path to the `Assets` folder. 4. Alternatively, **any kind of asset file** can be placed directly in the `wwwroot` folder as with any standard ASP.NET Core project. They will be deployed with the app, but the application code is responsible for fetching and using them. > **Is it an ASP.NET Core "web" project?** > No, but it shares a common structure. Some of the deployment features, like the `wwwroot` folder, and the Visual Studio integration for running/debugging are reused in a similar way to an ASP.NET Core project. The C# code put in the project will run in the browser, using the .NET runtime. There is no need for a server side component in Uno-Wasm projects. ## Embedding Native Elements Embedding native JavaScript elements is done through the `Uno.UI.NativeElementHosting.BrowserHtmlElement` class, which serves as an entry point to interact with your native element. > [!IMPORTANT] > The `BrowserHtmlElement` class is available on all target frameworks, eliminating the need for `#if` condition code, but it is only usable on WebAssembly. You'll need to guard its use by validating the platform with the `OperatingSystem` class. ```csharp using Uno.UI.NativeElementHosting.BrowserHtmlElement; public sealed partial class MyControlHost : ContentControl { private BrowserHtmlElement? _element; public MyControlHost() { if (OperatingSystem.IsBrowser()) { _element = BrowserHtmlElement.CreateHtmlElement("div"); Content = _element; } else { Content = "This control only supported on WebAssembly on the Browser"; } } } ``` This way, your native element is hosted inside a content control of your choosing. You can replace it with any available HTML tag. Once created, it is possible to interact directly with this element by calling `BrowserHtmlElement` methods. Here is a list of helper methods used to facilitate the integration with the HTML DOM: * The method `element.SetCssStyle()` can be used to set a CSS Style on the HTML element. Example: ```csharp // Setting only one CSS style _element.SetCssStyle("text-shadow", "2px 2px red"); // Setting many CSS styles at once using C# tuples _element.SetCssStyle(("text-shadow", "2px 2px blue"), ("color", "var(--app-fg-color1)")); ``` * The `element.ClearCssStyle()` method can be used to set CSS styles to their default values. Example: ```csharp // Reset text-shadow style to its default value _element.ClearCssStyle("text-shadow"); // Reset both text-shadow and color to their default values _element.ClearCssStyle("text-shadow", "color"); ``` * The `element.SetHtmlAttribute()` and `element.ClearHtmlAttribute()` methods can be used to set HTML attributes on the element: ```csharp // Set the "href" attribute of an element _element.SetHtmlAttribute("href", "#section2"); // Set many attributes at once (less interop) _element.SetHtmlAttribute(("target", "_blank"), ("referrerpolicy", "no-referrer")); // Remove attribute from DOM element _element.ClearHtmlAttribute("href"); // Get the value of an attribute of a DOM element var href = _element.GetHtmlAttribute("href"); ``` * The `element.SetCssClass()` and `element.UnsetCssClass()` methods can be used to add or remove CSS classes to the HTML Element: ```csharp // Add the class to element _element.SetCssClass("warning"); // Add many classes at once (less interop) _element.SetCssClass("warning", "level2"); // Remove class from element _element.UnsetCssClass("paused"); // You can also set one class from a list of possible values. // Like a radio-button, like non-selected values will be unset var allClasses = new [] { "Small", "Medium", "Large"}; _element.SetCssClass(allClasses, 2); // set to "Large" ``` * The `element.SetHtmlContent()` method can be used to set arbitrary HTML content as child of the control. ```csharp _element.SetHtmlContent("

Welcome to Uno Platform!

"); ``` * Finally, it is possible to make calls from and to JavaScript code by using [JSImport/JSExport](xref:Uno.Wasm.Bootstrap.JSInterop). The javascript code is directly executed in the context of the browser, giving the ability to perform anything that JavaScript can do. See next section for more details. ## Raising custom Javascript events It's also possible to have Javscript components raise events to be handled by C# code. From your Javascript or TypeScript code, you can raise events: ```javascript // Generate a custom generic event from JavaScript/Typescript htmlElement.dispatchEvent(new Event("simpleEvent")); // Generate a custom event with a string payload const payload = "this is the payload of the event"; htmlElement.dispatchEvent(new CustomEvent("stringEvent", { detail: payload })); // Generate a custom event with a complex payload const payload = { property:"value", property2: 1234 }; htmlElement.dispatchEvent(new CustomEvent("complexEvent", { detail: payload })); ``` Then from your C# code, add the following: ```csharp protected override void OnLoaded() { // Note: following extensions are in the namespace "Uno.Extensions" this.RegisterHtmlEventHandler("simpleEvent", OnSimpleEvent); this.RegisterHtmlEventHandler("stringEvent", OnStringEvent); this.RegisterHtmlEventHandler("complexEvent", OnComplexEvent); } private void OnSimpleEvent(object sender, JSObject args) { // You can react on "simpleEvent" here } private void OnStringEvent(object sender, JSObject args) { // You can react on "stringEvent" here var detail = args.GetPropertyAsString("detail"); } private void OnComplexEvent(object sender, JSObject args) { // You can react on "complexEvent" here var detail = args.GetPropertyAsJSObject("detail"); var property = detail?.GetPropertyAsString("property"); var property2 = detail?.GetPropertyAsInt32("property2"); } ``` ## 🔬 Going further * [Continue with Part 2](xref:Uno.Interop.WasmJavaScript2) - an integration of a syntax highlighter component. * [Continue with Part 3](xref:Uno.Interop.WasmJavaScript3) - an integration of a more complex library with callbacks to application. * Read the [Uno Wasm Bootstrapper](xref:UnoWasmBootstrap.Overview) documentation. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/interop/wasm-javascript-2.md --- uid: Uno.Interop.WasmJavaScript2 --- # Embedding Existing JavaScript Components in Uno Platform - Part 2 Let's create an app to integrate a Syntax Highlighter named [`PrismJS`](https://prismjs.com/). This library is simple and is self-contained - there's no external dependencies. ## Integration of PrismJS in a project ### 0. Before starting 📝 To reproduce the code in this article, you must [prepare a development environment using Uno's _Getting Started_ article](xref:Uno.GetStarted). ### 1. Create the projects 🎯 This section is very similar to the [Create a Counter App with Uno Platform](xref:Uno.Workshop.Counter) tutorial in the official documentation. Create a [new Uno Platform App project](xref:Uno.GetStarted) using one of the getting started **blank** or **recommended** presets. ### 2. Create a control in managed code 🎯 In this section, a control named `PrismJsView` is created in code and used in the XAML page (`MainPage.xaml`) to present it. 1. From the `[MyApp]` project, create a new class file named `PrismJsView.cs`. and copy the following code: ```csharp using System; using System.Collections.Generic; using System.Text; using Uno.Foundation; using Uno.UI.Runtime.WebAssembly; namespace PrismJsDemo; using Uno.UI.NativeElementHosting; namespace PrismJsDemo; class PrismJsView : ContentControl { private BrowserHtmlElement? _element; // ************************* // * Dependency Properties * // ************************* public static readonly DependencyProperty CodeProperty = DependencyProperty.Register( nameof(Code), typeof(string), typeof(PrismJsView), new PropertyMetadata(default(string), CodeChanged)); public string Code { get => (string)GetValue(CodeProperty); set => SetValue(CodeProperty, value); } public static readonly DependencyProperty LangProperty = DependencyProperty.Register( "Lang", typeof(string), typeof(PrismJsView), new PropertyMetadata(default(string), LangChanged)); public string Lang { get => (string)GetValue(LangProperty); set => SetValue(LangProperty, value); } // *************** // * Constructor * // *************** public PrismJsView() { _element = BrowserHtmlElement.CreateHtmlElement("code"); Content = _element; } // ****************************** // * Property Changed Callbacks * // ****************************** private static void CodeChanged(DependencyObject dependencyobject, DependencyPropertyChangedEventArgs args) { // TODO: generate HTML using PrismJS here } private static void LangChanged(DependencyObject dependencyobject, DependencyPropertyChangedEventArgs args) { // TODO: generate HTML using PrismJS here } } ``` This will define a control having 2 properties, one code `Code` and another one for `Lang`. 2. Change the `MainPage.xaml` file to the following content: ```xml ``` 3. Press CTRL-F5. You should see this: ![Browser image](assets/image-20200414144707425.png) 4. Press F12 (on Chrome, may vary on other browsers). 5. Click on the first button and select the light-blue part in the app. ![Select Item button - F12](assets/image-20200325132528604.png) 6. It will bring the DOM explorer to a `code` node. The `PrismJsView` should be right below after opening it. ![Html Explorer](assets/image-20200325132859849.png) The `code` control is there! 👌 The project is now ready to integrate PrismJS. ### 3. Add JavaScript & CSS files 🎯 In this section, PrismJS files are downloaded from their website and placed as assets in the app. 1. Go to [Prism download page](https://prismjs.com/download.html). 2. Choose desired Themes & Languages (`Default` theme + all languages is used for the demo). 3. Press the `DOWNLOAD JS` button and put the `prism.js` file in the `WasmScripts` folder of the `.Wasm` project. > Putting the `.js` file in this folder will instruct the Uno Wasm Bootstrapper to automatically load the JavaScript file during startup. 4. Press the `DOWNLOAD CSS` button and put the `prism.css` file in the `WasmCSS` folder of the `.Wasm` project. > Putting the `.css` file in this folder will instruct the Uno Wasm Bootstrapper to automatically inject a `` HTML instruction in the resulting `index.html` file to load it with the browser. 5. Right-click on the `.Wasm` project node in the Solution Explorer, and pick `Edit Project File` (it can also work by just selecting the project, if the `Preview Selected Item` option is activated). 6. Insert this in the appropriate ``: ```xml ``` > For the Uno Wasm Bootstrapper to take those files automatically and load them with the application, they have to be put as embedded resources. A future version of Uno may remove this requirement. 7. Compile & run 8. Once loaded, press F12 and go into the `Sources` tab. Both `prism.js` & `prism.css` files should be loaded this time. ![Prism Loaded in browser](assets/image-20200414143931953.png) ### 4. Invoke JavaScript from Managed Code 🎯 In this section, PrismJS is used from the app. 1. First, there is a requirement for _PrismJS_ to set the `white-space` style at a specific value, as [documented here](https://github.com/PrismJS/prism/issues/1237#issuecomment-369846817). An easy way to do this is to set in directly in the constructor like this: ```csharp public PrismJsView() { _element = BrowserHtmlElement.CreateHtmlElement("code"); Content = _element; // This is required to set to style for PrismJS to works well // https://github.com/PrismJS/prism/issues/1237#issuecomment-369846817 _element.SetCssStyle("white-space", "pre-wrap"); } ``` 2. Now, we need to create an `UpdateDisplay()` method, used to generate HTML each time there's a new version to update. Here's the code for the method to add in the `PrismJsView` class: ```csharp private void UpdateDisplay(string oldLanguage = null, string newLanguage = null) { string javascript = $$""" (function(){ // Prepare Prism parameters const code = "{{BrowserHtmlElement.EscapeJs(Code)}}"; const oldLanguageCss = "language-{{BrowserHtmlElement.EscapeJs(oldLanguage)}}"; const newLanguageCss = "language-{{BrowserHtmlElement.EscapeJs(newLanguage)}}"; const language = "{{BrowserHtmlElement.EscapeJs(newLanguage ?? Lang)}}"; // Process code to get highlighted HTML const prism = window.Prism; let html = code; if(prism.languages[language]) { // When the specified language is supported by PrismJS... html = prism.highlight(code, prism.languages[language], language); } // Display result element.innerHTML = html; // Set CSS classes, when required if(oldLanguageCss) { element.classList.remove(oldLanguageCss); } if(newLanguageCss) { element.classList.add(newLanguageCss); } })(); """; _element.ExecuteJavascript(javascript); } ``` 3. Change `CodeChanged()` and `LangChanged()` to call the new `UpdateDisplay()` method: ```csharp private static void CodeChanged(DependencyObject dependencyobject, DependencyPropertyChangedEventArgs args) { (dependencyobject as PrismJsView)?.UpdateDisplay(); } private static void LangChanged(DependencyObject dependencyobject, DependencyPropertyChangedEventArgs args) { (dependencyobject as PrismJsView)?.UpdateDisplay(args.OldValue as string, args.NewValue as string); } ``` 4. We also need to update the result when the control is loaded in the DOM. So we need to change the constructor again like this: ```csharp public PrismJsView() { // This is required to set to style for PrismJS to works well // https://github.com/PrismJS/prism/issues/1237#issuecomment-369846817 _element.SetCssStyle("white-space", "pre-wrap"); // Update the display when the element is loaded in the DOM Loaded += (snd, evt) => UpdateDisplay(newLanguage: Lang); } ``` 5. Compile & run. It should work like this: ![Final browser result](assets/image-20200415135422628.png) ## 🔬 Going further This sample is a very simple integration as there is no _callback_ from HTML to managed code and _PrismJS_ is a self-contained framework (it does not download any other JavaScript dependencies). Some additional improvements can be done to make the code more production ready: * **Make the control multi-platform**. Another would be to use a [WebView](xref:Uno.Controls.WebView2) on other platforms, giving the exact same text-rendering framework everywhere. The code of this sample won't run on non-WebAssembly targets. * **Use script files instead of using `ExecuteJavascript`**. That would have the advantage of improving performance and making it easier to debug the code. * **Support more PrismJS features**. There are many [_plugins_ for PrismJS](https://prismjs.com/#plugins) that can be used. Most of them are very easy to implement. * [Continue with Part 3](xref:Uno.Interop.WasmJavaScript3) - an integration of a more complex library with callbacks to application. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/interop/wasm-javascript-3.md --- uid: Uno.Interop.WasmJavaScript3 --- # Embedding Existing JavaScript Components Into Uno-WASM - Part 3 In the previous article, we used a simple _syntax highlighter_ to enhance the display of text in HTML. It may not be enough for some apps: it's often required for JavaScript components to call back into the C# side of the application. The easiest way to do that in Uno for WebAssembly is by using [_DOM Events_](https://developer.mozilla.org/docs/Web/Guide/Events/Creating_and_triggering_events). Uno Platform apps can [consume DOM Events](xref:Uno.Interop.WasmJavaScript1l) very easily. Let's create an application using this feature. ## Integration of Flatpickr - Callback to app from JavaScript 📝 [Flatpickr](https://flatpickr.js.org/) is a lightweight, self-contained date and time picker. It is an easy way to explore how JavaScript-side code can call back to the managed application using a `CustomEvent`. In this case, this will be used to report when the picker is opened and a date and time was picked. ### 0. Before starting 📝 To reproduce the code in this article, you must [prepare a development environment using Uno's _Getting Started_ article](xref:Uno.GetStarted). ### 1. Create the solution in Visual Studio 📝 This part is very short because it is similar to the previous article ([part 2](wasm-javascript-2.md)): 1. Create a `Uno Platform App` project and name it `FlatpickrDemo`. 1. Compile & Run to make sure everything works. ### 2. Inject Flatpickr from CDN 🎯 This section is using a CDN to get Flatpickr instead of hosting the JavaScript directly in the application. It is not always the best solution as it creates a dependency on the Internet availability. Any change made server-side could break the application. An easy way to achieve this is to add JavaScript code to load the CSS file directly from the CDN. The JavaScript portion of Flatpickr will be lazy-loaded with the control later. Create a new _JavaScript_ file `flatpickrloader.js` in the `Platforms/WebAssembly/WasmScripts` folder of the project: ```javascript (function () { const head = document.getElementsByTagName("head")[0]; // Load Flatpickr CSS from CDN const link = document.createElement("link"); link.rel = "stylesheet"; link.href = "https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css"; head.appendChild(link); })(); ``` This will load the Flatpickr assets directly from CDN. ### 3. Uno controls and XAML 🎯 This section is creating a control used in the XAML. It will activate `Flatpickr` on the control's `` element. 1. Create a `FlatpickrView.cs` class in the `[MyApp]` project like this: ```csharp using Uno.UI.NativeElementHosting; namespace FlatpickrDemo; public class FlatpickrView : ContentControl { private BrowserHtmlElement? _element; // ************************* // * Dependency Properties * // ************************* public static readonly DependencyProperty SelectedDateTimeProperty = DependencyProperty.Register( nameof(SelectedDateTime), typeof(DateTimeOffset?), typeof(FlatpickrView), new PropertyMetadata(default(DateTimeOffset?))); public DateTimeOffset? SelectedDateTime { get => (DateTimeOffset)GetValue(SelectedDateTimeProperty); set => SetValue(SelectedDateTimeProperty, value); } public static readonly DependencyProperty IsPickerOpenedProperty = DependencyProperty.Register( nameof(IsPickerOpened), typeof(bool), typeof(FlatpickrView), new PropertyMetadata(false)); public bool IsPickerOpened { get => (bool)GetValue(IsPickerOpenedProperty); set => SetValue(IsPickerOpenedProperty, value); } // *************** // * Constructor * // *************** public FlatpickrView() { if (OperatingSystem.IsBrowser()) { _element = BrowserHtmlElement.CreateHtmlElement("input"); Content = _element; } else { Content = "Only supported on WebAssembly"; } // Load Flatpickr using JavaScript LoadJavaScript(); } // ****************** // * Initialization * // ****************** private void LoadJavaScript() { // For demo purposes, Flatpickr is loaded directly from CDN. // Uno Platform uses AMD module loading, so you must give a callback when the resource is loaded. // We can access the corresponding DOM HTML Element by using the "element" variable available in the scope var javascript = $@"require([""https://cdn.jsdelivr.net/npm/flatpickr""], f => f(element));"; _element?.ExecuteJavascript(javascript); } // ****************** // * Event Handlers * // ****************** } ``` 2. Change the `MainPage.xaml` in the `[MyApp]` project like this: ```xml Is Picker opened: Picked Date/Time: Flatpickr control: ``` 3. After pressing CTRL-F5, after clicking on the `` rectangle, this should appear: ![Calendar picker 1](assets/image-20200415144159362.png) 📝 Almost there, still need to _call back_ to the managed code portion of the application. ### 4. Add a way to call managed code from JavaScript 🎯 This section will use `CustomEvent` to route Flatpickr's events to managed code. 1. Register event handlers for 2 custom events: `DateChanged` and `OpenedStateChanged`. To achieve this, put this code at the end of the `FlatpickrView` constructor: ```csharp // Register event handler for events from the DOM _element.RegisterHtmlEventHandler("DateChanged", OnDateChanged); _element.RegisterHtmlEventHandler("OpenedStateChanged", OnOpenedStateChanged); ``` 2. Add the implementation for the two handlers in the class: ```csharp private void OnDateChanged(object sender, JSObject e) { if (DateTimeOffset.TryParse(e.GetPropertyAsString("detail"), DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeLocal, out var dto)) { SelectedDateTime = dto; } } private void OnOpenedStateChanged(object sender, JSObject e) { switch (e.GetPropertyAsString("detail")) { case "open": IsPickerOpened = true; break; case "closed": IsPickerOpened = false; break; } } ``` 3. Change the initialization of `Flatpickr` in injected JavaScript to raise events. Change the implementation of the `OnLoaded` method to this instead: ```csharp private void LoadJavaScript() { // For demo purposes, Flatpickr is loaded directly from CDN. // Uno uses AMD module loading, so you must give a callback when the resource is loaded. // We can access the corresponding DOM HTML Element by using the "element" variable available in the scope var javascript = $@"require([""https://cdn.jsdelivr.net/npm/flatpickr""], f => {{ // Route Flatpickr events following Uno's documentation // https://platform.uno/docs/articles/wasm-custom-events.html const options = {{ onChange: (dates, str) => element.dispatchEvent(new CustomEvent(""DateChanged"", {{detail: str}})), onOpen: () => element.dispatchEvent(new CustomEvent(""OpenedStateChanged"", {{detail: ""open""}})), onClose: () => element.dispatchEvent(new CustomEvent(""OpenedStateChanged"", {{detail: ""closed""}})) }}; // Instantiate Flatpickr on the element f(element, options); }});"; this.ExecuteJavascript(javascript); } ``` 4. Compile & Run. Here's the result: ![Final result](assets/flatpickr-final.gif) ### Troubleshooting If your JavaScript integration is not behaving properly, you can troubleshoot with hints below. #### My JavaScript control does not accept pointer input When using the WebAssembly Native renderer, in the constructor of your wrapper control, add the following: ```csharp // XAML behavior: a non-null background is required on an element to be "visible to pointers". // Uno reproduces this behavior, so we must set it here even if we're not using the background. // Not doing this will lead to a `pointer-events: none` CSS style on the control. Background = new SolidColorBrush(Colors.Transparent); ``` #### `TextBlock` content is not visible in browsers with the dark theme `TextBlock` defaults the text color as White correctly but `Page` background needs to be set correctly. ```xml ``` ## 🔬 Going further This article illustrates how to integrate external assets (JavaScript and css files) and how to leverage JavaScript's `CustomEvent` in an Uno application. More steps could be done to make the code production ready: * **Make the control multi-platform**. Many date/time pickers exist on all platforms. It should be easy on other platforms to connect the same control to another great date picker native to the platform - no need to embed a WebView for this on other platforms. * **Create script files instead of generating dynamic JavaScript**. As in previous article, this would have the advantage of improving performance and increase the ability to debug it. * **Support more Flatpickr features**. There are a [lot of features in Flatpickr](https://flatpickr.js.org/examples/) you can leverage to make a perfect versatile control. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/uno-development/ways-to-contribute.md --- uid: Uno.Contributing.WaysToContribute --- # Ways to contribute to Uno Platform There are lots of ways to contribute to the Uno Platform, and all of them are appreciated. You can provide feedback, report bugs, give suggestions, contribute code, and share your Uno expertise with others. ## Provide feedback The Uno Platform is an ongoing effort. Bug reports and feature requests are important for prioritizing where that effort goes, and identifying the most pressing user needs. Your feedback is important to us - we want to hear about your experience, scenarios, and requirements. ### Report a bug by opening an issue If you think you've found a bug, the first thing to do is [search the existing issues](https://github.com/unoplatform/Uno/issues?q=is%3Aissue+is%3Aopen+label%3Akind%2Fbug) to check if it's already been reported. If it has been opened, provide additional commentary so we know more users are being affected. The best way to get your bug fixed is to be as detailed as you can be about the problem. **Providing a minimal project, stripped off as much code as possible, with steps to reproduce the problem (typed or screen-capture) is ideal.** Here are questions you can consider before you file a bug to make sure you're not missing any important information. The bug submission template will also ask for this information. Pre-Submission check: 1. Did you read the [documentation](https://platform.uno/docs/articles/intro.html)? 2. Did you check the latest [pre-release](https://www.nuget.org/packages/Uno.UI/absoluteLatest) of Uno Platform to see if the issue has been fixed? 3. Does the issue exist on the WinUI project (in which case it is not an Uno Platform issue) Issue Filing [via logging a new bug report](https://github.com/unoplatform/uno/issues/new?labels=kind%2Fbug%2C+triage%2Funtriaged&template=bug-report.md).: 1. Did you include the snippet of the broken code in the issue? 2. What are the *EXACT* steps to reproduce this problem? 3. What specific Uno Platform version or build are you using? 4. What operating system are you using? 5. What platform(s) are you targeting that are experiencing the issue? Is it working on some platform(s) and not on others. 6. What IDE and version are you using? [Log a new bug report](https://github.com/unoplatform/uno/issues/new?labels=kind%2Fbug%2C+triage%2Funtriaged&template=bug-report.md) GitHub supports [Markdown](https://help.github.com/articles/github-flavored-markdown/), so when filing issues, be sure to check the formatting in the 'Preview' tab before hitting submit. ### Request a feature If you need a [WinUI feature](https://learn.microsoft.com/uwp/api/microsoft.ui.xaml.controls) that Uno Platform doesn't support yet, you should [submit a feature request](https://github.com/unoplatform/uno/issues/new?labels=kind%2Fenhancement%2C+triage%2Funtriaged&template=enhancement.md). Check [existing issues first](https://github.com/unoplatform/uno/issues?q=is%3Aissue+is%3Aopen+label%3Akind%2Fenhancement) in case the same feature request already exists (in which case you can upvote the existing issue). To help us understand and prioritize your request, please provide as much detail as possible about your scenario and why the feature or enhancement would be useful. Wherever we can, we prefer to implement WinUI APIs for maximum cross-platform compatibility and existing code support, but for features/functionality not covered by WinUI's API, the same feature request process applies. ### Ask (and answer) questions If you have a question, be sure first to check out our [documentation](https://platform.uno/docs/articles/intro.html). But if you are still stuck, please visit [GitHub Discussions](https://github.com/unoplatform/uno/discussions) where our engineering team and community will be able to help you. If you've already done some Uno development, maybe there's a GitHub discussion question you can answer, giving another user the benefit of your experience. For a more direct conversation, [visit our Discord Server](https://platform.uno/discord). ### Spreading the word We love to see the community grow, and whether you're trying Uno for the first time or you're an old pro, it's great to share whatever you've learnt. You can: - write a blog post - present Uno at a local user group - share your open-source Uno projects Whatever you do, let us know [through X/Twitter](https://x.com/unoplatform), our [Discord Server](https://platform.uno/discord) in #contributing, or by emailing us at [info@platform.uno](mailto:info@platform.uno). ## Contributing code The WinUI framework is pretty big, but many hands make light work. We welcome code and content contributions from the community, and the core team is more than happy to help new contributors ramp up and familiarize themselves with Uno Platform's codebase. ### Diving into the code The [contributor's guide](contributing-intro.md) has plenty of resources to help you get up and running with Uno's code, including a [guide to building and debugging Uno.UI](debugging-uno-ui.md), and a [guide to Uno's internals](uno-internals-overview.md). ### Finding an issue to work on Not sure what to work on? Take a look through the currently open [good first issues](https://github.com/unoplatform/Uno/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) - these are all issues that have been identified by the core team as suitable for new contributors, with a well-defined scope and a relatively gentle learning curve. Maybe you have something in mind to work on already. That's great! Make sure there's an [opened issue](https://github.com/unoplatform/Uno/issues) for it, either by creating it yourself or searching for an existing report, as described above. In either case, once you're ready, leave a comment on the issue indicating that you'd like to work on it. A member of the core team will assign the issue to you, so as to make sure no one inadvertently duplicates your work (and you're not duplicating someone else's). ### Getting down to work The [contributor's guide](contributing-intro.md) has the information you need. The most important points are: - Work in [your own fork of Uno](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) - Be sure to use the [Conventional Commits format](git-conventional-commits.md) - Once you're done, you'll probably need to [add a test](../contributing/guidelines/creating-tests.md) ### Creating a PR Once you're ready to create a PR, check out the [Guidelines for pull requests](../contributing/guidelines/pull-requests.md) in Uno. ### Need help? If there's anything you need, [ping us on our Discord Server](https://platform.uno/discord). ## Sponsors & Grants Please consider sponsoring Uno Platform development, especially if your company benefits from this library. Your contribution will go towards adding new features and closing issues raised by the community at Uno Platform backlog on GitHub ([Issues · unoplatform/uno (github.com)](https://github.com/unoplatform/uno/issues)) and making sure all functionality continues to meet our high-quality standards. A grant for continuous full-time development has the biggest impact on progress. Periods of 2 to 5 days allow a contributor to tackle substantial complex issues that are otherwise left to linger until somebody can’t afford to not fix them. Contact [@jlaban](https://github.com/jeromelaban) or [@sasakrsmanovic](https://github.com/sasakrsmanovic) to arrange a grant to Uno Platform and its core contributors. --- # Source: https://raw.githubusercontent.com/unoplatform/uno/refs/heads/master/doc/articles/features/web-authentication-broker.md --- uid: Uno.Features.WAB --- # Web Authentication Broker * The timeout is set by default to 5 minutes. You can change it using `WinRTFeatureConfiguration.WebAuthenticationBroker.AuthenticationTimeout`. ## Usage on WebAssembly * The *redirect URI* **MUST** be with the origin (protocol + hostname + port) of the application. It is not possible to use a custom scheme URI. * When using the `