Showing posts with label XAML. Show all posts
Showing posts with label XAML. Show all posts

Monday, 23 April 2007

XAML Support in Resharper 3.0

I am an avid Jetbrains Resharper user and have been for years, I really think it increases the usability of Visual Studio above and beyond that provided by Microsoft. I regularly return to their site to check on the new releases and see what they're working on, and just noticed that they have started adding some support for XAML to their latest EAP Release. So having installed it and opened my solution, I open a XAML file to see what has happened. You can immediately see that Resharper is having an effect because things show up in completely different colours - there seems to be some processing happening on every tag in the XAML file (this processing all happens in the background so doesn't slow things down very much). So, now type names show up in blue and property names show up in purple. This is consistent with the rest of Resharpers colourings, although these are of course configurable. When you have the keyboard over a tag, there are now two context sensitive options, these are "Replace all tags" and "Replace all attributes". I think this just comes from the new changes they have made for XML refactoring and aren't hugely useful for XAML. It might be useful if you want to replace all TextBoxes with say, Labels or something, or if you rename a property on a type and want all references to be renamed (although I imagine this will eventually happen automatically). The only truly useful feature I can find simply comes from the fact that references are being resolved, so the existing Resharper feature of "Go To Definition (Ctrl+B) can be used on them. So you can now press Ctrl+B on any property or object name and get instantly taken to the definition of that. This is great for Styles and other resources (e.g. where you have Style="{StaticResource MyStyle}" you can navigate straight to the style) and using it on anything else seems to take you to the object browser for that type or property (previously you would just get taken to relevant line in the XmlPresentation.xsd file). That's about it really - overall I can't see much extra that this is adding to the XAML user experience, but I can see, by programatically resolving references that they are laying the groundworks for some very useful features. However there is still a lot to do on this subject - for example, open any complex XAML file and the first thing you will notice if you are using any custom namespaces or custom controls, is that Resharper is not picking them up. They do state on their site that they are working on improving this.

Tuesday, 6 February 2007

Using a ComboBox to select an Enum value in XAML

It is often a requirement in UI to provide a combo box which is used to select an Enum value. There are many ways to achieve this task. However, some are more elegant than others. Here I present a simple way to do this which uses nothing but XAML.

Firstly, we wish to get all the possible values of the Enum and set them to the ItemsSource of the ComboBox. For this, we can utilise the static GetValues() method on the Enum class. This can be done in XAML using an ObjectDataProvider. We then bind the ItemsSource property of our ComboBox to the ObjectDataProvider.

For this example, I am displaying the "BindingMode" enumeration which is built into WPF.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <Page.Resources>
        <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="PossibleValues">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="BindingMode" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Page.Resources>
    <ComboBox ItemsSource="{Binding Source={StaticResource PossibleValues}}" SelectedValue="{Binding Source={StaticResource PossibleValues}, Path=[4]}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Page>

Note that in order to use the GetValues() method, we need to include a reference to the System namespace in the mscorlib assembly.

So now we have a ComboBox which looks something like this:

Well that's all good, but we can do better than that! In most applications we want to provide descriptive text for the values than just the ToString() of the Enum.

As usual, DataTemplates come to our rescue - we can do it as follows:

<DataTemplate DataType="{x:Type BindingMode}">
    <TextBlock Text="{Binding}" x:Name="PART_Text" />
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding}" Value="OneWay">
            <Setter TargetName="PART_Text" Property="Text" Value="One way binding" />
            <Setter TargetName="PART_Text" Property="FontWeight" Value="Bold" />
        </DataTrigger>
        <DataTrigger Binding="{Binding}" Value="TwoWay">
            <Setter TargetName="PART_Text" Property="Text" Value="Two Way Binding" />
        </DataTrigger>
        <DataTrigger Binding="{Binding}" Value="OneTime">
            <Setter TargetName="PART_Text" Property="Visibility" Value="Collapsed" />
        </DataTrigger>
        <DataTrigger Binding="{Binding}" Value="OneWayToSource">
            <Setter TargetName="PART_Text" Property="Text" Value="One Way To Source Binding" />
        </DataTrigger>
        <DataTrigger Binding="{Binding}" Value="Default">
            <Setter TargetName="PART_Text" Property="Text" Value="Default Binding" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

Here is the final ComboBox:

I could have been more adventurous and used some images or colours or anything really in the DataTemplate, but I hope this example is enough to demonstrate what you can achieve.

Friday, 29 December 2006

WPF/XAML - x:Type and nested classes

Well now I am getting started with XAML and WPF I am hoping to start blogging a bit more! So I was trying to reference a nested type with the {x:Type} markup extension and it wasn't working. Say you have a class as follows:

public class MyClass
{
    public class MyInnerClass
    {
    }
}

You want to reference the inner class (e.g. for a DataTemplate). The following XAML does not work

<DataTemplate DataType="{x:Type MyClass.MyInnerClass}">

What you need to do is:

<DataTemplate DataType="{x:Type MyClass+MyInnerClass}">

Thanks to Seb for the hint on that one!