Click here to Skip to main content
15,880,905 members
Articles / Desktop Programming / X11

Writing a XAML application for X11 with massive data binding and zero code

Rate me:
Please Sign up or sign in to vote.
4.88/5 (5 votes)
22 Nov 2014CPOL10 min read 16.5K   175   5   2
Currently none of the big Linux/Unix (X11) GUI application frameworks (GTK+, KDE) support XAML based application development. The Moonlight project (including XAML support) was abandoned on May 29, 2012. This article reviews a XAML based application utilizing massive data binding with zero code.

Image 1 Download XamlFontApp_X11_32.zip
Image 2 Download XamlFontApp_X11_64.zip
Image 3 Download XamlFontApp_Win7.zip

Introduction

This article is a case study, how to write a MVVM (Model View ViewModel) design pattern based X11 application (utilizing massive data binding with zero code) with XAML using the Roma Widget Set (Xrw). The Roma Widget Set is a zero dependency GUI application framework for X11 (it requires only assemblies of the free Mono standard installation and libraries of the free X11 distribution; it doesn't particularly require GNOME, KDE or commercial libraries) and is implemented entirely in C#.

This article continues the works Writing a XAML dialog application for X11 and Writing a XAML ribbon application for X11. As far as i know, this (utilizing the Xrw) is the first attempt to use XAML for X11 application development after the abandonment of Moonlight.

Neither the Roma Widget Set nor the XAML implementation are complete. This sample application is intended as a more complex 'proof of concept' and checks out if and how it is possible bo create MVVM design pattern based X11 application with XAML.

Since this third attempt to use XAML for a X11 application development has been successful, other articles about XAML using the Roma Widget Set on X11 will follow centenly.

Background

The Motivation and the general Concept to use XAML for X11 application development are already explained in the Writing a XAML dialog application for X11 article.

Focus

While the first article Writing a XAML dialog application for X11 demonstrated, that with XAML

  • a window containing some controls can be defined and
  • click events can be connected to buttons,

and the second article Writing a XAML ribbon application for X11 demonstrated, that with XAML

  • a window containing a ribbon command interface can be defined,
  • static window resources (this sample has a resource converter and a ModelView) can be defined,
  • a ModelView can be assigned to a control's data context as a static resource,
  • a resource converter can be applied to a control's property as a static resource,
  • commands can be bound to buttons via the "RelayCommand" approach,
  • control properties can be bound to the data context and
  • controls can be updated via the INotifyPropertyChanged interface,

this article shall demonstrate that with XAML

  • massive data binding can provide a useful functionality and
  • an application with zero code behind can be defined.

Using the code

The sample application was written with Mono Develop 2.4.1 for Mono 2.8.1 on OPEN SUSE 11.3 Linux 32 bit EN and GNOME desktop. Neither the port to any older nor to any newer version should be a problem. The sample application's solution consists of two projects (the complete sources are provided for download):

  • XamlFontApp contains the source code of the sample application.
  • XamlPreprocessor contains the source code of the XAML preprocessor.

The sample application is also tested with Mono Develop 3.0.6 for Mono 3.0.4 on OPEN SUSE 12.3 Linux 64 bit DE and GNOME desktop, IceWM, TWM und Xfce.

The only difference between the 32 bit and the 64 bit solution is the definition of some X11 specific data types, as already described in the Programming Xlib with Mono develop -Part 1: Low level (proof of concept) article.

The Xlib/X11 window handling is based on the X11Wrapper assembly version 0.7, that defines the function prototypes, structures and types for Xlib/X11 calls to the libX11.so. This assembly has been developed for the Programming Xlib with Mono Develop - Part 1: Low-level (proof of concept) project and has been advanced during the Programming the Roma Widget Set (C# X11) - a zero dependency GUI application framework - Basics project.

The GUI framework is based on the Xrw assembly version 0.7, that defines the widgets/gadgets and its wrapper classes used within the XAML code (that should be as near to the Microsoft® original as reasonable). This assembly has been developed during the Programming the Roma Widget Set (C# X11) - a zero dependency GUI application framework - Basics project.

Advice: To use the class library documentation shortcut (F1) from MonoDevelop, the "mono-tools" package has to be installed.

The first image shows the sample application on OPEN SUSE 11.3 Linux 32 bit EN and GNOME desktop.

Image 4

The second image shows the sample application on OPEN SUSE 12.3 Linux 64 bit DE and Xfce.

Image 5

The third image shows the sample application on Windows® 7 64 Bit Edition.

Image 6

The sample application provides a Font Family selection list, a Family Typefaces selection list and a Font Size slider. Any font change will be shown by the preview text immediately.

The sample application is based on the ideas behind the article Pure XAML Font Choose by Norris Cheng. The specific challenge was to realize the full functionality with zero code behind for X11.

Walk through

The Project setup, Application file context (except the theme) and Preporocessor code generation steps are exactly the same as in Writing a XAML dialog application for X11. Please refer to this article, if a new solution shall be created from scratch.

Main view file context

The XAML (MainView.xaml)

First the XAML file of the window.

XML
<Window         x:Class="XamlFontApp.MainView"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:src="clr-namespace:XamlFontApp"
                DataContext="src:MainViewModel"
                Name="MainWindow" Title="XAML font application"
                Width="750" Height="400" Icon="XrwIcon16.bmp">
    <Window.Resources>
    </Window.Resources>
    <Grid Name="MainGrid" Background="#FFEBEBEB">
        <Grid.Resources>
            <!-- <src:MainViewModel x:Key="mainViewDataSource" /> -->
        </Grid.Resources>
        <Grid.Datacontext>
            <!-- <Binding Source="{StaticResource mainViewDataSource}"/> -->
        </Grid.Datacontext>
        <Grid.RowDefinitions>
            <RowDefinition Height="10"/>
            <RowDefinition Height="28"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="28"/>
            <RowDefinition Height="10"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="10"/>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="10"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="10"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="10"/>
        </Grid.ColumnDefinitions>
        
        <Label Name="FontFamiliesLabel" Grid.Column="1" Grid.Row="1" FontSize="14"
              FontWeight="Bold" Content="Font Family" Background="#FFEBEBEB" />
        <ListView Name="FontFamiliesListView" Grid.Column="1" Grid.Row="2"
                  ItemsSource="{x:Static Fonts.SystemFontFamilies}" >
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Source"
                                        DisplayMemberBinding="{Binding Source}" />
                        <GridViewColumn Header="Baseline"
                                        DisplayMemberBinding="{Binding Baseline}" />
                        <GridViewColumn Header="LineSpacing"
                                        DisplayMemberBinding="{Binding LineSpacing}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
        <Label Name="SelectedFontFamilyLabel" Grid.Column="1" Grid.Row="3"
               Content="{Binding SelectedItem.Source, ElementName=FontFamiliesListView, Mode=OneWay}"
               Background="#FFEBEBEB" />
        
        <Label Name="FamilyTypefacesLabel" Grid.Column="3" Grid.Row="1"
               FontSize="14" FontWeight="Bold" Content="Family Typefaces" Background="#FFEBEBEB" />
        <ListView Name="FamilyTypefacesListView" Grid.Column="3" Grid.Row="2"
                  ItemsSource="{Binding SelectedItem.FamilyTypefaces,
                                ElementName=FontFamiliesListView, Mode=OneWay}" >
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Style" DisplayMemberBinding="{Binding Style}" />
                        <GridViewColumn Header="Weight" DisplayMemberBinding="{Binding Weight}" />
                        <GridViewColumn Header="Stretch" DisplayMemberBinding="{Binding Stretch}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
        <Label Name="SelectedFamilyTypefacesLabel" Grid.Column="3" Grid.Row="3"
               Content="{Binding SelectedItem.Style, ElementName=FamilyTypefacesListView, Mode=OneWay}"
               Background="#FFEBEBEB" />
        
        <Slider Name="FontSizeSlider" Grid.Column="5" Grid.Row="1" Orientation="Horizontal"
                Minimum="6" Value="12" Maximum="72" SmallChange="1" LargeChange="8" />
        <TextBlock Name="TextSimulation" Grid.Column="5" Grid.Row="2"
                   Text="The quick brown fox jumps over the lazy dog."
                 FontFamily="{Binding SelectedItem.Source, ElementName=FontFamiliesListView}"
                 FontWeight="{Binding SelectedItem.Weight, ElementName=FamilyTypefacesListView}"
                 FontStretch="{Binding SelectedItem.Stretch, ElementName=FamilyTypefacesListView}"
                 FontStyle="{Binding SelectedItem.Style, ElementName=FamilyTypefacesListView}"
                 FontSize="{Binding Value, ElementName=FontSizeSlider}" TextWrapping="Wrap"
                 Background="#FFF8F8F8" />
        <Label Name="FontSizeLabel" Grid.Column="5" Grid.Row="3" Background="#FFEBEBEB"
               Content="{Binding Value, ElementName=FontSizeSlider, Mode=OneWay}" />
    </Grid>
</Window>

The complete XAML code is fully Microsoft® compatible.

Compared to Writing a XAML ribbon application for X11, only the enhancments and differences will be discussed.

The Label will be defined (in addition to the already known features) by:

  • The Background attribute defines the background color. This attribute is is optional. The syntax of the attribute is a hexadecimal value #AARRGGBB with AA for alpha, RR for red, GG for green and BB for blue. Currently the alpha value is not implemented.
  • The FontSize attribute defines the font size. This attribute is is optional. The syntax of the attribute is a decimal value. Bitmap fonts (in contrast to vector fonts) do not support any font size. Their font size will fall back to the nearest supported font size, if any unsupported font size is specified.
  • The FontWeight attribute defines the font weight. This attribute is is optional. The syntax of the attribute is the string representation of any System.Windows.FontWeight value. Typical values are Light, Regular and Bold. The fallback value is Regular. Mind that Windows® fonts typically use the font weight value Normal while X11 fonts typically use the font weight value Regular for equivalent font weight. Most of the default font falilies support only a few font wights and some font weights are not supported by any of the default font falilies.

The ListView will be defined (in addition to the already known features) by:

  • The ItemSource attribute defines the data source to create the items to display from. This attribute is is optional. The syntax of the attribute can be either {x:Static <resource name>} for static resources or  {Binding <path>, ElementName=<control name>, Mode=<mode>} for dynamic resources. The data source must implement System.Collections.IEnumerable. A dynamic data source should implement INotifyPropertyChanged as well. Currently the Mode is not implemented.

The Slider will be defined by:

  • The Name attribute defines the class instance name, that can be used to identify the class instance uniquely. This attribute is is recommended, or mandatory if this class instance has to be accessible through C# code.
  • The Grid.Column attribute defines the zero-based column index, the control has to be positioned inside a grid. The default value is 0. This attribute is recommended for a grid child, but mandatory for controls positioned not on column 0 inside a grid. The index must not exceed the available grid rows.
  • The Grid.Row attribute defines the zero-based row index, the control has to be positioned inside a grid. The default value is 0. This attribute is recommended for a grid child, but mandatory for controls positioned not on row 0 inside a grid. The index must not exceed the available grid rows.
  • The Orientation attribute defines the orientation. This attribute is optional. The default value is Horizontal.
  • The Minimum attribute defines the smallest possible value. This attribute is is optional. The default value is 0.0F.
  • The Maximum attribute defines the greatest possible value. This attribute is is optional. The default value is 100.0F.
  • The Value attribute defines the currently selected value. This attribute is is optional. The default value is Minimum.
  • The SmallChange attribute is currently not implemented.
  • The LargeChange attribute is currently not implemented.

The TextBlock (is similar to Label but supports automatic line break) will be defined by:

  • The Name attribute defines the class instance name, that can be used to identify the class instance uniquely. This attribute is is recommended, or mandatory if this class instance has to be accessible through C# code.
  • The Grid.Column attribute defines the zero-based column index, the control has to be positioned inside a grid. The default value is 0. This attribute is recommended for a grid child, but mandatory for controls positioned not on column 0 inside a grid. The index must not exceed the available grid rows.
  • The Grid.Row attribute defines the zero-based row index, the control has to be positioned inside a grid. The default value is 0. This attribute is recommended for a grid child, but mandatory for controls positioned not on row 0 inside a grid. The index must not exceed the available grid rows.
  • The Text attribute defines the text to display. This attribute is optional. The default value is an empty string.
  • The FontFamily attribute defines the font family name. This attribute is is optional. The syntax of the attribute is either <font family name> like Arial or <font foundry name>-<font family name> like Adobe-Utopia. The first syntax is fully Microsoft® compatible, the second syntax is necessary due to the X11 font specification.
  • The FontWeight attribute defines the font weight. This attribute is is optional. The syntax of the attribute is the string representation of any System.Windows.FontWeight value. Typical values are Light, Regular and Bold. The fallback value is Regular. Mind that Windows® fonts typically use the font weight value Normal while X11 fonts typically use the font weight value Regular for equivalent font weight. Most of the default font falilies support only a few font wights and some font weights are not supported by any of the default font falilies.
  • The FontStretch attribute defines the font stretch. This attribute is is optional. The syntax of the attribute is the string representation of any System.Windows.FontStretch value. Typical values are SemiCondensed, Medium and SemiExpanded. The fallback value is Medium. Most of the default font falilies support only a few font stretches and some font stretches are not supported by any of the default font falilies.
  • The FontStyle attribute defines the font style. This attribute is is optional. The syntax of the attribute is the string representation of any System.Windows.FontStyle value. Typical values are Normal, Italic and Oblique. The fallback value is Normal. Not all of the default font falilies support every font style.
  • The FontSize attribute defines the font size. This attribute is is optional. The syntax of the attribute is a decimal value. Bitmap fonts (in contrast to vector fonts) do not support any font size. Their font size will fall back to the nearest supported font size, if any unsupported font size is specified.

The code behind (MainView.xaml.cs)

The corresponding C# code file of the main view is MainView.xaml.cs. It is in initial state and thus almost empty.

C#
using System;

using X11;
using Xrw;
using XrwXAML;

namespace XamlFontApp
{
    /// <summary>The main window of the application. This class must be derived from XrwXAML.Window.
    /// It must be a partial class.
    /// The second part of the class will be autogenerated and named '*.generated.cs'.</summary>
    public partial class MainView : XrwXAML.Window, IView
    {
        
        /// <summary>The default constructor.</summary>
        public MainView ()
            : base (-1, -1)
        {
            InitializeComponent ();
            // Will be called after construction by generated code!
        }
    }
}

Main view model file context

The MainWindowViewModel.cs file remains in initial state. There is no functionality provided to the application by the ViewModel.

Main model file context

The MainModel.cs file remains in initial state. There is no functionality provided to the application by the Model.

Points of Interest

It is amazing to create as much functionality without any line if code! (And fully compatible with Microsoft®.)

The first three articles about "Writing a XAML application for X11" have shown, hat single view applications can be written with fully portable code for Windows® and X11. The next step should prove this for applications with multiple views.

Since 02. February 2015 the article Writing a XAML calculator application for X11 continues the XAML topic.

History

The first version of this article is from 22. November 2014.
The first reviewed version is from 19. February 2015.
The second reviewed version is from 19. February 2015.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Celonis SA
Germany Germany
I am currently the CEO of Symbioworld GmbH and as such responsible for personnel management, information security, data protection and certifications. Furthermore, as a senior programmer, I am responsible for the automatic layout engine, the simulation (Activity Based Costing), the automatic creation of Word/RTF reports and the data transformation in complex migration projects.

The main focus of my work as a programmer is the development of Microsoft Azure Services using C# and Visual Studio.

Privately, I am interested in C++ and Linux in addition to C#. I like the approach of open source software and like to support OSS with own contributions.

Comments and Discussions

 
GeneralGreat work Pin
AMC7-Oct-15 16:22
AMC7-Oct-15 16:22 
GeneralRe: Great work Pin
Steffen Ploetz7-Oct-15 18:52
mvaSteffen Ploetz7-Oct-15 18:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.