Building an Enterprise App with WPF, MVVM, and Entity Framework
After you've started to build your first enterprise app with WPF, MVVM, and Entity Framework, some questions like these might pop up:
(more…)
Note: There's a MS Dev Show Episode where @ytechie, @carlschweitzer and I are talking about UWP and the Visual Studio Shell built as part of this post. You find it here on www.msdevshow.comUWP is the technology to build native applications for the Windows Platform. But there's still some stuff missing that is required by a typical line-of-business application for the classic desktop: TreeView, DataGrid, Validation, SqlClient and more. Some parts like a DataGrid are available as 3rd-party controls. Other parts like the TreeView are already in development, as you can see in the Windows Dev Platform Backlog. That backlog shows that Microsoft is working on a TreeView, which is awesome! And I'm pretty sure, at some point in the future we'll also get a DataGrid. This was the case for WPF and also for Silverlight. But let's see, the future will tell us and for today we've great 3rd-party DataGrids. But what else is required to build a classic desktop application? (more…)
namespace UIRocker.Special
{
public class WindowsEight
{
public bool IsGreat { get; set; }
}
}
To use this class in Silverlight-XAML, you’ve to add an Namespace-Mapping like this
xmlns:rocker="clr-namespace:UIRocker.Special"
or like this if the CLR-Namespace is in another assembly than the XAML-file containing the Namespace-Mapping below:
xmlns:rocker="clr-namespace:UIRocker.Special; assembly=UIRockerLib"
With the Namespace-Mapping the classes from that Namespaces can be used with the chosen alias. The alias is “rocker” in the snippets above, so the WindowsEight-class can be used as below:
<rocker:WindowsEight IsGreat="True"/>
In WinRT-XAML you’re using the class in the same way as above, but the way of creating the Namespace-Mapping is different. Instead of using the syntax with “clr-namespace…” you use:
xmlns:rocker="using:UIRocker.Special"
You don’t care if the Namespace UIRocker.Special is in another assembly as the XAML-file or not. This works exactly the same way as the using-directive in C#, where you also don’t care if the Namespace is in another assembly than the .cs-File or not. So, great improvement, but creates a little incompability with Silverlight-XAML.
[assembly: XmlnsDefinition(
"http://thomasclaudiushuber.com/","UIRocker.Special")]
[assembly: XmlnsDefinition(
"http://thomasclaudiushuber.com/", "UIRocker.Mvvm")]
Classes out of the Namespaces UIRocker.Special and UIRocker.Mvvm can be used in XAML with one alias by making a 1:n-Namespace-Mapping like this:
xmlns:rocker="http://thomasclaudiushuber.com/"
Unfortunately in WinRT-XAML there is no possibility for a 1:n-Mapping. The Namespace Windows.UI.Xaml.Markup contains a XmlnsDefinition, but it’s not an attribute, it’s a struct and therefore not usable.
Especially when you create a library with many Namespaces in it, it’s great to use just one alias for the library in XAML. Maybe the next Version of WinRT will contain such a mapping. By the way, first versions of Silverlight also didn’t support 1:n-Namespace-Mappings.
<ListBox Background="Red">
The XAML-Parser takes the “Red”-string, creates a SolidColorBrush with the Color Red and assigns it to the Background-property of the ListBox.
(Excourse to WPF-XAML: In WPF-XAML this conversion is not done by the XAML-Parser, it is done by the BrushConverter-class)
Now if you have properties that are of your own type, let’s look at this works in Silverlight and WinRT. Let’s assume we have the classes below:
public class Person
{
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
public string Country { get; set; }
}
In Silverlight-XAML, it is possible to create a Person-instance as below if a TypeConverter for the Address-type exists:
<local:Person Address="Müllheim Germany"/>
The corresponding typeconverter could look like this:
public class AddressConverter : TypeConverter
{
public override bool CanConvertFrom(...Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(...object value)
{
if (value != null && value is string)
{
var array = value.ToString().Split(' ');
if (array.Length != 2)
throw new ArgumentOutOfRangeException(
"Invalid format for address");
return new Address
{
City = array[0],
Country = array[0]
};
}
return base.ConvertFrom(value);
}
}
The only thing that is additionally required is to tell the XAML-Parser where to find the AddressConverter. You do this by specifying the TypeConverterAttribute either on the Address-Property in the Person-class or on the Address-class itself. Below an example that specifies it on the Address-class.
public class Person
{
public Address Address { get; set; }
}
[TypeConverter(typeof(AddressConverter))]
public class Address
{
public string City { get; set; }
public string Country { get; set; }
}
So far to Silverlight-XAML, now let’s look at WinRT-XAML. As mentioned above, WinRT-XAML also supports conversion for