Почему мой конвертер выдает неверную ошибку приведения?

StackOverflow https://stackoverflow.com/questions/874635

Вопрос

Я создал конвертер для преобразования двойного числа в целое.

Но строка «return (int) значение»; Всегда получает «указанный актерский состав не является действительным».

Что мне нужно сделать, чтобы мой конвертер успешно преобразовал двойное число и отправил обратно целое число?

Конвертер:

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
    }
}

КСАМЛ:

<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>
Это было полезно?

Решение

Вы пытаетесь преобразовать (не преобразовать) из 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

Однако вы не можете привести объект одного типа к другому.Приведение подразумевает, что вы будете использовать объект, как если бы он был другого типа.В этом случае формы различаются, и это невозможно.

Другие советы

Проблема в том, что вы пытаетесь одновременно выполнить распаковку и приведение.Это потерпит неудачу.Сначала необходимо распаковать, а затем привести к соответствующему типу.

return (int)(double)value;

Эрик Липперт Недавно написал хорошую статью о том, почему это необходимо.Это стоит прочитать

А double значение заключено внутри объекта, и единственный способ получить его — распаковать его как double.После этого вы можете передать его в int.

return (int)(double)value;

Вы также можете использовать Convert.ToInt32(object) метод (как предложил тванфоссон), который преобразует объект в IConvertible и вызывает его виртуальный ToInt32 метод, который, в свою очередь, вызовет метод Convert.ToInt32(double) метод.Это, конечно, немного больше накладных расходов.

Вы хотите преобразовать, но выполняете приведение от double к int.Попробуй это:

    public object Convert(object value, ...)
    {
        return (int)(double)value;
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top