Bassem Mohsen's Programming Blog

"High thoughts must have high language." —Aristophanes

  • The Author

    Bassem Mohsen - Freelance Windows and
    Web application developer. Technical writer. 24 yo. Based in Cairo, Egypt.

  • MCTS certification logo

Archive for July, 2011

Culture Info

Posted by Bassem Mohsen on July 15, 2011

Download the source code and binaries of the Culture Info project.
Run Culture Info (Works only for Internet Explorer with XBAPs enabled).

Introduction

The MSDN documentation says: "Windows ships with a set of locales, equivalent to .NET Framework cultures, that specify culture-specific information such as how text is sorted, how a date is formatted, and the display format of numbers and currency."
This culture information is intended for use by the code that performs culture-sensitive sorting and formatting. But I think that this information can be interesting in itself. For example it can be interesting to know the currency symbol for a certain country and whether a certain language is written from right to left.

Culture Info is an XBAP that presents you with a list of cultures installed on your computer. You can select a culture from the list to view information about this culture.

This application was developed to explore and practice with WPF binding, specifically binding to collections (where the binding source is a collection), and master-detail binding (where selecting an item from a list shows you details about this item).

Binding Item Controls to Collections

The collection acting as the binding source can be specified either in the binding expression or by setting the DataContext property of the bound element or one of its ancestors to the collection object. Because in the CulturesWindow many controls are bound to the same collection (the CultureInfo array), my choice was to set the DataContext of the Window to the collection object. This saves me from specifying the binding source in every binding expression.

CultureInfo[] specificCultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures);

this.DataContext = specificCultures;

<ComboBox

          ItemsSource="{Binding}" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True"

          SelectedItem="{Binding Source={x:Static glob:CultureInfo.CurrentCulture}, Mode=OneWay}">

    …

</ComboBox>

The above piece of XAML defines a ComboBox that is bound to the CultureInfo array, specifies that the items of the ComboBox should display the value of the ‘Name’ property of the array items, sets the SelectedItem to the static object returned by CultureInfo.CurrentCulture, and sets the Binding Mode of the second binding expression to OneWay because we do not want the selection change to update the binding source.

But what about the IsSynchronizedWithCurrentItem="True"?
When a collection is bound to by a WPF binding, an ICollectionView is created for that collection. Item controls display all the items of the collection, but content controls only display the CurrentItem of the CollectionView. Setting IsSynchronizedWithCurrentItem to true on the ComboBox ensures that the SelectedItem property of the ComboBox will always be equal to the CurrentItem property of the ICollectionView. Consequently, the content controls will display the properties of the item that is selected in the ComboBox. This is how master-detail binding is achieved.

Binding Content Controls to the CurrentItem in the CollectionView

Here is how a TextBlock was bound to the AlgorithType of the Calendar of the currently selected CultureInfo.

<TextBlock Text="{Binding Path=/Calendar.AlgorithmType}" />

The ‘/’ in the binding path means that Calendar is a property of the type of the CurrentItem in the CollectionView. The ‘.’ in the path means that AlgorithmType is a property of the type of Calendar. I admit that this is a bit confusing, but the documentation of the Binding.Path property explains very well the binding path syntax.

Grouping and Sorting

ICollectionView supports grouping collection items.

ICollectionView culturesCollectionView = CollectionViewSource.GetDefaultView(specificCultures);

culturesCollectionView.GroupDescriptions.Add(new PropertyGroupDescription("Parent"));

The first statement in the above code snippet uses the static method CollectionViewSource.GetDefaultView to get the ICollectionView created for the specificCultures array. The second statement adds a PropertyGroupDescription based on the ‘Parent’ property to the GroupDescriptions collection of ICollectionView. This has the effect of putting items having the same value for the CultureInfo.Parent property next to each other. But there is more, we can define a header for the groups.

<ComboBox …>

    <ComboBox.GroupStyle>

        <GroupStyle>

            <GroupStyle.HeaderTemplate>

                <DataTemplate>

                    <Border>

                        <!– Styling code omitted for brevity –>

                        <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" />

                    </Border>

                </DataTemplate>

            </GroupStyle.HeaderTemplate>

        </GroupStyle>

    </ComboBox.GroupStyle>

</ComboBox>

We define the header by setting the GroupStyle property of the item control to a GroupStyle object, and setting the HeaderTemplate of this GroupStyle to a DataTemplate object. The ‘Name’ property to which the Text property of the TextBlock is bound is actually a property of PropertyGroupDescription.

The following screenshot shows how grouped items are displayed in the ComboBox.

ComboBox With Grouping

ICollectionView also supports sorting. Sorting is achieved by adding a SortDescription to the SortDescriptions property of ICollectionView.

culturesCollectionView.SortDescriptions.Add(

    new SortDescription("Name", ListSortDirection.Ascending));

Here the sort is ascending and is based on the value of the ‘Name’ property (CultureInfo.Name).

Download the source code and binaries of the Culture Info project.
Run Culture Info (Works only for Internet Explorer with XBAPs enabled).

Posted in Small Software Projects | Tagged: , , , | Leave a Comment »