Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork45
Concise, declarative C# UI markup for .NET browser / native UI frameworks
License
VincentH-Net/CSharpForMarkup
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Concise next-gen C# Markup for .NET UI frameworks
C# Markup 2 supports multiple UI frameworks, including theexcellentUno Platform.
If you don't know Uno, I recommend you check them out; Uno is one of the best and most mature .NET UI frameworks, it offers an impressive breadth of features that will have your back when you need to create real-world production apps end2end,fast.
dotnet new install Uno.Templatesdotnet new install Modern.CSharp.Templatesmd UnoCSharpMarkup2cd UnoCSharpMarkup2dotnet new unoapp -preset recommendeddotnet new mcs-uno-markup2 --presentation mvux --renderer skia --allow-scripts yes
Uno Platform supports both XAML and C# UI withUno C# Markup. C# Markup 2 adds another option that goes above and beyond what gen-1 C# Markup variants offer.
It's good to have options - everyone wins: devs get the experience that they like best, and the UI framework gains more adoption. Check it out and pick what you like!
As a first impression, here's a quick side-by-side comparison:
Enjoy a Flutter-like UI development experience with C# Markup 2:
- Build.NET applications fully in C#
- Unclutter your markup - while readingand writing.
- C# Markup2 goes above and beyond gen 1 C# Markup approaches (e.g.Maui orUno) to eliminate a lot of verbosity: no more endless repetitions of
new,HorizontalAlignment = HorizontalAlignment.Center,() =>ornameof(), no more specifying for each and everyTextBlockbinding that yes, you want to bind to theTextproperty... - Separated markup namespaces eliminate intellisense pollution, allow quick discovery and encourage clean separation of markup and logic: no more intellisense lists where you have to search in a sea of irrelevant options for the few that you are interested in. See only Markup API's while editing
MyPage.cs, see UI framework and other API's while editingMyPage.logic.cs.
- C# Markup2 goes above and beyond gen 1 C# Markup approaches (e.g.Maui orUno) to eliminate a lot of verbosity: no more endless repetitions of
- Target browsers and native desktop / mobile
- Use existing UI frameworks. Mature or bleeding edge isyour choice: WPF, WinUI 3 for Windows App SDK and Uno Platform. Coming: AvaloniaUI, Maui, possibly Blazor.
- Use the built-in MVVM support - or any other update model that supports your UI framework (e.g.Uno's MVUX orReactiveUI)
- Use for part or all of your application UI
- Designed to handle large UI fast: practically allocation-free, no reflection, efficient C#
No XAML / HTML / JavaScript / CSS required. No engine or layers to get in your way.
Chat (if needed,join DotNetEvolution first)
The best place to ask questions or help!
- Uno Platform / WinUI 3:Getting started with C# Markup 2 for WinUI 3 and Windows App SDK / Uno Platform
- WPF:Getting started with C# Markup 2 for WPF
Looking for C# Markup 1? Find ithere
July 14, 2025
Mapsui 5 - currently in beta, and one of the best OSS .NET libraries for maps - now has full support in C# Markup 3.1 for Uno Platform 6.0!
Anexample page using Mapsui is added to the example app in this repo, demonstrating how to use Mapsui with C# Markup 2.BrowseLive Mapsui 5.0 samples to experience the possibilities; see thesamples source for how.
July 4, 2025
ScottPlot.NET - one of the best OSS .NET libraries for graphs and charts - now has full support in C# Markup 3.1 for Uno Platform 6.0!
Anexample page using ScottPlot is added to the example app in this repo, demonstrating how to use ScottPlot with C# Markup 2.Use the excellentScottPlot 5.0 Cookbook to create beautiful graphs!
May 12, 2025
Hot on the heels of the game-changingUno 6.0 release, today's release adds full support for Uno SDK 6.0 / Windows App SDK 1.7 to all CSharpMarkup.WinUI NuGets.
Includes support for all API improvements in Uno SDK 6.0:
- 20+ WinUI API's are no longer marked unsupported
- Add support for ellipse shape to
ProgressBarTemplateSettings - New
TitleBarsupport, including strongly-typed access to all newTitlebarresources inThemeResource - New
TextBoxExtensionsallow to specifyInputReturnType
The example app in the repo is also updated to Uno 6.0 / Windows App SDK 1.7.
May 5, 2025
Today's release adds full support for Uno SDK 5.6 / Windows App SDK 1.6 and .NET 9 / .NET 8 to all CSharpMarkup.WinUI NuGets.
Includes support for all improvements in Uno SDK 5.6:
- 80+ WinUI API's are no longer marked unsupported
- new
ScrollPresenterAutomationPeer,FauxGradientBorderPresenter - new
NewFrameworkTemplateBuildersupport
The example app in the repo is also updated to .NET 9 plus Uno 5.6 / Windows App SDK 1.6 and demonstrates how to use C# partial properties with MVVM Community Toolkit to support AOT.
May 7, 2024
Today's release is fully updated to Updated to Uno 5.2 including Uno's.NET Single Project anduno.sdk!
Plus:
- Added support for latest
dotnet new unoapptemplate - Updated to Uno.Extensions.* 4.1
- Updated to Microsoft.WindowsAppSDK 1.5
Dec 21, 2023
In addition to some new C# Markup 2 methods, today's release adds support for the newC# Markup 2 templates for Uno Platform 5: an updatedmcs-uno-markup2 template, and a newmcs-uno-view template.
- Enjoy improved frictionless startup for both existing and new Uno solutions - whether created with Uno's
dotnet new unoapptemplate or with the Uno solution wizard for Visual Studio - Full support for .NET 8 / .NET 7, as well as model types MVUX / MVVM / none
- The new
mcs-uno-viewtemplate is used by the convenientNew-View.ps1script, which is included inmcs-uno-markup2 - Templates are now pre-structured in accordance with best practices for maintainability and code reuse of C# Markup 2 UI.
Nov 18, 2023
This release is fully updated to the awesomeUno 5 release and .NET 8 GA. You can use theUno Solution Wizard for Visual Studio and add a C# Markup 2 project to it at any time with one command. All Uno wizard customizations are supported: combine C# Markup 2 with MVUX or MVVM, XAML or Uno C# Markup, use Uno Navigation extensions, and target .NET 8 or .NET 7. All Uno target platforms are supported.
A brand new dotnet new C# Markup 2 project template gets you going in no time - carefully optimized for an optimal developer experience: uncluttered solution explorer view, automatic file grouping of markup and logic files, uncluttered markup source, focused intellisense, clear starting points for markup extensions in your code, plus fast hot reload - both automatic and with a hot reload button overlay in debug mode, for the platforms that your IDE can hot reload but cannot (yet) update the UI automatically.
Enjoy general C# Markup 2 improvements, plus C# Markup 2 API's for 5 additional Uno libraries:
- Support for Uno'sUI Toolkit,Reactive / MVUX extension andNavigation extensions
- Support for the awesomeLiveCharts2
- All
ThemeResources searchable in C# intellisense, strongly typed
Thegetting started is fully up to date. Examples in this repo and this readme will be updated soon to show off the new features.
NJoyconcise C# Markup!
Nov 1, 2023
Enjoy general C# Markup 2 improvements, plus C# Markup 2 API's for 5 additional Uno libraries:
- Support for Uno's UI toolkit, Reactive and Navigation extensions
- Support for the awesomeLiveCharts2
- All
ThemeResources searchable in C# intellisense, strongly typed - Automatic UI update on C# hot reload
- A development tools overlay
You can try this today - see the NuGets listed above.Documentation of the new features plus a new getting started guide is coming with thenext release - soon!
June 27, 2023
- Release 2.2 is out! Enjoy this polished release for Windows App SDK, Uno Platform and WPF.
- As the poll results indicated, C# Markup 2 support for.NET MAUI is most wanted.
Implementationhas started!
March 25, 2023
The March 2023 poll results on what to build next for C# Markup 2 are in!
A surprise addition was the ask for C# Markup 2 for Avalonia UI in the replies; it got a big response that catapulted it into a very close 2nd place.
Here are the results for thepoll including the likes for "Other" optionsBlazor andAvaloniaUI:
And the winner is:C# Markup 2 for MAUI!
Watch and star this repo to catch the release; you can also watch#CSharpForMarkup tweets for progress. Thanks for your response!
Feb 28, 2023
C# Markup 2 version 2.0 for WinUI 3 is here! Completely updated to .NET 7, C# 11 and the latest Windows App SDK and Uno Platform.With many improvements including 6 supported target platforms, C# hot reload support anddotnet new project templates.
Brought to you by Applicita
Special thanks go toApplicita for making this release possible; it's inspiring to see a company support OSS in this way (Applicita also open-sourced severalother useful libraries)
More on what's new in this releasehere.
Feb 16, 2023
Updated to .NET 7, C# 11 and the latest Windows App SDK and Uno Platform. With many improvements - including C# hot reload support and a dotnet new project template.Watch this space!
April 14, 2022
Seehere andhere for the full list of improvements
February 15, 2022
Seehere for the full list of improvements
November 30, 2021
This first preview targets WinUI 3 and Uno Platform - including browser webassembly - with C# 10 and .NET 6. It supports .NET Hot Reload for a fast inner dev loop.
- Clone this repo
- OpenCSharpMarkup.Wpf.Examples.sln and explore the source for the example pages. Note how page markup and page logic are separated in partial class files, and integrated with
Build(),Assign()andInvoke(). - .NET Hot Reload is supported; edit and save the page markup in VS 2022 while debugging to see instant updates
- To learn how to use C# Markup 2, read thefeatures description below and experiment in the example app
- To build your own app, reference
from a .NET 6 WPF project and create the C# Markup UI windows, pages etc in that project. Note that for existing apps you can reference (WPF / class library) projects that target older .NET versions from the .NET 6 project, so you can add C# Markup UI to your app without having to migrate existing logic and/or WPF UI to .NET 6 and C# 10.
First check if your development environment is ready:
Either choose an existing Uno Platform 5.2 solution, or create a new one with theUno Platform Template Wizard or thedotnet new unoapp template. Feel free to select any options; C# Markup 2 fully supports Uno 5.2 with .NET 8 or .NET 7,MVUX or MVVM, XAML or Uno C# Markup, on all target platforms.
Install the latestModern.CSharp.Templates for
dotnet newto getthese templates for Windows App SDK, Uno Platform and moredotnet new install Modern.CSharp.Templates
To see help about the template parameters:
dotnet new mcs-uno-markup2 -h
Add a C# Markup 2 project to the Uno Platform solution, e.g.:
cd C:\Repos\UnoApp1dotnet new mcs-uno-markup2 --appRootNamespace InnoWvate.UnoApp1 --presentation mvux --renderer skia --allow-scripts YesThis will:
Add a new project
UnoApp1.Presentationto the solution, with a working example:- Pages
- Models of the specified type (in above exampleMVUX)
- Navigation
- A
New-View.ps1script to quickly add more pages and models - A
Readme.mdwith instructions on how to get started quickly
The Presentation project is pre-structured for maintainability in accordance with best practices for C# Markup UI
Add NuGet package references to the Presentation project
Add a reference to the Presentation project in the
UnoApp1project
Note that you can use the
--nameparameter ofdotnet newto specify the name of yourexisting Uno project, if that differs from the solution folder name (in above example,UnoApp1). The specified name will be used with the.Presentationsuffix for the new project as well.Open or reload the Uno solution and follow the steps in the
Readme.mdof the Presentation project to get started.
To learn how to use C# Markup 2, read thefeatures description below.
Fore a more complete example, see theexample app in this repo.
C# Markup 2 contains a full declarative, fluent API for existing UI frameworks. It surfaces virtually every layout, view and property, including attached properties, and includesfull inline documentation that links each markup helper / parameter to the inline documentation for the underlying UI object / property.
The rich UI frameworks that C# Markup 2 surfaces can contain as much as500+ UI object types. E.g. layouts, views and styles, but also brushes, rich text elements, drawing primitives, transformations, animations, visual states and more. In addition C# Markup offers powerful and conciseconvenience API's for layout, bindings, convertors, templates and more.
- When targetingWindows Desktop, the WinUI API from the Windows App SDK is surfaced (without any dependency on Uno Platform).
- When targetingUno Platform, the Uno.WinUI API is surfaced (atm only webassembly is tested, but any Uno target platform that can support .NET 6 and C# 10 should work)
- When targetingWPF, the WPF API is surfaced.
Layouts, views, properties and property values look like this:
All properties can be set with extension methods: properties defined on the view type or it's base types, as well as attached properties.
Properties that are defined directly on the view type can alternatively be set with named parameters:
This is mainly useful for properties that take primitive types.
Properties that take enum values have extension methods so the enum name does not have to be repeated
(as inTextAlignment: TextAlignment.Center):
Attached property names are prefixed with the defining type plus underscore:
You canset multiple attached property values for the same defining typein one call:
In addition to this, there areconvenience overloads for some view types with just the most commonly used parameters:
Implicit converters are provided in theto subnamespace for common property value types:
These are:
- All converters that accept
stringvalues, as specified by the UI framework with theTypeConverter attribute
Note that WinUI 3 Desktop does not use this attribute, but Uno Platform and WPF do. - Additional manual converters that also accept other types than
string, including tuples if more than one value is expected. E.g.:
Allows you to specify:Button() .CornerRadius (2.5)orButton() .CornerRadius ((2.5, 0, 2.5, 0))
An example usingto.Point:
Button().Background(RadialGradientBrush(Center:(50,50),GradientOrigin:(100,50)))
An example usingto.TimeSpan andto.Duration:
ColorAnimation(BeginTime:"0:0:5",Duration:2.5)
In many cases the inline documentation on theto. type describes the supported values and formatting; especially for strings this can avoid guesswork.
Styles can be assigned like this:
In WPF you can bind a style setter value (WinUI 3 does not support this):
ADataTemplate is passed in as aFunc<UIElement>:
AControlTemplate can be created like this:
- The
.BindTemplate()method lets you bind template properties to the templated parent - The
targetTypeparameter is optional bhere is a null-valuedstatic UI_Buttonfield. In this example it only serves to demonstrate one way to get intellisense when editing binding expressions for aButton; seeBinding power for details.
Here is how you can use aControlTemplate in an implicit or explicitStyle:
You can use enums instead of numbers for Grid rows and colums. This improves readability and saves you from manually renumbering rows and columns when adding/removing/reordering them
Shorthand helpers are included as an alternative to common combinations of markup helpers:
All layouts ignorenull values in theirchildren; this makes it possible to have conditional views depending on the value of an expression at page (re) build time.
TheSpread helper allows to insert a variable number of children at a specific position in thechildren list (similar to what Flutter offers).
Thanks to the C# 10CallerArgumentExpression attribute, you don't have to use strings ornameof() to specify binding pathswith good performance. Instead you can use C# expressions and enjoy all the goodness that they bring: full intellisense, compiler checked, renaming support :
Note from the intellisense description in above image that thepathExpression parameter supports severalconvenience binding syntaxes, which allows to:
- Identify the viewmodel part of the expression with parenthesis:
path expression =viewmodel.path||(viewmodel expression).path, wherepathcan contain.e.g.:.Bind (vm.SelectedTweet)binds to "SelectedTweet".Bind ((vm.SelectedTweet).Title)binds to "Title".Bind ((vm.SelectedTweet).Author.Name)binds to "Author.Name"
- Use
?with null-valued type instances to enjoy C# goodness without needing object instances e.g.:.Bind (vm?.SelectedTweet?.Title)binds to "Title"
Note that using?can be necessary because the expression will be evaluated at runtime, even though we don't care about it's value; theCallerArgumentExpression attribute supplies an expression stringin addition to the expression value.
- You can still pass in string literals
.Bind ("SelectedTweet")binds to "SelectedTweet"
Any surrounding",@ or whitespace characters inpathExpression are ignored
Bind supports almost all functionality that the UI framework offers for binding. In addition, there are manyBind overloads that allows to:
- Omit the property name to bind to thedefault property of a view type:

- Bind withinline conversion:

- Bind acommand and it's parameter in one go:

A typical markup page starts like this:
FlutterPage.cs:
usingCSharpMarkup.<UIframework name>;usingstaticCSharpMarkup.<UI framework name>.Helpers;namespaceExamples;partialclassFlutterPage{publicvoidBuild()=>Content=
Note the use ofpartial class; this lets you separate the UI markup fromUI logic:
FlutterPage.logic.cs:
using<UIframework namespace>.Controls;namespaceExamples;publicsealedpartialclassFlutterPage:Page,IBuild{readonlyFlutterViewModelvm;publicFlutterPage(){InitializeComponent();// Only needed for WinUIDataContext=vm=<obtain viewmodel instance>;Build();
IMPORTANT:
InC# markup files like
<page>.cs:
IncludeCSharpMarkup.*namespace usings butno UI objectmodel usings such asusing Microsoft.UI.Xaml;
(by design the type names in the CSharpMarkup namespace are identical to the type names in the UI objectmodel, so including both would cause ambiguities)
Try to limit using the UI object model to UI logic files. If you must, youcan use the UI objectmodel safely in C# markup files; a good practice then is todefine global namespace using aliases, e.g.global using UI = Microsoft.UI;
For more guidance, see the comments in theGlobalUsings.csof a project created withdotnet new mcs-uno-markup2.InUI logic files like
<page>.logic.cs:
Do not useCSharpMarkupobjects
Markup object instances are not safe to use outside of a markup expression (due to performance features - each markup object type has a single static instance to prevent allocating an extra object for each view).That is whyAssignandInvoke(seebelow) pass the UI object contained in the markup object to the logic, instead of the markup object itself.
WithAssign andInvoke you can integrate UI markup with UI logic:
Note:
InSearchPage.cs,StackPanelandTextBoxaremarkup object types, while
inSearchPage.logic.csthey are the correspondingUI framework object types
There is no C# Markup IDE extension (yet...) to properly colorize markup, however C# Markup readability can be improved with this workaround in Visual Studio options:
UnderFonts and Colors, copy the color ofUser Types - Classes toUser Members - Methods (with theCustom... button). Now the markup color for views and properties will no longer be the same.
About
Concise, declarative C# UI markup for .NET browser / native UI frameworks
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.












