Thursday, December 12, 2013

Custom Markup Extensions using named parameters

WPF Version 4.0

In my previous blog I showed how to build and consume a custom markup extension using positional parameters. But some of your most popular markup extensions have formats like...

{Binding Path=Amount}

which uses a named parameter. In this case the name is Path and the value is Amount. What would the Markup Extension look like? Well, it would have a public property called Path. Let's take our example from the previous post and modify it to use a named parameter called 'Name'. The markup extension code would look like this...

Imports System.Windows.Markup
Public Class MyExtension
    Inherits MarkupExtension

    Public Property Name As String
   
    Public Overrides Function ProvideValue(serviceProvider As System.IServiceProvider) As Object
        Return "You said " & _Name
    End Function
End Class

I renamed the Parameter property to Name and removed the constructor. If there are no positional parameters you don't need one - the default will do. After instantiating the object the XAML parser will assign each named parameter to an identically named public property. If it fails for any reason it will throw an error.

Here's the xaml that references MyExtension using a named value

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPFTest"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Label Content="{local:My Name=Thing}"/>
    </Grid>
</Window>


As you type the xaml that references your markup extension intellisense automatically knows the list of public properties and displays them.


Note: Of course you could also specify the label's content with this xaml.

    <Grid>
        <Label>
            <Label.Content>
                <local:MyExtension Name="Thing"/>
            </Label.Content>
        </Label>
    </Grid>
</Window>

No comments:

Post a Comment