为什么我的转换器会给出无效的转换错误?
-
22-08-2019 - |
题
我创建了一个转换器来从双精度转换为整数。
但是行“返回(int)值”;始终获得“指定的铸件无效”。
我需要做什么才能让我的转换器成功转换双精度值并发回整数?
转换器:
namespace TestChangeAngle
{
[ValueConversion(typeof(double), typeof(int))]
class DoubleToIntegerConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
}
XAML:
<Page x:Class="TestChangeAngle.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestChangeAngle"
Title="Page1">
<Page.Resources>
<local:DoubleToIntegerConverter x:Key="DoubleToIntegerConverter"/>
</Page.Resources>
<StackPanel HorizontalAlignment="Left" Margin="20">
<Image Source="images\logo2.png"
RenderTransformOrigin="0.5, 0.5"
Width="100"
Margin="10">
<Image.RenderTransform>
<RotateTransform Angle="{Binding ElementName=TheSlider, Path=Value}"/>
</Image.RenderTransform>
</Image>
<Slider x:Name="TheSlider"
Width="200"
Minimum="0"
Maximum="360"
HorizontalAlignment="Center"
Margin="10"
Cursor="Hand"/>
<TextBox x:Name="TheAngle"
Margin="10"
Width="100">
<TextBox.Text>
<Binding ElementName="TheSlider"
Path="Value"
UpdateSourceTrigger="PropertyChanged"
Converter="{StaticResource DoubleToIntegerConverter}"
Mode="TwoWay">
<Binding.ValidationRules>
<local:MinMaxValidationRule Minimum="0" Maximum="360"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
</Page>
解决方案
您正在尝试从 double 转换(而不是转换)为 int,这是行不通的。您需要进行隐式转换或使用 Convert.ToInt32() ——因为参数实际上是 object 类型,我认为您需要后者来让编译器满意。是否要包含区域性的格式提供程序取决于您。
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Convert.ToInt32(value);
}
当对象具有相同的值时,可以使用强制转换运算符 形状, ,即当一个对象是您要转换到的类型的实例时。例如,如果 Foo 类扩展了 Bar 类,那么您可以将 Foo 类型的对象强制转换为 Bar 类型 - 因为 Foo 对象具有 Bar 对象所具有的所有方法和属性。但是,您不能将 Bar 类型的对象强制转换为 Foo 类型,因为 Foo 会更改(或可以更改,就编译器而言) 形状 通过添加 Bar 对象没有的方法或属性来实现 Bar 的功能。
在您的情况下,您正在处理仅共享对象接口的原始类型 - 它们之间没有继承关系,除了它们都派生自对象之外。然而,有一个隐含的 转换 两者之间。您可以将一种类型的对象分配给另一种类型的变量,尽管您可能会损失一些值的精度。
double x = 1.1;
int y = 0;
y = x; // implicit conversion, this works, y will be 1
x = y; // implicit conversion, this works, x will be 1.0
但是,您不能将一种类型的对象转换为另一种类型。强制转换意味着您将像使用其他类型的对象一样使用该对象。在这种情况下 形状 不同而无法做到。
其他提示
问题是您试图同时进行拆箱和强制转换。这将会失败。您必须首先拆箱,然后转换为适当的类型。
return (int)(double)value;
Eric Lippert 最近写了一篇很好的文章,解释了为什么这是必要的。值得一读
在double
值盒装对象内,并把它弄出来的唯一方式是拆箱它作为一个double
。之后,你可以将其转换为int
。
return (int)(double)value;
您还可以使用Convert.ToInt32(object)
方法(如tvanfosson建议的),这将施放对象IConvertible并调用它的虚拟ToInt32
方法,这反过来将调用Convert.ToInt32(double)
方法。这当然是一个位更多的开销。
您要转换的,但你在做双重铸造为int。 尝试这样:
public object Convert(object value, ...)
{
return (int)(double)value;
}