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

发布于 2024-07-20 20:22:43 字数 2564 浏览 7 评论 0原文

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

但是“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>

I created a Converter to convert from double to integer.

But the line "return (int)value;" always gets a "specified cast is not valid."

What do I have to do so that my Converter successfully converts a double and sends back an integer?

Converter:

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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请恋爱 2024-07-27 20:22:43

您正在尝试从 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

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

You are attempting to cast (not convert) from double to int, which won't work. You need to do an implicit conversion or use Convert.ToInt32() -- since the argument is actually of type object I think you'll need the latter to keep the compiler happy. It's up to you whether you want to include the culture's format provider or not.

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    return Convert.ToInt32(value);
}

You can use the cast operator when the object's have the same shape, that is, when one object is an instance of the type to which you are casting. For example, if class Foo extends class Bar, then you can cast an object of type Foo to type Bar - because a Foo object has all the methods and properties that a Bar object would. You couldn't, however, cast an object of type Bar to type Foo because Foo changes (or can change, as far as the compiler is concerned) the shape of Bar, by adding methods or properties that a Bar object doesn't have.

In your case you are dealing with primitive types which only share the object interface - there isn't an inheritance relationship between them except that they both derive from object. There is, however, an implicit conversion between the two. You can assign an object one type to a variable of the other, though you may lose some precision in the value.

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

You can't, however, cast an object of one type to the other. Casting implies that you will be using the object as if it were of the other type. In this case the shapes differ and it can't be done.

暮年慕年 2024-07-27 20:22:43

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

return (int)(double)value;

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

The problem is that you are attempting to do both an unbox and a cast at the same time. This will fail. You must first unbox and then cast to the appropriate type.

return (int)(double)value;

Eric Lippert Recently wrote a nice article on exactly why this is necessary. It's worth the read

月依秋水 2024-07-27 20:22:43

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

return (int)(double)value;

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

The double value is boxed inside an object, and the only way to get it out is to unbox it as a double. After that you can cast it to an int.

return (int)(double)value;

You can also use the Convert.ToInt32(object) method (as tvanfosson suggested), which will cast the object to IConvertible and call it's virtual ToInt32 method, which in turn will call the Convert.ToInt32(double) method. That is of course a bit more overhead.

倾城泪 2024-07-27 20:22:43

您想要转换,但正在进行从 double 到 int 的转换。
尝试这个:

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

You want to convert but you are doing casting from double to int.
Try this:

    public object Convert(object value, ...)
    {
        return (int)(double)value;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文