2009-05-17 6 views
7

Creé un convertidor para convertir de doble a entero.¿Por qué mi convertidor genera un error de conversión no válido?

Pero la línea "return (int) value;" siempre obtiene un "yeso especificado no es válido".

¿Qué debo hacer para que mi convertidor convierta con éxito un doble y devuelva un número entero?

Convertidor:

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> 

Respuesta

8

Está intentando fundido (no convertir) de doble a int, que no va a funcionar. Necesitas hacer una conversión implícita o usar Convert.ToInt32() - ya que el argumento es realmente de tipo objeto, creo que necesitarás lo último para mantener al compilador contento. Depende de usted si quiere incluir o no el proveedor de formatos de la cultura.

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

Usted puede utilizar el operador de conversión cuando el objeto de tener la misma forma , es decir, cuando un objeto es una instancia de la clase a la que está lanzando. Por ejemplo, si la clase Foo amplía la clase Bar, entonces puede convertir un objeto de tipo Foo para que escriba Bar, porque un objeto Foo tiene todos los métodos y propiedades que tendría un objeto Bar. Sin embargo, no podría lanzar un objeto de tipo Bar para escribir Foo porque Foo cambia (o puede cambiar, en lo que respecta al compilador) la forma de Bar, al agregar métodos o propiedades que un objeto Bar no ' t tener.

En su caso, se trata de tipos primitivos que solo comparten la interfaz del objeto, no existe una relación de herencia entre ellos, excepto que ambos derivan del objeto. Sin embargo, hay una conversión implícita entre las dos. Puede asignar un objeto de un tipo a una variable de la otra, aunque puede perder cierta precisión en el valor.

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 

No puede, sin embargo, lanzar un objeto de un tipo al otro. Casting implica que usarás el objeto como si fuera del otro tipo. En este caso, las formas difieren y no se puede hacer.

+0

Si el parámetro es siempre un valor doble que return (int) (double); también funcionará, pero ToInt32 es mejor. – Nir

+0

@Nir - sí, esto permitiría al compilador hacer una conversión implícita de doble a int aunque parezca un reparto. – tvanfosson

1

El valor double está encajonado dentro de un objeto, y la única manera de conseguirlo es a cabo a desempacar como un double. Después de eso, puedes convertirlo a int.

return (int)(double)value; 

También puede utilizar el método de Convert.ToInt32(object) (como se sugirió tvanfosson), que será lanzado el objeto a IConvertible y llamar a su método virtual de ToInt32, que a su vez llama al método Convert.ToInt32(double). Eso es, por supuesto, un poco más sobrecarga.

1

Quiere convertir, pero está haciendo la conversión de doble a int. Pruebe esto:

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