2009-05-17 21 views
7

Tôi đã tạo một Trình chuyển đổi để chuyển đổi từ đôi thành số nguyên.Tại sao trình chuyển đổi của tôi đưa ra lỗi truyền không hợp lệ?

Nhưng dòng "giá trị trả về (int);" luôn nhận được "dàn diễn viên được chỉ định không hợp lệ".

Tôi phải làm gì để Trình chuyển đổi thành công chuyển đổi một đôi và gửi lại một số nguyên?

Chuyển đổi:

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> 

Trả lời

8

Bạn đang cố gắng đúc (không chuyển đổi) từ hai đến int, mà sẽ không hoạt động. Bạn cần phải làm một chuyển đổi tiềm ẩn hoặc sử dụng Convert.ToInt32() - vì đối số là thực sự của đối tượng kiểu Tôi nghĩ rằng bạn sẽ cần sau này để giữ cho trình biên dịch hạnh phúc. Tùy thuộc vào bạn có muốn bao gồm nhà cung cấp định dạng của văn hóa hay không.

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

Bạn có thể sử dụng toán tử cast khi đối tượng của có cùng hình dạng , có nghĩa là, khi một đối tượng là một thể hiện của các loại mà bạn đang đúc. Ví dụ, nếu lớp Foo mở rộng lớp Bar, thì bạn có thể bỏ một đối tượng kiểu Foo để gõ Bar - bởi vì một đối tượng Foo có tất cả các phương thức và thuộc tính mà một đối tượng Bar sẽ làm. Tuy nhiên, bạn không thể bỏ một đối tượng kiểu Bar để gõ Foo vì Foo thay đổi (hoặc có thể thay đổi, theo như trình biên dịch liên quan) là hình dạng của Bar, bằng cách thêm các phương thức hoặc thuộc tính mà đối tượng Bar không làm ' t có.

Trong trường hợp của bạn, bạn đang xử lý các kiểu nguyên thủy chỉ chia sẻ giao diện đối tượng - không có mối quan hệ thừa kế giữa chúng ngoại trừ cả hai đều lấy được từ đối tượng. Tuy nhiên, có một số chuyển đổi tiềm ẩn giữa hai loại. Bạn có thể gán một kiểu đối tượng cho một biến khác, mặc dù bạn có thể mất một số độ chính xác trong giá trị.

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 

Tuy nhiên, bạn không thể truyền đối tượng của loại này sang loại khác. Đúc ngụ ý rằng bạn sẽ sử dụng đối tượng như thể nó thuộc loại khác. Trong trường hợp này, các hình dạng khác nhau và không thể thực hiện được.

+0

Nếu tham số luôn gấp đôi giá trị trả về (int) (đôi); cũng sẽ hoạt động, nhưng ToInt32 thì tốt hơn. – Nir

+0

@Nir - vâng, điều này sẽ cho phép trình biên dịch thực hiện chuyển đổi ngầm từ đôi thành int mặc dù nó trông giống như một diễn viên. – tvanfosson

3

Vấn đề là bạn đang cố gắng thực hiện cả hộp unbox và dàn diễn viên cùng một lúc. Điều này sẽ thất bại. Trước tiên, bạn phải bỏ hộp và sau đó truyền đến loại thích hợp.

return (int)(double)value; 

Eric Lippert Gần đây đã viết một bài viết hay về lý do tại sao điều này là cần thiết. Đó là giá trị đọc

1

Giá trị double được đóng hộp bên trong một đối tượng, và cách duy nhất để có được nó ra là để Unbox nó như là một double. Sau đó, bạn có thể truyền nó đến một số int.

return (int)(double)value; 

Bạn cũng có thể sử dụng phương pháp Convert.ToInt32(object) (như tvanfosson gợi ý), mà sẽ cast đối tượng để IConvertible và gọi nó là ảo ToInt32 phương pháp, mà lần lượt sẽ gọi phương thức Convert.ToInt32(double). Đó là tất nhiên hơn một chút chi phí.

1

Bạn muốn chuyển đổi nhưng bạn đang thực hiện truyền từ đôi đến int. Hãy thử điều này:

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