WPF 中的自定义值转换





3.00/5 (14投票s)
本文档描述了如何在 WPF 中执行自定义值转换。
引言
在 WPF 中,可以使用自定义值转换器将数据从一种类型转换为另一种类型。自定义转换器可用于实现自定义逻辑,将一个值转换为另一个值。为了演示本文,我使用 Visual C# 2010 Express Edition 开发了一个应用程序,该应用程序将十进制值作为输入,并将其转换为二进制、八进制和十六进制值。
背景
要创建自定义转换器,我们需要在用户定义的转换器类中实现 IValueConverter
接口。IValueConverter
接口有两个方法,我们必须在类中实现这些方法。这些方法如下:
Convert
:此方法将源值转换为目标值。此方法的签名如下:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
在此方法中,我们编写自定义转换的逻辑。
ConvertBack
:此方法将值从目标转换回源值。此方法的签名与 Convert
方法相同。如果不想将值转换回源值,则可以避免在此方法中编写自定义代码。Using the Code
以下 XAML 代码用于定义应用程序的用户界面:
<Window x:Class="NumberSystemConversion.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:NumberSystemConversion"
Background="BlanchedAlmond"
Title="Number System Converter" Height="350" Width="600">
<Window.Resources>
<local:NumberSystemConverter x:Key="myConverter"/>
</Window.Resources>
<Canvas>
<Label Canvas.Left="100" Canvas.Top="10" FontFamily="Comic Sans MS"
FontSize="32" Foreground="Fuchsia">Number System Converter</Label>
<Label Canvas.Left="40" Canvas.Top="100" FontFamily="Aharoni" FontSize="24"
Foreground="BlueViolet">Enter a Decimal Number: </Label>
<TextBox Name="txtDecimal" Canvas.Left="330" Canvas.Top="100" Width="225"
FontFamily="Aharoni" FontSize="24"
Foreground="BlueViolet" Background="LightPink"/>
<Label Canvas.Left="220" Canvas.Top="150" FontFamily="Lucida Console"
FontSize="24" Foreground="Red">Binary:</Label>
<TextBlock Name="txtBinary" Canvas.Left="330" Canvas.Top="150" Width="225"
FontFamily="Lucida Console" FontSize="24" Foreground="Red" Background="LightPink"
Text="{Binding ElementName=txtDecimal,Path=Text,Converter={StaticResource myConverter},ConverterParameter=2}"/>
<Label Canvas.Left="233" Canvas.Top="200" FontFamily="Lucida Console"
FontSize="24" Foreground="Green">Octal:</Label>
<TextBlock Name="txtOctal" Canvas.Left="330" Canvas.Top="200" Width="225"
FontFamily="Lucida Console" FontSize="24" Foreground="Green" Background="LightPink"
Text="{Binding ElementName=txtDecimal,Path=Text,Converter={StaticResource myConverter},ConverterParameter=8}"/>
<Label Canvas.Left="147" Canvas.Top="250" FontFamily="Lucida Console"
FontSize="24" Foreground="Blue">Hexadecimal:</Label>
<TextBlock Name="txtHexadecimal" Canvas.Left="330" Canvas.Top="250" Width="225"
FontFamily="Lucida Console" FontSize="24" Foreground="Blue" Background="LightPink"
Text="{Binding ElementName=txtDecimal,Path=Text,Converter={StaticResource myConverter},ConverterParameter=16}"/>
</Canvas>
</Window>
在上面的代码中,我创建了一个名为 myConverter
的窗口资源,它指向我们的自定义转换器类 NumberSystemConverter
。使用名为 txtDecimal
的 TextBox
来接受要转换的数字。三个 TextBlock
:txtBinary
、txtOctal
和 txtHexadecimal
用于显示转换后的结果。这三个 TextBlock
使用元素绑定绑定到 txtDecimal
TextBox
。转换器 NumberSystemConverter
用于使用 Converter
属性将十进制数转换为二进制、八进制和十六进制。ConverterParameter
属性用于将目标类型指定为 2、8 和 16,分别用于转换为二进制、八进制和十六进制值。
以下是我们的数字系统转换器的代码:
public class NumberSystemConverter : IValueConverter
{
Stack<object> stack = new Stack<object>();
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
// Store result digits in array
object[] digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F" };
try
{
// Get the source value
int number = System.Convert.ToInt32(value.ToString());
if (number == 0)
{
return 0;
}
// Get the target number system
int divisor = System.Convert.ToInt32(parameter.ToString());
while (number > 0)
{
int remainder = number % divisor;
// Push digits to stack
stack.Push(digits[remainder]);
number /= divisor;
}
StringBuilder builder = new StringBuilder();
while (stack.Count > 0)
{
builder.Append(stack.Pop().ToString());
// Return digits in LIFO order
}
return builder.ToString();
// Return result
}
catch (Exception)
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
在上面的代码中,Convert
方法的第一个参数表示要转换的数字(number),第三个参数表示目标数字系统(divisor)。将数字除以除数,并将余数推入堆栈。最后,将数字从堆栈中弹出,并附加到 StringBuilder
对象。将 StringBuilder
转换为 String
并将其作为结果返回,以在目标 TextBlock
上显示。
不需要实现 ConvertBack
方法。
关注点
虽然转换器还有许多用途以及使用转换器的各种方法,但我希望上述讨论能帮助理解 WPF 中转换器的工作原理。