• Overview
  • Documentation
  • GitHub
  • Blog
  • Premium support
  • Contact

AMMY

Modern UI language for XAML platforms

Lightweight

Straightforward JSON-like syntax that is both easy to write and maintain

Extendable

Create reusable components to avoid code duplication

Realtime

Application UI is updated on the fly, no need for recompilation

WPF

Quickstart

Xamarin Forms

Quickstart

UWP

Quickstart

NoesisGUI

Sample project

We love XAML

Ammy code is actually compiled to XAML. This means that any complex thing you could do in XAML you can also do with Ammy. Which would be much easier, thanks to concise syntax and mixins.
Learn more

Why Ammy?

Free!

Absolutely free for everyone!

Easy to learn

Ammy allows you to use your XAML knowledge while building better, easier to maintain applications

XAML compatible

Ammy is fully XAML compatible, meaning any XAML code can be converted to Ammy

Syntax meant for people

Ammy is designed with a goal to make coding less tedious. Fewer symbols means it’s easy write and maintain.

Mixins and variables

Code reuse means less copy-pasting, more centralized control of the UI

Realtime update

Without the need to recompile application anytime something changes, development cycle becomes shorter and more enjoyable

Nuget package

No project configuration needed. Just install a nuget package and you are good to go.

Visual Studio extension

Syntax coloring, smart completion, realtime updates, item templates, these are just few things Visual Studio extension brings to the table

Good support

Contact us anytime via means listed at the bottom of the page. We strive to help everyone as fast as possible.

DOCUMENTATION

What makes Ammy better than XAML?

Mixins

Mixins allow you to encapsulate often used patterns into small combinable components. If you are familiar with HTML/CSS then you can say that mixin is an upgraded version of CSS class.

Mixins can also be compared to XAML Styles in that they basically represent preconfigured properties that can be applied to an element. There are two major differences, though:

  1. Mixin can accept parameters
  2. You can apply multiple mixins to one element

With mixins you can separate logic from presentation, apply premade triggers, reuse animations and much more.

Simple mixin
Grid
Watermark
Simple mixin
mixin Accented() for TextBlock {
  Foreground: "#9BE55D"
}
 
TextBlock { 
  #Accented
  "Hello" 
}
 
TextBlock { 
  #Accented
  "World"
}
Grid
mixin ThreeRows (one, two, three) for Grid
{
  RowDefinitions: [
    RowDefinition { Height: $one }
    RowDefinition { Height: $two }
    RowDefinition { Height: $three }
  ]
}

Grid { 
  #ThreeRows(100, "*", "Auto")
}
Watermark
TextBox {
  #Watermark("FirstName", "First name")
}
TextBox {
  #Watermark("LastName", "Last name")
}
mixin Watermark(bindingPath, watermarkText) for TextBox {
  Style: combine Style {
    TargetType: TextBox
    Triggers: [
      DataTrigger {
        Binding: bind $bindingPath 
                 convert (string str) => string.IsNullOrEmpty(str)
        Value: true
                
        Setter { Property: "Text", Value: $watermarkText}
        Setter { Property: "FontSize", Value: 24}
        Setter { Property: "Opacity", Value: 0.3}
      }

      DataTrigger {
        Binding: bind IsFocused from $this
        Value: true
              
        Setter { Property: "Opacity", Value: 1}
        Setter { 
          Property: "Text"
          Value: bind $bindingPath 
                 set [ UpdateSourceTrigger: PropertyChanged ]
        }
      }

      DataTrigger {
        Binding: bind $bindingPath 
                 convert (string str) => !string.IsNullOrEmpty(str)
        Value: true 
        Setter { 
          Property: "Text"
          Value: bind $bindingPath 
                 set [ UpdateSourceTrigger: PropertyChanged ]
        }
      }
    ]
  }
}

Aliases

Alias is very similar to a mixin, but where mixin defines a set of properties, alias defines an element. Most of the stuff from mixins also applies to aliases.

You could describe alias as a lightweight alternative to UserControl that can accept parameters.

Simple alias
Image button
Grid item control
Simple alias
alias Header() {
  TextBlock { 
    FontSize: 16
    FontWeight: Bold
    TextAlignment: Center
  }
}

@Header() {
  Text: "Settings"
}
Image button
alias ImageButton(text, image) {
  Button { 
    ToolTip: $text,
    Image { 
      Source: $image
    }
  }
}

@ImageButton("Play", "/Icons/play.png") {}
@ImageButton("Pause", "/Icons/pause.png") {}
Grid item control
alias GridItemsControl() {
  ItemsControl {
    ScrollViewer.HorizontalScrollBarVisibility: Disabled,
 
    ItemsPanel: ItemsPanelTemplate { 
      WrapPanel {
        IsItemsHost: true
        Orientation: Horizontal
      }
    }
  }
}

Binding converters

Ammy allows you to define binding converters inside markup. A binding converter is represented by a C#-like code, that looks like a lambda expression. It can do most of the stuff lambda expression can: comparisons, method calls, constructors etc.

Once defined, a converter is serialized as a string and later deserialized as Expression Tree. All converters are cached, meaning only first usage will involve deserialization.

Simple converter
Visibility
Brush from binding
Simple converter
TextBlock { 
  Text: bind FirstName 
        convert (string name) => "Hello, " + name
}
Visibility
Button { 
  Visibility: bind HasErrors
              convert (bool hasErrors) => hasErrors
                                          ? Visibility.Collapsed 
                                          : Visibility.Visible
}
Brush from binding
Rectangle { 
  Fill: bind    // Leaving path empty will bind DataContext object
        convert (ColorViewModel vm) => new SolidColorBrush(Color.FromArgb(vm.A, vm.R, vm.G, vm.B))
}

Live coding

Developing UI on a running application feels like an actual magic. You can change anything in markup and instantly see an update on a screen. Most importantly all your bindings work and represent actual running data.

If you are designing a twitter client you would see new tweets appear, while you change their appearance at the same time.

Or, imagine there is a big data entry form you need to create. You can arrange inputs, setup bindings, apply validation and all of that while your app runs and shows actual data. You can click stuff and see that it really works.

Project Converter

In a few clicks, you can upgrade you current XAML project to Ammy. The converter will translate every XAML file to Ammy and update project file with required item references.

You can also convert singular XAML files. Just paste file contents and copy resulting Ammy markup.

There are formatting options that can be configured to suit your particular coding style and application.

Binaries

Source code

WPF Demo

Watch the development of a simple data entry application. Note that application was always running during the development, never needing to restart. Also note how window structure and presentation are separated. Structure being in MainWindow.ammy file, while all presentation resides in MainWindowMixins.ammy.

Skip to 24:30 if you want to see resulting code and application.

Xamarin Forms Demo

Live development of a small shopping list scanner application using Xamarin Forms and Android emulator. Showcases Mixin and binding converter usage.

Join Gitter discussion
Submit issues on GitHub
Follow us on Twitter

We offer UI development services for WPF, UWP and Xamarin Forms

Reasonable prices, great quality, and fast execution.

Contact us as info@ammyui.com for more information

Do you like Ammy? Share your feelings!

1

Powered by Nitra

info@ammyui.com

© 2017 Ammy by ION OÜ