为什么我的转换器会出现无效的转换错误?

时间:2009-05-17 13:37:40

标签: c# wpf xaml casting converters

我创建了一个转换器,可以从double转换为整数。

但是行“return(int)value;”总是得到“指定演员阵容无效。”

我必须做什么才能让我的Converter成功转换一个double并发回一个整数?

转换器:

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>

4 个答案:

答案 0 :(得分:8)

您正在尝试将(不转换)从double转换为int,这将无效。你需要进行隐式转换或使用Convert.ToInt32() - 因为参数实际上是对象类型我认为你需要后者来保持编译器满意。您是否想要包含文化格式提供者取决于您。

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

但是,您不能将一种类型的对象转换为另一种对象。强制转换意味着您将使用该对象,就好像它是另一种类型一样。在这种情况下,形状不同,无法完成。

答案 1 :(得分:3)

问题在于您尝试同时执行unbox和强制转换。这将失败。您必须首先取消选择,然后转换为适当的类型。

return (int)(double)value;

Eric Lippert最近写了一篇很好的文章,说明为什么这是必要的。值得一读

答案 2 :(得分:1)

double值在对象内部加框,获取它的唯一方法是将其展开为double。之后,您可以将其投射到int

return (int)(double)value;

你也可以使用Convert.ToInt32(object)方法(如tvanfosson建议的那样),它会将对象强制转换为IConvertible并调用它的虚拟ToInt32方法,然后调用Convert.ToInt32(double)方法。这当然是一个更多的开销。

答案 3 :(得分:1)

你想要转换但是你正在从double转换为int。 试试这个:

    public object Convert(object value, ...)
    {
        return (int)(double)value;
    }