https://github.com/wieslawsoltes/NXUI
NXUI (nex-ui), next-gen UI - Create minimal Avalonia applications using C# 10 and .NET 8
https://github.com/wieslawsoltes/NXUI
avalonia avaloniaui csharp dotnet minimal xaml
Last synced: 15 days ago
JSON representation
NXUI (nex-ui), next-gen UI - Create minimal Avalonia applications using C# 10 and .NET 8
- Host: GitHub
- URL: https://github.com/wieslawsoltes/NXUI
- Owner: wieslawsoltes
- License: mit
- Created: 2021-09-01T20:57:37.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-10-31T10:53:03.000Z (12 months ago)
- Last Synced: 2025-01-11T22:07:31.868Z (9 months ago)
- Topics: avalonia, avaloniaui, csharp, dotnet, minimal, xaml
- Language: C#
- Homepage:
- Size: 3.13 MB
- Stars: 152
- Watchers: 8
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
# NXUI (next-gen UI)
[](https://www.nuget.org/packages/NXUI)
[](https://www.nuget.org/packages/NXUI)Creating minimal [Avalonia](https://avaloniaui.net/) next generation (NXUI, next-gen UI) application using C# 10 and .NET 8
https://user-images.githubusercontent.com/2297442/132313187-32f18c4b-e894-46db-9a9d-9de02f30835e.mp4
# Requisites
### NXUI
```xml
```
Additionally, depending on the application type:
### Desktop
For Desktop extensions:
```xml```
or using plain Avalonia:
```xml```
### Browser
```xml
```
```
dotnet workload install wasm-tools
```# Usage
```csharp
Window Build() => Window().Content(Label().Content("NXUI"));AppBuilder.Configure()
.UsePlatformDetect()
.UseFluentTheme()
.StartWithClassicDesktopLifetime(Build, args);
``````csharp
var count = 0;Window Build()
=> Window(out var window)
.Title("NXUI").Width(400).Height(300)
.Content(
StackPanel()
.Children(
Button(out var button)
.Content("Welcome to Avalonia, please click me!"),
TextBox(out var tb1)
.Text("NXUI"),
TextBox()
.Text(window.BindTitle()),
Label()
.Content(button.ObserveOnClick().Select(_ => ++count).Select(x => $"You clicked {x} times."))))
.Title(tb1.ObserveText().Select(x => x?.ToUpper()));AppBuilder.Configure()
.UsePlatformDetect()
.UseFluentTheme()
.WithApplicationName("NXUI")
.StartWithClassicDesktopLifetime(Build, args);
```Minimalistic Desktop app:
```csharp
Run(
() => Window().Content(Label().Content("NXUI")),
"NXUI",
args,
ThemeVariant.Dark);
```# Generate
C#
```bash
cd src/Generator
dotnet run -- ../NXUI/Generated
```F#
```bash
cd src/Generator
dotnet run -- ../NXUI.FSharp/Generated -fsharp
```# dotnet run app.cs
Using .NET 10 you can run GUI apps using scripts: https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-app/#using-shebang-lines-for-shell-scripts
Note: You might need to adjust shebang line to `#!/usr/bin/dotnet run`
App.cs
```csharp
#!/usr/local/share/dotnet/dotnet run
#:package NXUI.Desktop@11.3.0
NXUI.Desktop.NXUI.Run(
() => Window().Content(Label().Content("NXUI")),
"NXUI",
args,
ThemeVariant.Dark,
ShutdownMode.OnLastWindowClose);
``````bash
chmod +x App.cs
./App.cs
```
More complex app:
```csharp
#!/usr/local/share/dotnet/dotnet run
#:package NXUI.Desktop@11.3.0var count = 0;
Window Build()
=> Window(out var window)
.Title("NXUI").Width(400).Height(300)
.Content(
StackPanel()
.Children(
Button(out var button)
.Content("Welcome to Avalonia, please click me!"),
TextBox(out var tb1)
.Text("NXUI"),
TextBox()
.Text(window.BindTitle()),
Label()
.Content(button.ObserveOnClick().Select(_ => ++count).Select(x => $"You clicked {x} times."))))
.Title(tb1.ObserveText().Select(x => x?.ToUpper()));AppBuilder.Configure()
.UsePlatformDetect()
.UseFluentTheme()
.WithApplicationName("NXUI")
.StartWithClassicDesktopLifetime(Build, args);
```
## F# Support
From F# 9.0 and above the compiler resolves [extension methods instead of instrinsic properties](https://github.com/dotnet/fsharp/pull/16032) so, there's no need for a separate F# package or any additional changes to your project files.
Extension methods provided by the main package `NXUI`
```fsharp
open Avalonia
open Avalonia.Controlsopen NXUI.Extensions
open NXUI.Desktop
open type NXUI.Builderslet Build () =
let mutable count = 0
let mutable window = Unchecked.defaultof
let mutable button = Unchecked.defaultof
let mutable tb1 = Unchecked.defaultofWindow(window)
.Title("NXUI")
.Width(400)
.Height(300)
.Content(
StackPanel()
.Children(
Button(button).Content("Welcome to Avalonia, please click me!"),
TextBox(tb1).Text("NXUI"),
TextBox().Text(window.BindTitle()),
Label()
.Content(
button.ObserveOnClick()
|> Observable.map (fun _ ->
count <- count + 1
count)
|> Observable.map (fun x -> $"You clicked {x} times.")
|> _.ToBinding()
)
)
)
.Title(tb1.ObserveText())[]
let Main argv = NXUI.Run(Build, "NXUI", argv)
```> ### F# 8.0 Support
>
> The compiler feature is available in the .NET9 SDK and above so even if you target a lower dotnet version you don't need to change your project files.
>
> However, if you must to use the .NET8 SDK you only need to set the language version to preview
> In your \*.fsproj project and you'll get the same benefits.
>
> ```xml
>
> net8.0
> preview
>
> ```## Extensions
NXUI ships with a rich set of extension methods and builder helpers so that all
UI composition can be expressed in C#. The code generator produces most of
these members for every Avalonia control and property.### Builders
`NXUI.Builders` exposes factory methods for every control type. Each method
creates the control instance and overloads let you capture it via `out var` for
later use.### Property helpers
For each Avalonia property the following methods are generated:
* **`(value)`** – set the property value.
* **`(IBinding, mode, priority)`** – bind with an Avalonia binding.
* **`(IObservable, mode, priority)`** – bind from an observable.
* **`Bind(mode, priority)`** – create a binding descriptor.
* **`Observe()`** – observable of property values.
* **`On(handler)`** – pass the observable to a handler.
* **`ObserveBinding()`** – observe binding values including errors.
* **`OnBinding(handler)`** – receive the binding observable.
* **`ObserveChanged()`** – observe full change events.
* **`OnChanged(handler)`** – handler for change observable.Enum properties get convenience methods for each enum value, e.g.
`HorizontalAlignmentCenter()`.### Event helpers
For routed and CLR events:
* **`ObserveOn(routes)`** – returns an `IObservable` sequence.
* **`On(handler, routes)`** – handler receiving the observable.
* **`OnHandler(action, routes)`** – attach a simple callback.### Style setters
`Set` methods on `Style` and `KeyFrame` let you define
style values using constants, bindings or observables.### Core runtime helpers
`NXUI.Extensions.AvaloniaObjectExtensions` provides `BindOneWay` and
`BindTwoWay` to link properties or observables without verbose binding code.`NXUI.Extensions.ReactiveObservableExtensions` adds utilities for reactive
workflows:- `ObserveOnUiThread` / `SubscribeOnUiThread`
- `TakeUntilDetachedFromVisualTree` / `SubscribeUntilDetached`
- `DisposeWith`
- `DataTemplate`
- `WhenAnyValue` (single or multiple expressions)Together these extensions enable complex, reactive UIs built entirely in code
while managing resources with minimal overhead.