2016-05-08 4 views
2

RenderTransformのPointを指定するために値コンバーターを実装したいと考えています。私はIValueConverterインターフェイスを実装するまでうまく動作します。 MarkupExtensionクラスを実装して、毎回私のコンバータのXAMLリソースを宣言しないようにすることができます。これを実装しようとすると、私は持っていますMarkupExtensionとしてコンバーターを指定するとデザイン時にInvalidCastExceptionが発生する

InvalidCastException: 'System.Windows.Data.IValueConverter'タイプに 'System.Object'型のオブジェクトをキャストすることができません。

コンバータの実装:

[ValueConversion(typeof(Point), typeof(Transform))] 
public class PointToTransformConverter : MarkupExtension, IValueConverter 
{ 
    private PointToTransformConverter _instance = null; 

    public object Convert(
     object value, 
     Type targetType, 
     object parameter, 
     CultureInfo culture) 
    { 
     var point = (Point)value; 

     return new TransformGroup 
     { 
      Children = new TransformCollection 
      { 
       new TranslateTransform(point.X, point.Y) 
      } 
     }; 
    } 

    public object ConvertBack(
     object value, 
     Type targetType, 
     object parameter, 
     CultureInfo culture) 
    { 
     var transform = value as TransformGroup; 
     if (transform?.Children.Count > 0) 
     { 
      var translateTransform = transform.Children[0] as TranslateTransform; 
      if (translateTransform != null) 
      { 
       return new Point(
        translateTransform.X, 
        translateTransform.Y); 
      } 
     } 

     return null; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return _instance ?? (_instance = new PointToTransformConverter()); 
    } 
} 

XAMLの使用:私は間違って何をやっている

<local:PathControl x:Class="PathToWiringTube.PathView" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:local="clr-namespace:PathToWiringTube" 
        xmlns:view="clr-namespace:PathToWiringTube.View" 
        xmlns:vm="clr-namespace:PathToWiringTube.VM" 
        xmlns:crocodile="clr-namespace:Crocodile;assembly=Crocodile" 
        mc:Ignorable="d" 
        d:DataContext="{d:DesignInstance vm:PathVm}"> 
    <local:PathControl.Resources> 
     <crocodile:PointToTransformConverter x:Key="pointToTransformConverter"/> 
    </local:PathControl.Resources> 
    <Canvas> 
     <ItemsControl x:Name="itemsMarkers" ItemsSource="{Binding Markers}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <view:SplineDensityMarker Width="5" RenderTransform="{Binding Position, Converter={StaticResource pointToTransformConverter}}"/> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </Canvas> 
</local:PathControl> 

答えて

0

私は別の環境に私のコードをチェックし、それが動作することを検出しました。私はVisual Studioのバージョンが不一致であることを調査し、それを見つけました(14.0.23107.0 D14RELと14.0.24720.00 Update1)。私の古い環境に最新のVisual Studio Update 2をインストールした後、すべて正常に動作します。

1

下記のコードを試して例外が発生していないかどうか確認してください。 私はそれを修正しました。インスタンスは静的でxamlでなければなりません。静的リソースとして呼び出すのではなく、直接コンバータを参照できます。これは、MarkupExtensionを使用する主な用途です。以下のコードは正常に動作するはずです。何か問題があれば元に戻してください。

コンバータ:

[ValueConversion(typeof(Point), typeof(Transform))] 
public class PointToTransformConverter : MarkupExtension, IValueConverter 
{ 
    private static PointToTransformConverter _instance = null; 

    public object Convert(
     object value, 
     Type targetType, 
     object parameter, 
     CultureInfo culture) 
    { 
     var point = (Point)value; 

     return new TransformGroup 
     { 
      Children = new TransformCollection 
      { 
       new TranslateTransform(point.X, point.Y) 
      } 
     }; 
    } 

    public object ConvertBack(
     object value, 
     Type targetType, 
     object parameter, 
     CultureInfo culture) 
    { 
     var transform = value as TransformGroup; 
     if (transform?.Children.Count > 0) 
     { 
      var translateTransform = transform.Children[0] as TranslateTransform; 
      if (translateTransform != null) 
      { 
       return new Point(
        translateTransform.X, 
        translateTransform.Y); 
      } 
     } 

     return null; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return _instance ?? (_instance = new PointToTransformConverter()); 
    } 
} 

XAML:

<local:PathControl x:Class="PathToWiringTube.PathView" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:local="clr-namespace:PathToWiringTube" 
        xmlns:view="clr-namespace:PathToWiringTube.View" 
        xmlns:vm="clr-namespace:PathToWiringTube.VM" 
        xmlns:crocodile="clr-namespace:Crocodile;assembly=Crocodile" 
        mc:Ignorable="d" 
        d:DataContext="{d:DesignInstance vm:PathVm}"> 
    </local:PathControl.Resources> 
    <Canvas> 
     <ItemsControl x:Name="itemsMarkers" ItemsSource="{Binding Markers}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <view:SplineDensityMarker Width="5" RenderTransform="{Binding Position, Converter={crocodile:PointToTransformConverter}}"/> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </Canvas> 
</local:PathControl> 
+0

はい、私はまだ正常に動作していると言いました。しかし、この場合、MarkupExtensionクラスとIValueConverterインターフェースを同時に実装する方法はありますか? –

+0

いいえ私は、コンバータがマークアップ拡張なしで動作しているか、つまり静的リソースとして追加しているかどうかを確認したいのですか? – ViVi

+0

私はコードを実際に更新しました。今すぐご確認ください。 – ViVi

関連する問題