My inner geek got really excited when I read about Custom Markup Extensions. Over the months I've become used to {binding} and {staticresource} but it never occured to me that I could use {myspecialmarkup} until I read about it. It turns out to be extremely easy - very similar to converters, in fact. Let's walk it through. Start by creating a new WPF application called WPFTest. Make sure the default namespace is also WPFTest because we will refer to it later. Good. Now add a new class file called MarkupExtension, and add a class called MyExtension which derives from MarkupExtension. There are two methods we will add. Look at the complete code below.
Imports System.Windows.Markup
Public Class MyExtension
Inherits MarkupExtension
Public Property Parameter As String
Public Sub New(Parameter As String)
_Parameter = Parameter
End Sub
Public Overrides Function ProvideValue(serviceProvider As System.IServiceProvider) As Object
Return "You said " & _Parameter
End Function
End Class
We are going to accept a single string in the constructor and save it to a property. When the XAML is loaded the ProvideValue method is called. We will return "You said " plus the string passed to the constructor. Whatever property is bound to MyExtension will receive this string. To reference our new markup extension we have to add an xmlns and a reference to the extension in MainWindow.xaml. Look at the xaml below...
<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 Thing}"/>
</Grid>
</Window>
The xmlns:local line tells the xaml that anything starting with local: can be resolved within the WPFTest assembly. When it sees local:My it looks for a class called MyExtension (the Extension is added automatically) in the WPFTest assembly. It will then call the constructor and pass the string 'Thing'. Later on, when it wants to know what value to put in the label's content it calls the ProvideValue method on the object it created earlier.
No comments:
Post a Comment