Archive for the ‘C#’ 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();
}

Homebrew UnitTest (C#)

Thursday, August 26th, 2010

Just instantiate by calling constructor with type of class to be tested. All methods either public or private with the following signature are called where SNAFU can be replaced by anything:

static void TestSNAFU();

Probably the most stupid approach… but works.

public class UnitTest
{
    public UnitTest(Type type)
    {
        IEnumerable<MethodInfo> methods =
            from
                method
            in
                type.GetMethods(System.Reflection.BindingFlags.Static
                | System.Reflection.BindingFlags.Public
                | System.Reflection.BindingFlags.NonPublic)
            where
                method.Name.StartsWith("Test")
                && method.ReturnType == typeof(void)
                && method.GetParameters().Length == 0
            select
                method;

        foreach (var m in methods)
        {
            m.Invoke(null, new object[] { });
        }
    }
}

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;
    }
}

Convert DOS wildcards to Regex search pattern (C#)

Saturday, May 8th, 2010

Based on Codekeep by Stephen Smith. Additionally I escape backslash:

public static string WildcardToRegex(string pattern)
{
    return ("^" +
         pattern.Replace(@"\", @"\\")
         .Replace("(", @"\(")
         .Replace(")", @"\)")
         .Replace(".", @"\.")
         .Replace("*", "(.*)")
         .Replace("?", "(.{1,1})"));
        }
}

Here some testcode:

string[] texts = new string[]
{
    @"\\VirtualDrive\Test1.mp3",
    @"\\VirtualDrive\Test2.mp3",
    @"\\VirtualDrive\Test3.bin"
};

string wildCards = @"\\VirtualDrive\*.mp3";
string pattern = WildcardToRegex(wildCards);

string[] result =
    (from t in texts
    where RegularExpressions.Regex.IsMatch(t, pattern, RegexOptions.IgnoreCase)
    select t).ToArray();

UnitTest.Test(result.Length == 2);
UnitTest.Test(result[0] == texts[0]);
UnitTest.Test(result[1] == texts[1]);

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