Archive for the ‘WPF’ Category

WPF Application Localization using Dynamics (C#)

Wednesday, September 1st, 2010

This was the first use-case for dynamics from C# 4.0 that I got into mind. One can bind the texts from XAML to a singleton class that publishs the text IDs as properties. Here a label is bound to a property called ‘Ready’:

<Label
    x:Name="labelStatus"
    Content="
      {
          Binding Source={x:Static text:TextProvider.Instance},
          Path=Ready
      }" />

The TextProvider singleton inherits DynamicObject and returns a text for each requested property. As ID, the property name is taken. It actually re-directs the calls to an object which is here called LocalizationDatabase:

public class TextProvider : DynamicObject
{
    public static TextProvider Instance
    {
        get
        {
            return instance;
        }
    }

    public override bool TryGetMember(
        GetMemberBinder binder,
        out object result)
    {
        result = LocalizationDatabase.Instance.GetText(binder.Name);
        return true;
    }

    private static TextProvider instance = new TextProvider();
}

WPF controls intercepting Undo/Redo (C#)

Tuesday, June 29th, 2010

If you want to implement your own Undo/Redo and prevent e.g. a TextBox from intercepting, attach to the command preview events through CommandManager.AddPreviewCanExecuteHandler and CommandManager.AddPreviewExecutedHandler and set the event.Handled flag to true:

MySomething()
{
    CommandManager.AddPreviewCanExecuteHandler(
        this,
        new CanExecuteRoutedEventHandler(OnPreviewCanExecuteHandler));
    CommandManager.AddPreviewExecutedHandler(
        this,
        new ExecutedRoutedEventHandler(OnPreviewExecutedEvent));
}
void OnPreviewCanExecuteHandler(object sender, CanExecuteRoutedEventArgs e)
{
    if (e.Command == ApplicationCommands.Undo)
    {
        e.CanExecute = true;
        e.Handled = true;
    }
    else if (e.Command == ApplicationCommands.Redo)
    {
        e.CanExecute = true;
        e.Handled = true;
    }
}
void OnPreviewExecutedEvent(object sender, ExecutedRoutedEventArgs e)
{
    if (e.Command == ApplicationCommands.Undo)
    {
        // DO YOUR UNDO HERE
        e.Handled = true;
    }
    else if (e.Command == ApplicationCommands.Redo)
    {
        // DO YOUR REDO HERE
        e.Handled = true;
    }
}

WPF Startingpoints

Saturday, March 13th, 2010

Essential Windows Presentation Foundation by Chris Anderson.

MSDN: Walkthrough: Create a Button by Using XAML

Sacha Barber’s ‘WPF: A Beginner’s Guide – Part 1 of n’ at Codeproject
Christian Moser’s page www.wpftutorial.net
MSDN Social: WPF FAQ

WPF ListView Example

Friday, March 12th, 2010

I am far away knowing how things work in WPF. For writing an own list view I needed quite much time. If it is done right? I can’t tell. Here how I understood things: Demo Project for Visual Studio 2008.

The goals were:

  1. Data is provided through data binding
  2. Support for different type of objects, each getting its own view
  3. Overwrite the default look with the blue selection background

A data bound WPF ListView in XAML with overwritten look using templates and template triggers:

<ListView Name="myListView" ItemsSource="{Binding MyList}">
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="SnapsToDevicePixels" Value="true"/>
            <Setter Property="OverridesDefaultStyle" Value="true"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Name="Border" Padding="2"
                                SnapsToDevicePixels="true"
                                Background="Transparent">
                            <ContentPresenter Name="Content" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="Border"
                                Property="Background" Value="Tomato"/>
                                <Setter Property="Foreground" Value="Yellow"/>
                                <Setter Property="FontWeight" Value="Bold" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="Gray"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="FontWeight" Value="Bold" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.Resources>
        <DataTemplate DataType="{x:Type local:MyItemBase}">
            <TextBlock Text="{Binding Path=Name}"></TextBlock>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:MyItemDerived}">
            <StackPanel>
                <TextBlock Text="{Binding Path=Name}"></TextBlock>
                <TextBlock Text="{Binding Path=Description}"></TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListView.Resources>
</ListView>

Here the document classes in c#. MyDocument contains the list. MyItemBase and MyItemDerived are the classes of items contained in the list. For both item classes a data template was defined in the XAML file:

public class MyItemBase
{
    private string name;

    public MyItemBase(string name)
    { Name = name; }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

public class MyItemDerived : MyItemBase
{
    private string description;

    public MyItemDerived(string name, string description)
        : base(name)
    { Description = description; }

    public string Description
    {
        get { return description; }
        set { description = value; }
    }
}

public class MyItemList
{
    private ObservableCollection<MyItemBase> myList
        = new ObservableCollection<MyItemBase>();

    public MyItemList()
    {
        myList.Add(new MyItemBase("Banana"));
        myList.Add(new MyItemBase("Apple"));
        myList.Add(new MyItemDerived("Orange", "Also a color"));
        myList.Add(new MyItemBase("Mango"));
    }

    public ObservableCollection<MyItemBase> MyList
    {
        get { return myList; }
    }
}

Here the view gets connected with the document:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        myListView.DataContext = new MyItemList();
    }
}

And here is how it looks in action (quite bad, eh?):

Screenshot of TestListView

References:

MDSN: ListView
MSDN: ListViewItem
MSDN: How to ListView

Codeproject: WPF custom ListBox with scrollbar on the background
SwitchOnTheCode: ListView tutorial with editable GridView

Blog: About ScrollViewer.CanContentScroll
Blog: Get rid of blue background 1
Blog: Get rid of blue background 2