• Stars
    star
    115
  • Rank 305,916 (Top 7 %)
  • Language
    C#
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Immutable objects that mirror popular object oriented UIs

Immutable UI

Immutable UI is a collection of immutable data objects that mirror object-oriented user interface APIs. It's like a "shadow DOM" for .NET apps.

So far, only Xamarin.Forms has been bound, but I hope to also cover UIKit. And I still haven't bound events... wip :-)

Try it

  1. Open ImmutableUI.sln in Visual Studio.

  2. Select the project FormsButtonCounter in the Samples folder, and run it.

  3. Click the "Increment" button a few times.

  4. Note that the label increases.

Here's the UI code for that sample:

using Xamarin.Forms;
using ImmutableUI.Forms;

public class MainPage : ContentPage
{
    public MainPage() => Content = BuildView().CreateView();

    void SetState() => BuildView().Apply(Content);

    int _counter;

    Command _push => new Command(() => {
        _counter++;
        SetState();
    });

    ViewModel BuildView() =>
        new StackLayoutModel(
            children: new ViewModel[] {
                new LabelModel(text: _counter.ToString(), fontSize: 42),
                new ButtonModel(text: "Increment", command: _push),
            },
            padding: new Thickness(42));
}

Immutable UI Models

There is an immutable model class provided for every UI class in Xamarin.Forms.

To keep ourselves sane, each of these objects is suffixed with Model and is contained in the namespace ImmutableUI.Forms. (If the names weren't suffixed then terribly annoying name collisions would happen with the OOP API.)

For example, Xamarin.Forms.Button has an immutable counterpart named ImmutableUI.Forms.ButtonModel.

Thread Safety

UI Model objects can be used on multiple threads simultaneously since there's no risk of corrupting state. This means they can be shared between the UI thread and background workers without the need for synchronization.

Sharing

Immutable objects can be added to multiple UI trees to make multiple displays and caching easy.

Structural Equality

Every object implements deep versions of Equals and GetHashCode so that you can reliably test if two UIs are identical. This also allows you to use these objects as keys in dictionaries and sets.

Fluent Setter Interface

Let's be honest, immutable objects are a bit of a pain to deal with - sometimes you just want to set a property. Well, you still can't quite do that, but this library does provide a fluent interface to help out. Here it is in action:

var basicButton = new ButtonModel().WithFontSize(24).WithTextColor(Color.Green);
var okButton = basicButton.WithText("OK").WithCommand(ok);
var cancelButton = basicButton.WithText("Cancel").WithTextColor(Color.Red).WithCommand(cancel);

Note that the basicButton above is being used like a template - a fun little use of this fluent capability.

Complete Constructors

Every object's constructor accepts any of the properties stored in the object. In fact, constructing objects is your only chance to set these properties.

Every constructor parameter is a lowercased named after its corresponding property. Each one also has a default so you aren't forced to specify everything.

The fluent example above would can be written using constructors:

var basicButton = new ButtonModel(fontSize: 24, textColor: Color.Green);

Serializable

Every object is light-weight and can be serialized and deserialized using your favorite library.

This means your UI can now be serialized. This opens up many opportunities for quick state restoration, in-app GUI design, etc.

Works with the Mutable Objects

None of these objects would be useful unless they could work with their original mutable counterparts.

This is accomplished with two methods:

  • Create* creates the mutable counterpart to the immutable object and sets its properties appropriately. For example, ButtonModel objects have a CreateButton method that returns a Xamarin.Forms.Button. This is the easiest way to create real UI objects from these lightweight immutable objects.

  • Apply sets the properties of the mutable oop object to match the properties of the immutable object. The following example shows its simplest use:

// Create the UI object independently of the immutable object
var button = new Button();
// Now create our immutable object model
var buttonModel = new ButtonModel(text: "Hello");
// Set the properties of `button` to those of the model
buttonModel.Apply(button);

Important note: While all methods on these model objects are thread safe thanks to their immutability, you must run the Apply method on the UI thread of your app because it directly manipulates the UI. This synchronization is not handled for you.

Related Work

More Repositories

1

sqlite-net

Simple, powerful, cross-platform SQLite client and ORM for .NET
C#
3,753
star
2

Ooui

A small cross-platform UI library that brings the simplicity of native UI development to the web
C#
1,616
star
3

Netjs

Compile .NET assemblies to TypeScript and JavaScript
C#
955
star
4

NGraphics

NGraphics is a cross platform library for rendering vector graphics on .NET. It provides a unified API for both immediate and retained mode graphics using high quality native renderers.
C#
696
star
5

FuGetGallery

An alternative web UI for browsing nuget packages
C#
672
star
6

webgpu-torch

Tensor computation with WebGPU acceleration
TypeScript
488
star
7

Continuous

Continuous IDE Addin enables live coding from Xamarin Studio and Visual Studio
C#
268
star
8

CLanguage

C parser, compiler, and interpreter for .NET
C#
252
star
9

Bind

A small but powerful C# library for data binding
C#
205
star
10

CrossGraphics

Cross-platform Graphics Library for .NET
C#
194
star
11

transformers-js

Browser-compatible JS library for running language models
JavaScript
178
star
12

ListDiff

C#
113
star
13

Iril

Compiles LLVM IR (bytecode) or C to .NET Assemblies
LLVM
94
star
14

web-transformers

Transformer neural networks in the browser
TypeScript
89
star
15

Praeclarum.MacCatalyst

Convert your Xamarin.iOS apps to Mac Catalyst apps by adding this nuget.
C#
63
star
16

Csg

Solid modeling library for .NET
C#
62
star
17

AskGPT

Ask ChatGPT questions from the command line.
C#
58
star
18

SwiftSharp

Swift compiler for .NET
HTML
52
star
19

Gone

GO compiler for .NET
F#
42
star
20

HotDogOrNot

A minimal Xamarin CoreML app to detect hotdogs
C#
40
star
21

lcars

LCARS Reader - the coolest iPad news reader not on the App Store
C#
36
star
22

CSharpInteractive

C# Interactive is a REPL for C# in Xamarin Studio
C#
30
star
23

Praeclarum

My general purpose library
C#
29
star
24

QuickTest

C#
28
star
25

GooglePlus

GooglePlus API Documentation and .NET Implementation
C#
27
star
26

MetalTensors

.NET Neural Network training library using Apple's Metal Performance Shaders
C#
26
star
27

runcs

The C# compiler hosted in a web app
C#
26
star
28

odata

OData Browser for the iPhone
C#
26
star
29

CSharpToSwift

Converts your C# projects to Swift
C#
23
star
30

StopCrashing

Script to detect possible sources of crashes in Xamarin apps
F#
21
star
31

FunctionalMeetup

Example code for Frank Krueger's Functional Mobile Apps talk at NDC Oslo 2016
F#
19
star
32

EasyLayout

EasyLayout makes writing auto layout code in Xamarin.iOS easier.
C#
18
star
33

SdfKit

.NET library to convert signed distance functions (SDFs) into triangle meshes and 3D renders
C#
17
star
34

OouiChat

Chat room web app built using Xamarin.Forms, ASP.NET, and Ooui
C#
16
star
35

MarriageClock

An IoT thing in the shape of heart that tells you how long you've been married
C++
13
star
36

ThreeDO

C#
13
star
37

Ur

Game of Ur using Blazor
C#
13
star
38

CircuitTranslations

Language support for iCircuit
F#
13
star
39

ARDemo

Xamarin Evolve 2014 Augmented Reality Demo
C#
12
star
40

fuget

C#
10
star
41

praeclarum.github.io

Frank A. Krueger's blog
HTML
10
star
42

caulker

3D Map for MonoTouch
C#
10
star
43

WebGlobe

3D Globe Screensaver Written in WebGPU
JavaScript
9
star
44

JavaScriptLanguage

Resharper add-in that decompiles to JavaScript.
C#
8
star
45

NMusic

Library and demo app for composing music and playing it on iOS
C#
8
star
46

Demo11

iOS 11 Demo Code Presented at the Seattle Mobile .NET Meetup
C#
8
star
47

BuildLight

Show IDE build status using an IoT device
C#
8
star
48

circuitpython-net

CircuitPython compiled to run on .NET
C#
8
star
49

CuneiformTranslators

Neural network trained to translate from ancient languages to modern languages
Jupyter Notebook
8
star
50

ukf

Unscented Kalman Filter Library
7
star
51

ClrTools

Tools for .NET Developers
C#
7
star
52

ImageRecognizer

Uses Metal Performance Shaders on iOS 13+ to train a neural network to recognize shapes
C#
7
star
53

rt

My Pet Raytracer in C#
C#
6
star
54

Monospace11

Demo code from Frank Krueger's talk at Monospace
C#
6
star
55

rouse

Declarative RESTful server
C#
5
star
56

NEcho

Amazon Echo ("Alexa") ASP.NET Core Web Service
C#
5
star
57

html5

C#
5
star
58

NeuralScanner

C++
4
star
59

Fom

F#
4
star
60

VectorPerf

Measures the performance of different vector types in .NET
C#
4
star
61

Knossus

Quick and easy web apps
C#
4
star
62

WasmAloneLab

HTML
4
star
63

UIDays

Cataloging the release dates of various UI frameworks
4
star
64

HomeAI

C#
4
star
65

ColmapSharp

COLMAP builds and bindings for .NET
C++
4
star
66

SubMark1Sim

F# Code to visualize a submarine control simulation
F#
3
star
67

AppleNative.Templates

F#
3
star
68

dotnet-tree-sitter

.NET bindings to the Tree-sitter parsing library
Makefile
3
star
69

Lilui

The lilest cross platform UI library for .NET
C#
3
star
70

BuildBoard

Display build status on an LED matrix
C++
2
star
71

nerf-py

Python
1
star
72

VacuumMold

C#
1
star
73

PythonRepl

Python REPL for iOS using Xamarin and IronPython
C#
1
star
74

BoxEditor

Generic box-based diagram editor for .NET
C#
1
star
75

Armina

Programming language cross compilation tools
C#
1
star