Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.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# d:具有接口类型的DesignInstance_C#_Wpf_Xaml_Resharper - Fatal编程技术网

C# d:具有接口类型的DesignInstance

C# d:具有接口类型的DesignInstance,c#,wpf,xaml,resharper,C#,Wpf,Xaml,Resharper,我正在将一个UI绑定到一个接口(该接口由多个演示者实现,无法从UI程序集访问) 我非常喜欢designer中的d:DesignInstance,因为它(有点)使用R#使xaml成为强类型 遗憾的是,d:DesignInstance不支持接口类型:“无法创建接口的实例。” 我想的第一件事是:好的,没问题,让我们创建一个自定义标记扩展,它以System.Type为参数,ProvideValue方法返回它的一个伪实例(这个接口的虚拟实现,由动态IL生成) 这非常有效,绑定在设计时得到解决(我可以在设

我正在将一个UI绑定到一个接口(该接口由多个演示者实现,无法从UI程序集访问)

我非常喜欢designer中的d:DesignInstance,因为它(有点)使用R#使xaml成为强类型

遗憾的是,d:DesignInstance不支持接口类型:“无法创建接口的实例。”

我想的第一件事是:好的,没问题,让我们创建一个自定义标记扩展,它以System.Type为参数,ProvideValue方法返回它的一个伪实例(这个接口的虚拟实现,由动态IL生成)

这非常有效,绑定在设计时得到解决(我可以在设计面板中看到这一点,因为我的标记扩展使用lorem ipsum填充对象属性)

但是最好的#功能不起作用:Resharper无法识别datacontext类型,只给出一条消息“无法解析类型为“object”的数据上下文中的属性“{0}”

有人知道如何解决这个问题吗

(任何允许我让R#知道接口datacontext类型的替代方案都非常好)

谢谢

ps:我还尝试创建另一个标记扩展,该扩展返回生成的运行时类型,以便将其提供给DesignInstance:“{d:DesignInstance type={utilsUi:InstanceType commons:User}}”=>给出错误“InstanceType类型的对象无法转换为System.type类型”
... 似乎DesignInstance不支持内部标记扩展:(

在这种情况下,您可以利用IsDesignTimeCreatable,如下所示:

d:DataContext="{d:DesignInstance commons:User, IsDesignTimeCreatable=False}"

这本质上指示设计者仅将类型用于intellisense和错误突出显示,而不是实际尝试实例化设计实例。

@Olivier:这是使用“适配器设计模式”的最佳方案之一

注意:我不知道Resharper,我是一名C#和.NET开发人员。但根据您的解释,我知道存在兼容性问题。 下面是您可以尝试的可能解决方案

  • 编写一个实现所需接口类型的C#类
  • 在类中实现接口,但是不要自己编写整个实现,而是调用在实现的方法中实现接口的其他类方法
  • 开始使用您编写的类
  • 为获得兼容性而编写的类称为适配器
  • 示例代码:

    class Program
    {
        static void Main(string[] args)
        {
            // create an object of your adapter class and consume the features.
            AdapterInterfaceUI obj = new AdapterInterfaceUI();
    
            // Even though you have written an adapter it still performs the operation in base class
            // which has the interface implementation and returns the value.
            // NOTE : you are consuming the interface but the object type is under your control as you are the owner of the adapter class that you have written.
            Console.WriteLine(obj.DisplayUI());
            Console.ReadKey();
        }
    }
    
    
    #region code that might be implemented in the component used.
    public interface IinterfaceUI
    {
        string DisplayUI();
    }
    
    public class ActualUI : IinterfaceUI
    {
        //Factory pattern that would be implemented in the component that you are consuming.
        public static IinterfaceUI GetInterfaceObject()
        { 
            return new ActualUI();
        }
    
        public string DisplayUI()
        {
            return "Interface implemented in ActualUI";
        }
    }
    #endregion
    
    
    #region The adapter class that you may need to implement in resharper or c# which ever works for you.
    public class AdapterInterfaceUI : ActualUI, IinterfaceUI
    {
        public string DisplayUI()
        {
            return base.DisplayUI();
        }
    }
    #endregion
    

    我想这个解决方案会对你有所帮助。

    我刚刚调查了差不多相同的问题……实际上,我所做的是遵循的原则。确切地说,我使用了ViewModelLocator(或多或少是静态的)以便ViewModel是在运行时或设计时注入的。神奇之处在于MvvMLight框架提供的函数ViewModelBase.IsInDesignModeStatic。最后,我的ViewModelLocator类如下所示

    public class ViewModelLocator
        {
            private static readonly IKernel _kernel;
    
            static ViewModelLocator()
            {
                _kernel = new StandardKernel();
                if (ViewModelBase.IsInDesignModeStatic)
                {
                     _kernel.Bind<IBasicVM>().To<DesignBasicVm>();
                }
                else
                {
                    _kernel.Bind<IBasicVM>().To<BasicVm>();
                }
            }
    
            public IBasicVM BasicVm { get { return _kernel.Get<IBasicVM>(); } }
        }
    
    公共类ViewModelLocator
    {
    私有静态只读IKernel_内核;
    静态ViewModelLocator()
    {
    _内核=新的标准内核();
    if(ViewModelBase.IsIndesignatic)
    {
    _kernel.Bind().To();
    }
    其他的
    {
    _kernel.Bind().To();
    }
    }
    公共IBasicVM BasicVm{get{return}_kernel.get();}
    }
    
    您可以忽略_内核,但如果要使用Ioc构建ViewModels,则可能需要它(或类似的Ioc)

    App.xaml将ViewModelLocator声明为ressource

      <Application.Resources>
        <ResourceDictionary>
          <viewModel:ViewModelLocator x:Key="ViewModelLocator" />
        </ResourceDictionary>
      </Application.Resources>
    

    我已经创建了一个模板。

    我发现了如何克服这个不合逻辑的Visual Studio XAML设计器错误

    而不是

    <SomeControl d:DataContext={d:DesignInstance commons:IUser}>
        <!--element content here-->
    </SomeControl>
    
    
    
    你可以写

    <SomeControl>
        <d:SomeControl.DataContext>
            <x:Type Type="commons:IUser" />
        </d:SomeControl.DataContext>
        <!--element content here-->
    </SomeControl>
    
    
    
    是的,这个解决方案看起来不那么酷,但肯定不会更糟

    Type
    tag允许指定接口、嵌套类型(例如n:A+B)甚至泛型!

    对于泛型,只需在类型中添加一个反勾号和一些类型参数:


    顺便说一句,所有这些都适用于样式,
    不会产生错误!

    这不是我要寻找的。我不想损坏我的程序集(重新分发)有一堆无用的设计类。我也不想花时间实现这些。谢谢你PS:Resharper只是一个visual studio扩展。哪个版本的visual studio和Resharper?2012年,我没有得到“无法创建接口实例”的问题message and Resharper Intellisense起作用,但在2010年不起作用。
    IsDesignTimeCreatable=False
    也不能解决2010年的问题。@nmclean:这非常令人惊讶,我在Resharper 8上使用VS 2012…这不是一个好答案(我已经知道IsDesignTimeCreatable,它不适合我的需要),但我奖励你不要浪费赏金:)thx的回答只需在第二个参数中添加'd:',它就会正常工作:DataContext=“{d:DesignInstance commons:User,d:IsDesignTimeCreatable=False}”没有帮助。IsDesignTimeCreatable不是默认为false吗?到目前为止,最好的答案是,我在寻找避免样式错误的方法时找到的。没有缺点(除了有点冗长),加上能够指定接口(和泛型)是巨大的。我意识到这是一个古老的答案,但这是迄今为止我在这个问题上找到的最好的答案。但我想知道:当你说“嵌套类型”时,你是指多个类型吗?如果是这样,如何实现多种类型?当我从您的示例中尝试
    时,我得到一个错误,指出不存在这样的接口(因为它正在寻找一个名为
    IUser+IFoo
    )。为第二个接口使用
    commons:
    前缀并不能修复它。显然,
    DataContext
    属性不能设置两次,因此有两个
    
    
    <SomeControl>
        <d:SomeControl.DataContext>
            <x:Type Type="commons:IUser" />
        </d:SomeControl.DataContext>
        <!--element content here-->
    </SomeControl>