RecentComments

Comment RSS

WPF XAML SYNTAX 101

by Ioannis 16. December 2008 08:21

DownLoad in .pdf (145,97 kb)

This post provides the basic key points in order to understand the WPF XAML syntax and what is going on behind the scenes in the XAML Processor. Although you may be the kind of guy/girl who prefers to learn through writing/reading code, I recommend reading this article since it may save you a lot of time when trying to figure out how to combine the XAML Elements together.

First things first, we need to define what the XAML processor does. Well, the XAML processor as the following figure suggests, receives XAML XML language constructs and translates them to code that will be compiled to run in the .NET Framework. 

So the user writes the XAML File and some source code.

Behind the scenes the XAML File is translated to code by the XAML Processor. The translated code is combined with the source code and the final merged product is compiled and leads to the desired WPF application.

The programmer that was used in programming for Windows Forms, apart from learning the new language constructs, he/she also needs to learn the XAML syntax and how it is translated to code. This is the main topic of this article. So we will be interested in this translation:

First of all, in any XML document we have XML elements and XML attributes. For the XAML processor Elements are Class Instantiations and XML Attribute-Value pairs are Class Property-Value assignments.

For example the following table shows equivalence for the instantiation of a class of type Button:

But as you know classes reside in namespaces. So how can you define a namespace to locate the classes that you need?

At the beginning of a XAML file there are two definitions:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml

The first one is the actual declaration of the WPF namespace and since it is not followed by a “:” it is the default namespace. Since “Button” does not have a “:” prefix its definition will be expected to be in there.

On the contrary the next namespace defines the XAML syntax and will carry the “x” name throughout the document. Actually the x namespace carries some special directives to the XAML Processor and does not necessarily follow the typical Attributes to Properties mapping. For example the “x:Name” attribute in the Button declaration instructs the XAML Processor to create a named instance for the Button class because we want to be able to access it through code.

So if you want to use in your XAML File your own classes and controls you need to define your namespace in XAML. The following example code snippet defines two namespaces the one (Entities) that will be named tools and resides in Entities.dll and the other (Force) that resides in the same dll with the XAML file.

xmlns:tools="clr-namespace:Entities;assembly=Entities"
xmlns:local="clr-namespace:Force"

Moreover the definition:

x:Class="Force.MainClass"

states that there will be a code-behind class MainClass which will be used in conjunction with the XAML File which also carries code for the MainClass class.

But wait a second, in the previous example the property IsEnabled is Boolean and is assigned in XAML the value of “True” which is a String. And what will happen if the property is of type “Int”?

Well, when the programmer writes in XAML IsEnabled=”True” the XAML Processor does the following: It locates the property and finds out its type. It searches to find whether there exists a special class named “Type Converter” defined for the type. The type converter is a class that is fed by the XAML processor with the attribute value (eg “True”) and returns a mapping of that value to the actual type (eg the Boolean value True). So for the Boolean type there is a Type Converter class that transforms String literals to Boolean values. You can create your own type converters for your own types (classes) by following the instructions in the following nice articles:

How to: Implement a Type Converter
Walkthrough: Creating a Type Converter for the WPF Designer

Ok so we know how to instantiate classes in XAML and assign values to properties through the use of type converters.

Now we need to define how “Nesting” is interpreted by the XAML Processor. Nesting is the process of containing an XML tagged block within another. In XAML WPF the way nesting is handled is defined by the class that is instantiated.

For example nesting in the Button class is equivalent to assigning a value to the property “Content”.

Or in the ViewPort3D class nesting is equivalent to adding items to the property Children which is of a list type.

In general nesting either gives value to a specific “default” property or adds another element in a property that defines some kind of list.

A specific nesting type answers the previous question of giving values to properties that have to do with instantiating other classes. If a nested block is defined by properties of the class written in the dot syntax, then the contents are setting the value for this property:

To summarize up to now we can fully understand the following XAML files:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"> 
    <Button x:Name="button1" IsEnabled=”True”>Test</Button>
</Window>

A button class is defined with its Content property equal to Test. The class is named button1. The property IsEnabled is assigned the Boolean value true through the use of a type converter that converts string values to Boolean. The property Content of the Window top-level class has the value of the instantiated button.

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Button x:Name="button1" Content="Test" IsEnabled=”True”/>
</Window>

Same as before without using the nesting.

Another way of setting the value to a property is by using the nesting as a property setting mechanism. For example, to set the Content property of the previous example we could:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    Title="Window1" Height="300" Width="300">  
   <Button x:Name="button1" IsEnabled=”True”> 
       <Button.Content>Test</Button.Content> 
    <Button/>
</Window>

This way is especially useful when we want to instantiate whole new classes to be values for properties of objects. In the previous example the window class sets by default the content property through nesting which will be assigned a reference to the Button class. It is equivalent to:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 
   Title="Window1" Height="300" Width="300"> 
   <Window.Content> 
       <Button x:Name="button1"> 
            <Button.Content>Test</Button.Content> 
        </Button> 
    </Window.Content>
</Window>

But there is another way for setting values to properties through the use of Markup Extensions. Markup extensions are either defined by curly braces or as nested values for setting properties. For example:

<GridViewColumn Width="Auto" Header="Επωνυμία" 
                   DisplayMemberBinding
= "{Binding Path=Logo}"/>

Is equivalent to:

<GridViewColumn Width="Auto" Header="Επωνυμία">
           <GridViewColumn.DisplayMemberBinding> 
            <Binding Path="Logo"/> 
      </GridViewColumn.DisplayMemberBinding>

</GridViewColumn>

Markup extension classes tell the XAML Processor to create an instance of the defined class (in our case the Binding class), set some properties (in our case the Path property is set to “Logo”) of the class and run the constructor with some parameters (in our case no parameters are passed) and call the ProvideValue member of the extension class to get the value that will be assigned to the property. The general syntax is as follows:

{MarkupExtensionClass
        
ConstructorArg1, ConstructorArg2,…,ConstructorArgN,
         Property1=Value1,Property2=Value2,…,PropertyN=ValueN
}

There is already a whole bunch of predefined markup extensions. Their summary can be found in the following:

Markup Extensions in XAML

This summarizes a brief introduction to the WPF XAML syntax. Happy coding.

kick it on DotNetKicks.com

Tags:

.NET | WPF

Code Formatter for HTML

by Ioannis 7. December 2008 04:55

I have been searching for some time for a neat html code generator from C# code that supports syntaxt highlighting, in order to use it in BlogEngine.Net. The previous posts in this article have been written by applying the usual _[_code:cs]...[_/code] tags. Unfortunately this approach does not always work correctly especially when somebody wants to copy-paste code directly from Visual Studio. Moreover it would be nice if the converter was univeral, that is it could be used independently of BlogEngine.

What I want to do is copy-paste code from a program I have written in Visual Studio, convert the code to html with tags defining what each word is (keyword, comment, string etc), copy-paste this code to my HTML page or the BlogeEninge's javascript editor (in HTML mode) and finally apply some styles in the css file to define the colors of the words.

I am putting in this post a small program I have written that can help towards this direction. You can copy-paste any code from a Visual Studio window and get its simple html version in the form described above. You only have to copy-paste this code to your post as plain html and add to your .css file, the formatting directives as you will see in the accompanying zip file. Here are some results acquired using this tool:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace ConverVSCodeToHTML
{
    static class Program
    {
        /// 
        /// The main entry point for the application.
        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FormConverter());
        }
    }
}

Or the following:

if (level == 1)
{
    if (CharRead[0] == ' ')
        convertedString += "hello";
    else
        convertedString += CharRead[0].ToString();
   
}
BytesRead = rdr.Read(CharRead, 0, 1);
break;


The program works as follows: The code is initially in RTF format. The software looks for the color directives of the RTF code and based on the coloring defines the word as keyword, comment, string etc. This means that If you have changed the default syntax coloring of VS 2008 this program will not work. Note also that this syntax highlighter can be used independently of BlogEngine.NET if you want to easily copy-paste code to your HTML page.

Finally I stress that this is a beta version of the software and therefore any bug reports/comments are more than welcome. Note also that there is a minor bug in the code generated. Specifically, exactly at the start of the generated code the text "lang 1024" is displayed. You must manually erase that.

CSToHTMLConverter.zip (14,22 kb)

Encodings and Charsets

by Ioannis 1. December 2008 12:07

I always dreaded the "unrecognized characters" problems encountered in windows applications when dealing with old data. They appeared and still appear usually when data from an old MSDOS application are ported to current database management applications (MS Access, Microsoft SQL, .NET Datasets). The Greek language characters seem to have undergone a major change from old to new and applications do not automatically know how to cope with them. I guess the same applies also to other languages.In this article I will try to shed some light to those issues and offer a possble solution. To understand the "root of evil", we need to first understand enodings and character sets. And to do that we need to learn some history...

Each character displayed is associated with a number usually referred to as its "character code".  This number is the one used by the computer in order to locate in memory the representation of the character. Initially the first character codes to be used in computers where the 128 character codes defined in ASCII. Part of those 128 characters where the latin characters of the English alphabet. English speaking computer users where very happy with them but that can not be claimed for those poor people who happened to write and read in a language with different characters. What did the rest of the world do then to solve this problem?

Well if you think about it the ASCII character codes are stored in 1 byte (8 bits) where 7bits are used for the code and the 8th bit is reserved as it is the "parity" bit. The parity bit? Yeah,it turns out that originally ASCII was used as a telegraphic code and promoted as such by Bell data services. Since this bit ceased to serve such purpose in computers, each computer programmer who needed some custom characters to write in his/her aplhabet improvised new characters with codes from 128-255 by just setting this bit to 1 and assigning new character representations to the new set of 128 characters (the rest  bits with bit 8 set to 1). Each one of those new alphabets has become a character set and was given a specific code and thus has become a codepage.

To summarize:

  • Initially we had the ASCII table with codes from 0-127 stored in 1byte and handling only the latin alphabet.
  • Later a number of different character sets are created where 0-127 codes are the same as ASCII and 128-255 vary depending on each set. Those are called "codepages" or "charsets".

For example the latin letter "A" has character code 65 in every charset since it is one of the initial 128 characters. On the contrary the greek letter "A" has character code 128 in the ANSI Codepage 737(Greek DOS) and character code 164 in the ANSI Codepate 869 (Greek Modern DOS). This means that if you receive a string of characters from an old application you need to experiment with the codepages to find out to which codepage the characters refer to. 

This clearly is a mess. The resolution is to try to improvise a universal encoding scheme. And that is what Unicode represents. Each code represents a specific character. All characters in the world for all languages have a Unicode code associated with them. But how is this code stored in memory? Do we need to use 1 byte, 2 bytes or more? There seem to be a lot of ways that this number can be stored in memory and and that ar the "encodings". So different encodings are different representations of the Unicode code in memory. To make this clear suppose the following example concerning the greek character "A".

In the codepage era the character has many codes depending on the charset used.

  • Greek Character A has the character code 128 in the ANSI Codepage 737(Greek DOS).
  • Greek Character A has the character code 164 in the ANSI Codepage 869 (Greek Modern DOS).
  • If the character was not Greek  there may be a codepage where each character needs to bytes (the codepage consists of two byte entries)

In the Unicode era the character has a single Unicode code 0x391 but many encodings dependig on how it is stored in memory

  • Greek Character A with code 0x391 is stored as CE 91 in two bytes in UTF-8.
  • Greek Characer A  with code 0x391 is stored as 03 91 in two bytes in UTF-16.
  • Greek Charater A has a different encoding in UTF-7 and so on.

Note that the fact that characters are no longer stored in 1 byte, changes the view we are used to have the 1 char = 1 byte. Clearly we should forget about that.

Now in C# we distinguish the following cases:

We know the encoding of a string and need to get the actual bytes used to present the string. For example we have a string in Unicode(the default) and want to get the actual bytes:

String test="Α";                          //The greek A
Encoding dst=Encoding.Unicode;
byte [] byteCode = dst.GeBytes(test);

The code above returns the acutal bytes used to store the string:

Note that the normal ToCharArrayMethod() would return a two-byte char as expected:

For a string to be displayed properly, it must be in Unicode. So it must be translated from the encoding/charset it is to Unicode. This is achieved through the Encoding.Convert (Encoding Source, Encoding Destination, Bytes of String); method. So to translate a string expressed in an encoding we need to guess we do as folows:

String Test="The received string in unknown encoding";
Encoding src=Encoding.GetEncoding(Encoding Name);    //Play here with candidate encoding names (to get the list of encodings try Encoding.GetEncodings();
Encoding dst=Encoding.Unicode;

byte [] ByteCodes=src.GetBytes(Test);
byte [] ResultCodes=Encoding.Convert(src,dst,ByteCodes);

String Result=new String (dst.GetChars(ResultCodes));

If the result is readable congratulations, you have found the encoding and can translate !

Download a demo exe app for Encodings here. If you need the source leave a message (EncodingsDemo.exe (18,00 kb)).

kick it on DotNetKicks.com

Tags:

.NET | Encodings

Powered by BlogEngine.NET 1.5.0.7

Programming Blogs - BlogCatalog Blog Directory Add to Technorati Favorites

MVP Award

Ioannis Panagopoulos





This blog is using BlogEngine.Net and is hosted in the hoster below. I have not experienced any problems installing BlogEngine.Net in the host and I am satisfied with the host's response times. Therefore I recommend it.


DiscountASP Add