2016-05-08 21 views
2

我想要實現值轉換器以指定Point for RenderTransform。這工作正常,直到我只是實現IValueConverter接口。我知道我可以實現MarkupExtension類,以避免每次都爲我的轉換器聲明獨立的XAML資源。當我嘗試執行此操作時,我有將指定轉換器指定爲MarkupExtension時,InvalidCastException在設計時指定

InvalidCastException:無法強制類型爲'System.Object'的對象類型爲'System.Windows.Data.IValueConverter'。

轉換器實現:

[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

請問您是否可以嘗試下面的代碼並檢查是否會發生異常? 我已糾正它。實例應該是static和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