1 Previous Next 

WPF Bind to a Method


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>



1 Previous Next