askill
uno-csharp-markup

uno-csharp-markupSafety 90Repository

C# Markup for Uno Platform: code-first UI with fluent API, strongly-typed data binding, resources, styles, templates, and Uno Toolkit integration. Use when: (1) Building UI in C# instead of XAML, (2) Using fluent data binding with expression trees, (3) Applying styles and templates in C# Markup, (4) Integrating Uno Toolkit controls in C# Markup, (5) Setting up a C# Markup project from scratch

3 stars
1.2k downloads
Updated 2/2/2026

Package Files

Loading files...
SKILL.md

Uno Platform C# Markup

Declarative, fluent-style C# syntax for building Uno Platform UIs. Same underlying object model as XAML with compile-time validation, IntelliSense, and refactoring support.

Setup

Select C# Markup in the project template:

dotnet new unoapp -markup csharp

Add CSharpMarkup to UnoFeatures for existing projects:

<UnoFeatures>
    CSharpMarkup;
    Material;
    Toolkit;
</UnoFeatures>

Pages use .cs files instead of .xaml + .xaml.cs pairs.

Core Patterns

Creating Controls and Setting Properties

Fluent API chains property setters. Type conversion is automatic for common types (Thickness, Brush, Color, CornerRadius, FontFamily).

new TextBlock()
    .Margin(12)                              // auto-converts int to Thickness
    .TextAlignment(TextAlignment.Center)     // strongly typed enum
    .Text("Hello Uno Platform!")

Children and Content

new StackPanel()
    .VerticalAlignment(VerticalAlignment.Center)
    .HorizontalAlignment(HorizontalAlignment.Center)
    .Children(
        new TextBlock().Text("First"),
        new TextBlock().Text("Second"),
        new Button().Content("Click me")
    )

DataContext and Binding

Use expression trees for strongly-typed binding. The vm parameter is a placeholder, not a live reference.

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.DataContext(new MainViewModel(), (page, vm) => page
            .Background(ThemeResource.Get<Brush>("ApplicationPageBackgroundThemeBrush"))
            .Content(
                new StackPanel()
                    .VerticalAlignment(VerticalAlignment.Center)
                    .Children(
                        new TextBlock()
                            .Text(() => vm.Count, count => $"Counter: {count}"),
                        new TextBox()
                            .Text(x => x.Bind(() => vm.Step).TwoWay()),
                        new Button()
                            .Command(() => vm.IncrementCommand)
                            .Content("Increment")
                    )
            )
        );
    }
}

Binding modes:

  • Default (OneWay): () => vm.Property
  • TwoWay: .Text(x => x.Bind(() => vm.Property).TwoWay())
  • OneTime: .Text(x => x.Bind(() => vm.Property).OneTime())

Without ViewModel instance (type-only):

this.DataContext<MainViewModel>((page, vm) => page
    .Content(...)
);

Resources

Access theme and static resources with strongly-typed API:

// Theme resource
this.Background(ThemeResource.Get<Brush>("ApplicationPageBackgroundThemeBrush"));

// Static resource
new TextBlock()
    .Style(StaticResource.Get<Style>("TitleLarge"));

Styles

new TextBlock()
    .Style(new Style<TextBlock>()
        .Setters(s => s
            .Foreground(ThemeResource.Get<Brush>("OnSurfaceBrush"))
            .FontSize(24)
        )
    )

Templates

new ListView()
    .ItemsSource(() => vm.Items)
    .ItemTemplate<MyItem>(item =>
        new StackPanel()
            .Orientation(Orientation.Horizontal)
            .Children(
                new TextBlock().Text(() => item.Name),
                new TextBlock().Text(() => item.Description)
            )
    )

Uno Toolkit in C# Markup

Toolkit controls work with the same fluent API:

using Uno.Toolkit.UI;

new AutoLayout()
    .Spacing(16)
    .Padding(24)
    .PrimaryAxisAlignment(AutoLayoutAlignment.Center)
    .Children(
        new NavigationBar().Content("Page Title"),
        new SafeArea()
            .Insets(SafeArea.InsetMask.Top | SafeArea.InsetMask.Bottom)
            .Child(
                new TextBlock().Text("Safe content")
            )
    )

ResponsiveExtension in C# Markup

Responsive values require XAML-style markup extensions. In C# Markup, use adaptive logic or VisualStateManager instead:

// Use VisualStateManager for responsive layouts in C# Markup
new Grid()
    .VisualStateManager(vsm => vsm
        .Group(g => g.Name("WidthStates")
            .State(s => s.Name("Narrow")
                .StateTriggers(new AdaptiveTrigger() { MinWindowWidth = 0 })
                .Setters(/* narrow layout */)
            )
            .State(s => s.Name("Wide")
                .StateTriggers(new AdaptiveTrigger() { MinWindowWidth = 800 })
                .Setters(/* wide layout */)
            )
        )
    )

MVUX with C# Markup

C# Markup pairs naturally with MVUX models. Bind directly to Feed/State properties:

this.DataContext<MainModel>((page, vm) => page
    .Content(
        new FeedView()
            .Source(() => vm.Items)
            .DataTemplate<ItemViewModel>(item =>
                new TextBlock().Text(() => item.Name)
            )
    )
);

Common Mistakes

  • Using string-based {Binding} syntax instead of expression-tree bindings
  • Forgetting that vm is a placeholder, not a live object (don't call methods on it outside binding expressions)
  • Setting DataContext in code-behind AND in the fluent chain (double initialization)
  • Not adding CSharpMarkup to UnoFeatures (extension methods won't be generated)
  • Mixing XAML and C# Markup in the same page (use one or the other per page)

Key Differences from XAML

XAMLC# Markup
{x:Bind Path}() => vm.Path
{Binding Path, Mode=TwoWay}x => x.Bind(() => vm.Path).TwoWay()
{StaticResource Key}StaticResource.Get<T>("Key")
{ThemeResource Key}ThemeResource.Get<T>("Key")
x:Uid="MyPage.Title"Set programmatically or use attached properties
.xaml + .xaml.csSingle .cs file

Limitations

  • Hot Design only supports XAML markup files (not C# Markup) at this time
  • XAML-only markup extensions ({utu:Responsive}) need alternative patterns in C# Markup
  • Localization with x:Uid requires manual string loading via ResourceLoader

Detailed References

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

96/100Analyzed 2/11/2026

An excellent, comprehensive guide for Uno Platform C# Markup with clear setup steps, code examples, and troubleshooting tips.

90
95
90
98
95

Metadata

Licenseunknown
Version-
Updated2/2/2026
Publishermtmattei

Tags

api