【问题标题】:Why does my converter giving an invalid cast error?为什么我的转换器会给出无效的转换错误?
【发布时间】:2010-10-26 20:30:46
【问题描述】:

我创建了一个转换器来从双精度转换为整数。

但是“return (int)value;”这一行总是得到“指定的演员表无效。”

我必须做些什么才能让我的转换器成功转换双精度并返回一个整数?

转换器:

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>

【问题讨论】:

    标签: c# wpf xaml casting converters


    【解决方案1】:

    您正在尝试将(而不是转换)从 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 对象没有。

    在您的情况下,您正在处理仅共享对象接口的原始类型 - 除了它们都从对象派生之外,它们之间没有继承关系。然而,两者之间存在隐含的转换。您可以将一种类型的对象分配给另一种类型的变量,但可能会丢失一些值的精度。

    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
    

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

    【讨论】:

    • 如果参数始终是double,则返回(int)(double)值;也可以,但 ToInt32 更好。
    • @Nir -- 是的,这将允许编译器进行从 double 到 int 的隐式转换,即使它看起来像强制转换。
    【解决方案2】:

    问题是您试图同时进行拆箱和强制转换。这将失败。您必须先拆箱,然后再转换为适当的类型。

    return (int)(double)value;
    

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

    【讨论】:

      【解决方案3】:

      double 值被装箱在一个对象中,唯一的方法是将其拆箱为double。之后,您可以将其转换为 int

      return (int)(double)value;
      

      您还可以使用Convert.ToInt32(object) 方法(如tvanfosson 建议的那样),它将对象转换为IConvertible 并调用它的虚拟ToInt32 方法,该方法又将调用Convert.ToInt32(double) 方法。这当然会增加一些开销。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多