C# d:具有接口类型的DesignInstance
我正在将一个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类型”C# d:具有接口类型的DesignInstance,c#,wpf,xaml,resharper,C#,Wpf,Xaml,Resharper,我正在将一个UI绑定到一个接口(该接口由多个演示者实现,无法从UI程序集访问) 我非常喜欢designer中的d:DesignInstance,因为它(有点)使用R#使xaml成为强类型 遗憾的是,d:DesignInstance不支持接口类型:“无法创建接口的实例。” 我想的第一件事是:好的,没问题,让我们创建一个自定义标记扩展,它以System.Type为参数,ProvideValue方法返回它的一个伪实例(这个接口的虚拟实现,由动态IL生成) 这非常有效,绑定在设计时得到解决(我可以在设
... 似乎DesignInstance不支持内部标记扩展:(在这种情况下,您可以利用IsDesignTimeCreatable,如下所示:
d:DataContext="{d:DesignInstance commons:User, IsDesignTimeCreatable=False}"
这本质上指示设计者仅将类型用于intellisense和错误突出显示,而不是实际尝试实例化设计实例。@Olivier:这是使用“适配器设计模式”的最佳方案之一 注意:我不知道Resharper,我是一名C#和.NET开发人员。但根据您的解释,我知道存在兼容性问题。 下面是您可以尝试的可能解决方案
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>