1 Previous Next 

WPF OneWay Binding Part 2


In the last part we bound a label to the value of the scrollbar. In this part we will format the scrollbar's value before we display it.


To be able to format the output of a bound value you need a class which inherits from IValueConverter. For this example I am using the NumbersToWords function found here to convert the number to a word for display.



Public Class NumberToWord
    Implements IValueConverter


    Private Function NumbersToWords(ByVal num As Decimal) As String
        Dim power_value(5) As Decimal
        Dim power_name(5) As String
        Dim digits As Integer
        Dim result As String
        Dim i As Integer

        ' Initialize the power names and values.
        power_name(1) = "trillion" : power_value(1) = 1000000000000.0#
        power_name(2) = "billion" : power_value(2) = 1000000000
        power_name(3) = "million" : power_value(3) = 1000000
        power_name(4) = "thousand" : power_value(4) = 1000
        power_name(5) = "" : power_value(5) = 1
        For i = 1 To 5
            ' See if we have digits in this range.
            If num >= power_value(i) Then
                ' Get the digits.
                digits = Int(num / power_value(i))
                ' Add the digits to the result.
                If Len(result) > 0 Then result = result & ", "
                result = result & Words_1_999(digits) & " " & power_name(i)
                ' Get the number without these digits.
                num = num - digits * power_value(i)
            End If
        Next i
        NumbersToWords = Trim$(result)
    End Function

    ' Return words for this value between 1 and 999.
    Private Function Words_1_999(ByVal num As Integer) As String
        Dim hundreds As Integer
        Dim remainder As Integer
        Dim result As String
        hundreds = num \ 100
        remainder = num - hundreds * 100
        If hundreds > 0 Then
            result = Words_1_19(hundreds) & " hundred "
        End If
        If remainder > 0 Then
            result = result & Words_1_99(remainder)
        End If
        Words_1_999 = Trim$(result)
    End Function

    ' Return a word for this value between 1 and 19.
    Private Function Words_1_19(ByVal num As Integer) As String
        Select Case num
            Case 1
                Words_1_19 = "one"
            Case 2
                Words_1_19 = "two"
            Case 3
                Words_1_19 = "three"
            Case 4
                Words_1_19 = "four"
            Case 5
                Words_1_19 = "five"
            Case 6
                Words_1_19 = "six"
            Case 7
                Words_1_19 = "seven"
            Case 8
                Words_1_19 = "eight"
            Case 9
                Words_1_19 = "nine"
            Case 10
                Words_1_19 = "ten"
            Case 11
                Words_1_19 = "eleven"
            Case 12
                Words_1_19 = "twelve"
            Case 13
                Words_1_19 = "thirteen"
            Case 14
                Words_1_19 = "fourteen"
            Case 15
                Words_1_19 = "fifteen"
            Case 16
                Words_1_19 = "sixteen"
            Case 17
                Words_1_19 = "seventeen"
            Case 18
                Words_1_19 = "eightteen"
            Case 19
                Words_1_19 = "nineteen"
            Case Else
                Words_1_19 = ""
        End Select
    End Function

    ' Return a word for this value between 1 and 99.
    Private Function Words_1_99(ByVal num As Integer) As String
        Dim result As String
        Dim tens As Integer
        tens = num \ 10
        If tens <= 1 Then ' 1 <= num <= 19
            result = result & " " & Words_1_19(num)
        Else
            ' 20 <= num
            ' Get the tens digit word.
            Select Case tens
                Case 2
                    result = "twenty"
                Case 3
                    result = "thirty"
                Case 4
                    result = "forty"
                Case 5
                    result = "fifty"
                Case 6
                    result = "sixty"
                Case 7
                    result = "seventy"
                Case 8
                    result = "eighty"
                Case 9
                    result = "ninety"
            End Select
            ' Add the ones digit number.
            result = result & " " & Words_1_19(num - tens * 10)
        End If
        Words_1_99 = Trim$(result)
    End Function

    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
        Dim d As Double
        If Double.TryParse(value.ToString, d) Then
            Return NumbersToWords(CDec(d))
        Else
            Return value
        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
        Return Nothing
    End Function
End Class


Now that we created the class we need to register the xml namespace with the window. The namespace you need to use for this is clr-namespace:NamespaceName. In this case it is the applications name. I am adding the local prefix so we can reference it later.


<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:WPFOneWayBind"
    Title="WPFOneWayBind" Height="300" Width="300"
    >


Now we need to make the converter a resource for the window.


  <Window.Resources>
    <local:NumberToWord x:Key="conv"></local:NumberToWord>
  </Window.Resources>



Right after we set the path for the binding we can specify the converter. The converter is a StaticResource of the window.


      <Label   HorizontalAlignment="Center" DataContext="{Binding ElementName=hscroll, Mode=OneWay}"
               Content="{Binding Path=Value, Converter = {StaticResource conv}}"  />


Here is the windows 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:WPFOneWayBind"
    Title="WPFOneWayBind" Height="300" Width="300"
    >
  <Window.Resources>
    <local:NumberToWord x:Key="conv"></local:NumberToWord>
  </Window.Resources>
    <Grid>
      <StackPanel>
      <ScrollBar Name="hscroll" Maximum="100"  Minimum="1" SmallChange="1" LargeChange="10" Orientation="Horizontal"></ScrollBar>
      <Label   HorizontalAlignment="Center" DataContext="{Binding ElementName=hscroll, Mode=OneWay}"
               Content="{Binding Path=Value, Converter = {StaticResource conv}}"  />
      </StackPanel>
    </Grid>
</Window>




1 Previous Next