Thursday, December 12, 2013

Custom Markup with multiple constructors

As we saw in earlier blogs, it is easy to create Markup Extensions. They are simply classes that inherit from MarkupExtension. When you use positional, instead of named, parameters the xaml parser looks for a constructor that matches the signature in the markup. This lets us do some interesting things. Let's suppose we wanted to write a markup extension that calculates the area of a circle, rectangle, or triangle simply by passing one, two, or three integers. We just write three constructors. Here's the markup extension code.

Imports System.Windows.Markup
Public Class AreaExtension
    Inherits MarkupExtension

    Private Area As Double
    Private Text As String
    Public Sub New(r As Integer)
        Area = Math.PI * (r ^ 2)
        Text = "Area of circle of radius " & r & " is " & Math.Round(Area, 2)
    End Sub
    Public Sub New(x As Integer, y As Integer)
        Area = x * y
        Text = "Area of rectangle of sides " & x & " and " & y & " is " & Area
    End Sub
    Public Sub New(s1 As Integer, s2 As Integer, s3 As Integer)
        Dim s As Integer = (s1 + s2 + s3) / 2
        Area = Math.Sqrt(s * (s - s1) * (s - s2) * (s - s3))
        Text = "Area of triangle with sides " & s1 & ", " & s2 & ", and " & s3 & " is " & Math.Round(Area, 2)
    End Sub
    Public Overrides Function ProvideValue(serviceProvider As System.IServiceProvider) As Object
        Return Text
    End Function
End Class
See the three constructors? Now this is how we call them.
<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">
    <WrapPanel>
        <Label Width="400" Content="{local:Area 2}"/>
        <Label Width="400" Content="{local:Area 3,4}"/>
        <Label Width="400" Content="{local:Area 5,6,7}"/>
    </WrapPanel>
</Window>

And here's the result.

No comments:

Post a Comment