在WPF设计器中无法将类型为'Castle.Proxies.XProxy'的对象转换为类型'X' [英] Unable to cast object of type 'Castle.Proxies.XProxy' to type 'X' in WPF Designer

查看:392
本文介绍了在WPF设计器中无法将类型为'Castle.Proxies.XProxy'的对象转换为类型'X'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近从Blend中发现了WPF组件非常有用的设计时属性,该属性(除其他外)使您可以仅在设计时设置DataContext.太棒了!

I've recently discovered the very useful design time attributes from Blend for a WPF component, which (among other things) allows you to set a DataContext only at design time. Awesome!

结合DesignInstance属性,可以设置在设计时自动创建并绑定到的类型,从而允许您将Visual Studio Designer与WPF组件在运行时的实际外观结合使用.真的很好,我希望它花了我这么长时间才发现.

Combined with the DesignInstance attribute, you can set a type to be automatically created and bound to during design time, allowing you to use the Visual Studio Designer with some context as to what your WPF component will actually look like at run time. Its really nice, and I wish it hadn't taken me so long to discover.

很明显,因为我在这里而不是在程序员天堂生活,所以在使用这些设计时间属性时遇到了问题.

Obviously, because I'm here and not living it up in programmer heaven I've encountered a problem while using these design time attributes.

我已经围绕一个ViewModel创建了一个设计时间包装,该包装具有无参数构造函数(因此可以由设计人员创建).在其构造函数内部,它使用NSubstitute模拟出注入到其继承的ViewModel中的所有依赖项.

I've created a design time wrapper around one my ViewModels, which has a parameterless constructor (so it can be created by the designer). Inside its constructor, it uses NSubstitute to mock out all of the dependencies injected into the ViewModel it inherits from.

在设计器中使用此设计时类会导致错误,如下所示:

Using this design time class in the designer results in an error much like the following:

Unable to cast object of type 'Castle.Proxies.XProxy' to type 'X'.

(将X替换为我注入的依赖项之一).

(With the X being replaced with one of my injected dependencies).

您可以使用下面的最少代码集来重现该问题.

You can use the following minimal set of code to reproduce the problem.

在VS2013中创建一个针对.NET Framework 4.5.1的WPF应用程序(我不知道它也可能在以前的版本中发生),并且其中包含以下文件.

Create a WPF Application in VS2013 targeting .NET Framework 4.5.1 (it might happen in previous versions too, I don't know) with the following files in it.

View.xaml

<Page 
    x:Class="DesignTimeNSubstituteIssue.Views.View"
    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:DesignTimeNSubstituteIssue_Views_DesignTime="clr-namespace:DesignTimeNSubstituteIssue.Views.DesignTime"
    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance Type=DesignTimeNSubstituteIssue_Views_DesignTime:DesignTimeViewModel, IsDesignTimeCreatable=True}">
    <Grid>
        <TextBlock Text="{Binding Message, FallbackValue=Design_Time_Message_Failed_Using_Fallback}"/>
    </Grid>
</Page>

ViewModel.cs

using DesignTimeNSubstituteIssue.Services;

namespace DesignTimeNSubstituteIssue.ViewModels
{
    public class ViewModel
    {
        public ViewModel(XDependency dependency)
        {
            _Dependency = dependency;
        }

        private readonly XDependency _Dependency;
        public string Message { get; protected set; }
    }
}

DesignTimeViewModel.cs

using DesignTimeNSubstituteIssue.Services;
using DesignTimeNSubstituteIssue.ViewModels;
using NSubstitute;

namespace DesignTimeNSubstituteIssue.Views.DesignTime
{
    public class DesignTimeViewModel : ViewModel
    {
        public DesignTimeViewModel()
            : base(Substitute.For<XDependency>())
        {
            Message = "This is a Design Time message.";
        }
    }
}

XDependency.cs

namespace DesignTimeNSubstituteIssue.Services
{
    public interface XDependency
    {

    }
}

编译,关闭并重新打开解决方案,然后在设计器中打开View.xaml. 它将正常工作.然后,关闭设计器,重新生成解决方案,然后再次在设计器中打开View.xaml,您将收到以下错误:

Compile, close and reopen the solution and open View.xaml in the designer. It will work just fine. Then, close the designer, rebuild solution and open View.xaml in the designer again, and you will get the following error:

Unable to cast object of type 'Castle.Proxies.XDependencyProxy_1' to type 'DesignTimeNSubstituteIssue.Services.XDependency'.

发生此错误时,设计器将停止使用指定的DesignTimeViewModel,并退回到根本没有DataContext的地方.

When this error occurs, the designer stops using the specified DesignTimeViewModel, and falls back to having no DataContext at all.

解决此问题的唯一方法是关闭并重新打开解决方案.

The only way to fix this is to close and reopen the solution.

我怀疑我知道发生了什么,但我不知道为什么发生或如何解决.

I suspect I know what is happening, but I don't know why its happening or how to fix it.

我认为在第一次编译时,设计人员正在获得对该程序集的引用并对其进行缓存.当进行第二次编译时,程序集将被重建并且基本相同,但是NSubstitute代理将使用新的后缀(例如Castle.Proxies.XDependencyProxy_2之类)重新生成,该后缀不在第一个程序集中,因此设计人员不知道该代理实际上实现了XDependency接口. 这纯粹是我的推测.

I think that on the first compile the designer is obtaining a reference to the assembly and caching it. When the second compile occurs, the assembly is rebuilt and is mostly the same, but the NSubstitute proxy is regenerated with a new suffix (like Castle.Proxies.XDependencyProxy_2 or something) which wasn't in the first assembly, so the designer doesn't know that that proxy actually implements the XDependency interface. This is purely conjecture on my part.

我可以通过不使用NSubstitute来创建变通办法,并手动模拟依赖项,但是我很想知道是否有人可以对这个问题有所了解.

I can create a workaround by not using NSubstitute, and manually mocking the dependencies, but I'm interested to see if someone can shed some light on the subject.

推荐答案

似乎我的原始项目和最小复制项目都没有正确地对程序集进行版本控制,这意味着设计人员不知道需要重新加载程序集(因为新版本与旧版本完全相同).更改程序集版本以包含自动生成的版本号似乎可以解决该问题.

It looks as though both my original project AND minimal reproduction project do not version the assembly correctly, meaning the designer doesn't know that it needs to reload the assembly (because the new one is exactly the same version as the old one). Changing the assembly version to include an autogenerated version number appears to fix the problem.

这篇关于在WPF设计器中无法将类型为'Castle.Proxies.XProxy'的对象转换为类型'X'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆