C# 为什么我的转换器出现无效转换错误?
我创建了一个转换器,将double转换为integer 但行“return(int)value;”始终获取“指定的强制转换无效” 为了使转换器成功地转换一个double并发回一个整数,我必须做些什么 转换器:C# 为什么我的转换器出现无效转换错误?,c#,wpf,xaml,casting,converters,C#,Wpf,Xaml,Casting,Converters,我创建了一个转换器,将double转换为integer 但行“return(int)value;”始终获取“指定的强制转换无效” 为了使转换器成功地转换一个double并发回一个整数,我必须做些什么 转换器: namespace TestChangeAngle { [ValueConversion(typeof(double), typeof(int))] class DoubleToIntegerConverter : IValueConverter {
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
}
}
<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>
XAML:
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
}
}
<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)
方法。这当然会增加一些开销。您想要转换,但您正在从double转换为int。
试试这个:
public object Convert(object value, ...)
{
return (int)(double)value;
}
如果参数始终是双精度返回(int)(double)值;也可以,但ToInt32更好。@Nir--是的,这将允许编译器执行从double到int的隐式转换,即使它看起来像一个强制转换。