In this part we will bind to a method. As we type a number into a textbox the
results will be displayed in label below it. For this example we use a class
which figures out the area of a circle.
Let's start off with a class which calculates the area of a circle. This
class has one function named CalculateArea.
Public Class
Area
Public Function CalculateArea(ByVal Radius
As Double) As Double
Return
Math.PI * Radius ^ 2
End Function
End Class
Now that we have a class set up to calculate the area we need 2 additonal
classes. The first needs to inherit from ValidationRule to alert the user if
they enter an incorrect value (textbox's border turns red for invalid values).
The other need to inherit from IValueConveter to convert the user input from
string to double and back again.
Imports System.Windows.Controls
Imports
System.Windows.Data
Public Class
ValidDouble
Inherits
ValidationRule
Public Overrides Function
Validate(ByVal value As Object, ByVal cultureInfo As
System.Globalization.CultureInfo) As
System.Windows.Controls.ValidationResult
Dim
num As Double
If
Double.TryParse(value.ToString, num)
Then
Return
New ValidationResult(True,
Nothing)
Else
Return
New ValidationResult(False, "Invalid
Number")
End
If
End Function
End Class
Public Class
DoubleToString
Implements
IValueConverter
Public Function Convert(ByVal
value As Object, ByVal targetType As System.Type, ByVal parameter As Object,
ByVal culture As System.Globalization.CultureInfo) As Object Implements
System.Windows.Data.IValueConverter.Convert
If
value IsNot Nothing
Then
Return
value.ToString
Else
Return
Nothing
End
If
End Function
Public
Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type,
ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As
Object Implements
System.Windows.Data.IValueConverter.ConvertBack
Dim
num As Double
If (value IsNot
Nothing) AndAlso Double.TryParse(value.ToString, num)
Then
Return
num
Else
Return
Nothing
End
If
End Function
End Class
Now that we have the classes we need its time to register the namespaces with
the form.
<Window
x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFBindToMethod"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="WPFBindToMethod"
Height="300" Width="300"
>
Finally we will use an ObjectDataProvider to bind to the method and register
the ValidationRule with the form.
<Window.Resources>
<ObjectDataProvider
ObjectType="{x:Type
local:Area}"
MethodName="CalculateArea"
x:Key="CircleArea">
<ObjectDataProvider.MethodParameters>
<system:Double>0</system:Double>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:DoubleToString
x:Key="doubleToString"
/>
</Window.Resources>
The Form's complete XAML
<Window
x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFBindToMethod"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="WPFBindToMethod"
Height="300"
Width="300"
>
<Window.Resources>
<ObjectDataProvider
ObjectType="{x:Type
local:Area}"
MethodName="CalculateArea"
x:Key="CircleArea">
<ObjectDataProvider.MethodParameters>
<system:Double>0</system:Double>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:DoubleToString
x:Key="doubleToString"
/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition
/>
<ColumnDefinition
Width="140"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition
Height="30"
/>
<RowDefinition
Height="30"
/>
</Grid.RowDefinitions>
<Label
Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right">Radius
of the Circle:</Label>
<TextBox
Grid.Row="0" Grid.Column="1"
Name="tb">
<TextBox.Text>
<Binding
Source="{StaticResource CircleArea}"
Path="MethodParameters[0]"
BindsDirectlyToSource="true"
UpdateSourceTrigger="PropertyChanged"
Converter="{StaticResource
doubleToString}">
<Binding.ValidationRules>
<local:ValidDouble/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Label
Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right">Area of
the Circle:</Label>
<Label
Grid.Column="1" Grid.Row="1" Content="{Binding Source={StaticResource
CircleArea}}"></Label>
</Grid>
</Window>