Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将转换器指定为MarkupExtension时,设计时出现InvalidCastException_C#_Wpf_Xaml - Fatal编程技术网

C# 将转换器指定为MarkupExtension时,设计时出现InvalidCastException

C# 将转换器指定为MarkupExtension时,设计时出现InvalidCastException,c#,wpf,xaml,C#,Wpf,Xaml,我想实现值转换器来指定RenderTransform的点。在我实现IValueConverter接口之前,这一切都很好。我知道我可以实现MarkupExtension类,以避免每次为转换器声明分离的XAML资源。当我试图实现这一点时,我 InvalidCastException:无法将“System.object”类型的对象强制转换为“System.Windows.Data.IValueConverter”类型。 转换器实现: [ValueConversion(typeof(Point), ty

我想实现值转换器来指定RenderTransform的点。在我实现IValueConverter接口之前,这一切都很好。我知道我可以实现MarkupExtension类,以避免每次为转换器声明分离的XAML资源。当我试图实现这一点时,我

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>


我做错了什么?

请尝试下面的代码并检查是否出现异常? 我已经改正了。实例应该是静态的,而xaml则可以直接引用转换器,而不是将其作为静态资源调用。这是使用标记扩展名的主要用途。下面的代码应该可以正常工作。如果有任何问题,请回复

转换器:

[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());
    }
}
<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>
Xaml:

[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());
    }
}
<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>


我在另一个环境中检查了我的代码,并检测到它可以工作。我对Visual Studio版本不匹配进行了研究,并发现了它(14.0.23107.0 D14REL和14.0.24720.00 Update1)。在我的旧环境上安装最新的Visual Studio Update 2后,一切正常

是的,我已经说过它工作得很好。但是,在这种情况下,我如何能够同时实现MarkupExtension类和IValueConverter接口?不,我想检查转换器是否在没有标记扩展的情况下工作,即作为静态资源添加?谢谢Vishakh,我已经复制粘贴了您的代码。但这会在重建后的设计时再次导致异常。我对此进行了调查,并将在这里报告我的进度。您能替换代码中的返回null并用一些值初始化它吗??