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>