.NET BLOG

Windows Presentation Foundation and more …

Text Clarity in WPF

In some cases there are problems with the clarity of small fonts. To avoid these problems you should know about how WPF renders text.

Have a look at the article Text Clarity in WPF to get an overview how WPF works in that case and how you can avoid the problems mentioned above.

A Beginner’s Guide to NHibernate

Hibernate is one of the mosed used O/R mappers in the Java world. For .NET NHibernate is available which can be downloaded under the given link. Hibernate is some years old and works pretty fine.

I’ve used this O/R mapper already for different projects. Therefore I am receiving questions concerning NHibernate very often. As this is not my main point of interet I haven’t wrote an article about NHibernate. As I got the question "How to start with NHibernate" again for several times within the last weeks I tried to find a very good resource for beginners. And here it is:

Your first NHibernate based application

This article should give you a very good entry point if you want to learn about NHibernate. Try the sample project and you should be able to use NHibernate within your solutions.

ObservableCollection and NHibernate

To develop data based applications brings up the need to use O/R mappers for translating your relational data to objects. Regarding to WPF there might come up the problem that NHibernate does not support ObservableCollection by default.

The ObservableCollection is necessary to notify changes within a collection to the data binding system of WPF.

Accidentally I found an article that comes up with a solution:

Bridge the Gap Between Your NHibernate Collections and WPF UI

This article includes a sample project as well.

Generic List an dynamic Type

I was asked, how a generic list based on a dynamic type can be loaded. Here is some code that comes up with a solution:

Type t = Type.GetType("System.String");
IList tempList = (IList)Activator.CreateInstance(
               (typeof(List<>).MakeGenericType(t))
            );
Console.WriteLine(tempList.GetType().FullName);

ListView within a ListView

I got the question how to display items within a ListView and their children in another ListView as a child item. This can be done very easily.

To create an example, we need our class hierarchy. For this we create a class called Parent, one called Child and the needed collections.

Parent

public class Parent
{
    private ChildCollection _children = new ChildCollection();

    public string FirstName { get; set; }
    public string LastName { get; set; }

    public ChildCollection Children
    {
        get { return _children; }
    }
}

public class ParentCollection : ObservableCollection<Parent>
{
}

Child

public class Child
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class ChildCollection : ObservableCollection<Child>
{
}

As we want to work with some test data,  we’ll create a data mock that will create the necessary data for us:

public static class DataMock
{
    private static ParentCollection _parents;

    public static ParentCollection GetParents()
    {
        if (_parents == null)
        {
            _parents = new ParentCollection();

            Parent p1 = new Parent() { FirstName = "Norbert", LastName = "Eder" };
            Parent p2 = new Parent() { FirstName = "Hugo", LastName = "Test" };

            Child c1 = new Child() { FirstName = "Child", LastName = "Uno" };
            Child c2 = new Child() { FirstName = "Child", LastName = "Due" };

            p1.Children.Add(c1);
            p2.Children.Add(c2);

            _parents.Add(p1);
            _parents.Add(p2);
        }
        return _parents;
    }
}

Within our XAML file (of a window for example) we create a ListView and set the ItemSource property to the result of our DataMock. This is done via code behind but can also be done via XAML.

Furthermore we need a template for displaying the parent items within the List View. This template defines two TextBlocks binded to the given data source. Then there is another ListView which exists for showing the children of the parent item. For this another template is needed which defines how the children are displayed.

Here’s the code:

<Window x:Class="DotNetGui.ListViewInListViewDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:DotNetGui.ListViewInListViewDemo"
    Title="Nested ListView Demo" Height="Auto" Width="Auto">
    <Window.Resources>

        <DataTemplate x:Key="ChildrenTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="100"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding LastName}" Grid.Column="0"/>
                <TextBlock Text="{Binding FirstName}" Grid.Column="1"/>
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="ParentTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <TextBlock Text="{Binding LastName}" Grid.Column="0" Grid.Row="0"/>
                <TextBlock Text="{Binding FirstName}" Grid.Column="1" Grid.Row="0"/>
                <ListView ItemsSource="{Binding Children}" ItemTemplate="{StaticResource ChildrenTemplate}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1" BorderThickness="0"/>
            </Grid>
        </DataTemplate>

    </Window.Resources>

    <Grid>
        <ListView x:Name="DataListView" ItemTemplate="{StaticResource ParentTemplate}"/>
    </Grid>
</Window>

And here is the result (it’s not the niciest, but this shouldn’t be the problem):

Nested ListView Dmeo

Difference between DataTemplate and ControlTemplate

I got this question very often via email. So I’ve decided to give an answer using my blog.

DataTemplate

A DataTemplate defines the visual tree of an data item represented within a ListBox, ListView or something similiar. This can either be for an object that inherits for example a ListBoxItem or is a simple CLR object.

ControlTemplate

A ControlTemplate describes the visual tree of an control. That means how a control is represented.

Conclusio

That means: Use the DataTemplate for items which are represented within an control which has a collection of items. Otherwise use the ControlTemplate.

And yes, this is a very simple anwer to the questions I got, but it should provide the important information. If not, leave a comment.

I am an MVP

Microsoft Most Valuable ProfessionalYezzzzzzz :) Two days ago I was awarded the Microsoft MVP for 2008. Category: Development Platforms - Client Application Development.

I got the MVP for my efforts in the German speaking communities, my weblog and several projects I started.

I am really happy about that! Thank you Microsoft and all others who supported me.

 

 

:)

WPF ListBox: Implement a "Hover-Selection"

Yesterday I was asked if it’s possible to implement a simple hover effekt for the WPF ListBox control. What does this mean? An item of a list box is selected when clicking it. But in this case the item should be selected on a mouse move.

To show how this can be done here is a complete example.

First of all, we need a simple data class which can be bound to our list box control:

namespace DotNetGui.ListBoxHooverSelector
{
    public class Person
    {
        private static int _counter = 0;

        public String FirstName { get; set; }
        public String LastName { get; set; }

        public static Person Build()
        {
            return new Person() { FirstName = "Test" + (_counter++).ToString(), LastName = "Tester" + (_counter++).ToString() };
        }
    }
}

After that we define the content of our window. This includes the list box as well as some data bound fields. Furthermore it includes a data template for the items of the list box:

<Window x:Class="DotNetGui.ListBoxHooverSelector.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ListBox Hoover Selector" Height="300" Width="400">

    <Window.Resources>

        <Style TargetType="{x:Type TextBox}">
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="BorderBrush" Value="LightGray"/>
            <Setter Property="Margin" Value="0 2 0 2"/>
        </Style>

        <DataTemplate x:Key="PersonTemplate">
            <StackPanel Orientation="Horizontal" MouseMove="StackPanel_MouseMove">
                <TextBlock Text="{Binding LastName}"/>
                <TextBlock Text=", "/>
                <TextBlock Text="{Binding FirstName}"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Border BorderBrush="LightGray" BorderThickness="1" CornerRadius="5" Padding="2" Margin="2" Grid.Column="0">
            <ListBox x:Name="PersonListBox" BorderThickness="0" ItemTemplate="{StaticResource PersonTemplate}"/>
        </Border>

        <StackPanel Orientation="Vertical" Grid.Column="1">
            <TextBlock Text="Firstname of selected person"/>
            <TextBox Text="{Binding SelectedItem.FirstName, ElementName=PersonListBox}"/>
            <TextBlock Text="Lastname of selected person"/>
            <TextBox Text="{Binding SelectedItem.LastName, ElementName=PersonListBox}"/>
        </StackPanel>
    </Grid>
</Window>

As shown in the XAML markup, we’ve created an event handler for the StackPanel which is defined for each item. This is needed to catch dthe MouseMove event.

Last but not least we have to fill up the list box with items and to handle the MouseMove event:

namespace DotNetGui.ListBoxHooverSelector
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            PersonListBox.Items.Add(new Person() { LastName = "Eder", FirstName = "Norbert" });
            PersonListBox.Items.Add(Person.Build());
            PersonListBox.Items.Add(Person.Build());
            PersonListBox.Items.Add(Person.Build());
            PersonListBox.Items.Add(Person.Build());
            PersonListBox.Items.Add(Person.Build());
            PersonListBox.Items.Add(Person.Build());
            PersonListBox.Items.Add(Person.Build());
        }

        private void StackPanel_MouseMove(object sender, MouseEventArgs e)
        {
            PersonListBox.SelectedItem = (sender as StackPanel).DataContext;
        }
    }
}

That’s all.

Download: ListBox Hover Selection Demo

UniformGrid - The simple Grid

There is a really simple Grid control in the namespace System.Windows.Controls.Primitives. It’s called UniformGrid. The only provided functionality is to display child elements in columns and rows of the same size. The order of the elements is given by it’s order they’ve been added.

Let’s have a look at some samples:

<UniformGrid>
    <Button Content="Button 1"/>
    <Button Content="Button 2"/>
    <Button Content="Button 3"/>
    <Button Content="Button 4"/>
</UniformGrid>

This defines a UniformGrid having four child elements of typ Button. The grid itself now measures the elements to the same size and calculates how many columns and rows are needed. In that case there will be two columns and two rows. Here is a screenshot:

UniformGrid with four child elements

The grid changes the layout if another button is added:

UniformGrid with five elements

As you can see, the amount of columns and rows is calculated automatically. This is the default behavior, but you can change this (a little bit).

There are to attributes called Columns and Rows. Using one of them (or both) you can define how many columns and rows should be displayed. If you provide just one of these attributes the other one is calculated automatically.

Here’s an example:

<UniformGrid Columns="2" Rows="3">
    <Button Content="Button 1"/>
    <Button Content="Button 2"/>
    <Button Content="Button 3"/>
    <Button Content="Button 4"/>
    <Button Content="Button 5"/>
</UniformGrid>

And that’s the result:

UniformGrid with two columns and three rows

But be carefull. If there are more elements than defined through Columns and Rows just that element are shown which can be placed in the grid:

<UniformGrid Columns="2" Rows="2">
    <Button Content="Button 1"/>
    <Button Content="Button 2"/>
    <Button Content="Button 3"/>
    <Button Content="Button 4"/>
    <Button Content="Button 5"/>
</UniformGrid>

UniformGrid with more elements than defined trough Columns and Rows

It’s not THAT really cool control, but it makes sense in some cases. So keep it in mind.

WPF: How to implement the "Open Windows" Feature

A lot of applications which are using multiple windows show them within a "Window" menu. This article shows how you can implement such a feature in your WPF application. The result can be look like the following screen shot (which isn’t very nice, but it does the job):

WPF Open Windows List

First of all: Is there no ready-to-use implementation in WPF? Yes there is. Application.Current.Windows provides a collection of all open windows of you application. The disadvantage is that the collection isn’t an ObservableCollection, so you can’t use data binding and we have to implement our own system.

The first implementation step is to create a simple data class which will hold a reference to an open window. In this case it’s just a simple wrapper but there might be added some features in future.

public class WindowInformation
{
    private Window _window; 

    public WindowInformation(Window window)
    {
        _window = window;
    }

    public Window Window
    {
        get { return _window; }
    }

    public int WindowHashCode
    {
        get { return _window.GetHashCode(); }
    }

    public String Title
    {
        get { return _window.Title; }
    }

    public ImageSource Icon
    {
        get { return _window.Icon; }
    }
}

To get the possibility to use data binding, we create a simple collection which inherits ObervableCollection and holds a list of WindowInformation-objects.

public class WindowInformationCollection :
    ObservableCollection<WindowInformation>
{
}

The next step is to create a manager class which enables some functionality to manage access to the collection of windows as well as features to remove and get windows. It is implemented using the singleton pattern so that there can be only one instance within your whole application.

public class WindowManager
{
    private static WindowManager _manager;

    private WindowInformationCollection _openWindows =
        new WindowInformationCollection();

    private WindowManager() { }

    public static WindowManager GetInstance
    {
        get
        {
            if (_manager == null)
                _manager = new WindowManager();
            return _manager;
        }
    }

    public WindowInformationCollection OpenWindows
    {
        get { return _openWindows; }
    }

    public Window GetOpenWindow(int hashCode)
    {
        foreach (WindowInformation wi in _openWindows)
        {
            if (wi.WindowHashCode == hashCode)
            {
                return wi.Window;
            }
        }
        return null;
    }

    public bool RemoveOpenWindow(int hashCode)
    {
        WindowInformation windowToRemove = null;
        foreach (WindowInformation wi in _openWindows)
        {
            if (wi.WindowHashCode == hashCode)
            {
                windowToRemove = wi;
                break;
            }
        }
        if (windowToRemove != null)
        {
            _openWindows.Remove(windowToRemove);
            return true;
        }
        return false;
    }
}

As you can see, I am working with the hash code of each window. This code should be unique in most cases. It is very bad to work with the title of a window as it can change and the "reference" breaks.

Now we need something like handler. This handler is used to mark a window to be handled by our system:

public class WindowInformationHandler
{
    public static readonly DependencyProperty IsHandledProperty =
    DependencyProperty.RegisterAttached("IsHandled",
        typeof(bool), typeof(WindowInformationHandler),
        new FrameworkPropertyMetadata((bool)false,
            new PropertyChangedCallback(OnIsHandledChanged)));

    private static void OnIsHandledChanged(
        DependencyObject dObj,
        DependencyPropertyChangedEventArgs e)
    {
        Window openWindow = dObj as Window;
        if (openWindow != null)
        {
            openWindow.Loaded += new RoutedEventHandler(WindowLoaded);
            openWindow.Closed += new EventHandler(WindowClosed);
        }
    }

    public static bool GetIsManaged(DependencyObject dObj)
    {
        return (bool)dObj.GetValue(IsHandledProperty);
    }

    public static void SetIsManaged(DependencyObject dObj, bool value)
    {
        dObj.SetValue(IsHandledProperty, value);
    }

    private static void WindowClosed(object sender, EventArgs e)
    {
        Window closedWindow = sender as Window;
        if (closedWindow != null)
        {
            WindowManager.GetInstance.RemoveOpenWindow(closedWindow.GetHashCode());
            openWindow.Loaded -= new RoutedEventHandler(WindowLoaded);
            openWindow.Closed -= new EventHandler(WindowClosed);
        }
    }

    private static void WindowLoaded(object sender, RoutedEventArgs e)
    {
        Window openWindow = sender as Window;
        if (openWindow != null)
        {
            WindowInformation winInfo = new WindowInformation(openWindow);
            WindowManager.GetInstance.OpenWindows.Add(winInfo);
        }
    }
}

This class includes a dependency property so that we are able to use this easily from our XAML file. If the property IsHandled is set to true, two events of the window will be registered: Loaded and Closed. If the window is loaded we create an instance of our type WindowInformation which is added to our collection of all open windows.

If the window is closed, the reference will be removed from the collection of open windows and the registered events are unregistered.

To get a window handled by this system you have to add the following XAML to the Window element:

local:WindowInformationHandler.IsManaged="true"

That’s all.

The example application uses the following XAML:

<Window.Resources>
    <DataTemplate x:Key="WindowTemplate">
        <MenuItem Header="{Binding Title}"
                  Icon="{Binding WindowIcon}"
                  Click="ShowWindow"/>
    </DataTemplate>
</Window.Resources>

<Grid>
    <Menu>
        <MenuItem Header="File">
            <MenuItem Header="New Window …"
                      Click="NewWindow"/>
        </MenuItem>
        <MenuItem Header="Edit"/>
        <MenuItem x:Name="mnuWindows"
                  Header="Windows"
                  ItemTemplate="{StaticResource WindowTemplate}"/>
    </Menu>
</Grid>

The code behind file looks as follows (please note that you can set the data binding also within the XAML markup):

public MainWindow()
{
    InitializeComponent();

    mnuWindows.ItemsSource = WindowManager.GetInstance.OpenWindows;
}

private void NewWindow(object sender, RoutedEventArgs e)
{
    MainWindow window = new MainWindow();
    window.Title = String.Format("Open Window {0}",
        Application.Current.Windows.Count);
    window.Show();
}

private void ShowWindow(object sender, RoutedEventArgs e)
{
    MenuItem mi = sender as MenuItem;
    if (mi != null)
    {
        WindowInformation wi = mi.DataContext
            as WindowInformation;
        if (wi != null)
        {
            wi.Window.Focus();
        }
    }
}

If you have any suggestions, please let me know.