Domanda

Ho creato un Convertitore per la conversione da doppia per intero.

Ma il "return (int)valore;" ottiene sempre un "cast specificato non è valido."

Cosa devo fare perché la mia Converter converte con successo una doppia e restituisce un numero intero?

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>
È stato utile?

Soluzione

Si sta tentando di lanciare (non convertire) dal doppio a int, che non funziona. Hai bisogno di fare una conversione implicita o utilizzare Convert.ToInt32 () - dal momento che l'argomento è in realtà di tipo di oggetto Penso che sarà necessario a quest'ultimo di mantenere il compilatore felice. E 'a voi decidere se si desidera includere provider di formato la propria cultura o meno.

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

È possibile utilizzare l'operatore di cast quando l'oggetto sono la stessa forma , cioè quando un oggetto è un'istanza del tipo a cui si sta casting. Ad esempio, se la classe Foo estende la classe Bar, allora si può lanciare un oggetto di tipo Foo digitare Bar - perché un oggetto Foo ha tutti i metodi e le proprietà che un oggetto bar sarebbe. Non si poteva, tuttavia, lanciare un oggetto di tipo bar a digitare Foo Foo perché cambia (o può cambiare, per quanto riguarda il compilatore è interessato) il forma di Bar, con l'aggiunta di metodi o proprietà che un oggetto Bar non ha.

Nel tuo caso si tratta di tipi primitivi che condividono solo l'interfaccia oggetto - non c'è una relazione di ereditarietà tra loro, tranne che entrambi derivano da oggetto. V'è, tuttavia, un implicito conversione tra i due. È possibile assegnare un oggetto un tipo di una variabile dell'altro, anche se si rischia di perdere una certa precisione nel valore.

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

Non è possibile, però, lanciare un oggetto di un tipo all'altro. Casting implica che si prevede di utilizzare l'oggetto come se fosse di altro tipo. In questo caso i forme sono diverse e non può essere fatto.

Altri suggerimenti

Il problema è che si sta tentando di fare entrambe le cose un Unbox e un cast al tempo stesso. Questo fallirà. È necessario prima Unbox e poi gettato al tipo appropriato.

return (int)(double)value;

Eric Lippert ha scritto di recente un bell'articolo su esattamente il motivo per cui ciò sia necessario. Vale la pena di lettura

Il double il valore è in scatola all'interno di un oggetto, e l'unico modo per uscire è quello di unbox come un double.Dopo di che è possibile eseguire il cast di un int.

return (int)(double)value;

È inoltre possibile utilizzare il Convert.ToInt32(object) metodo (come tvanfosson suggerito), che sarà il cast dell'oggetto IConvertible e chiamata virtuale ToInt32 il metodo, che a sua volta chiama il Convert.ToInt32(double) metodo.Che è, naturalmente, un po ' più alto.

Si desidera convertire, ma si sta facendo lanciare da doppia a int. Prova questo:

    public object Convert(object value, ...)
    {
        return (int)(double)value;
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top