d:具有接口类型的DesignInstance

Oli*_*ier 26 c# wpf resharper xaml

我将UI绑定到接口(由几个演示者实现,无法从UI程序集访问).

我非常喜欢设计师中的D:DesignInstance,因为它(有点)使用R#强力键入xaml.

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

界面上的设计实例

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

这很好用,绑定在设计时解决(我可以在设计面板中看到,因为我的标记扩展用lorem-ipsum填充了对象属性)

最好的R#功能不起作用:Resharper无法识别datacontext类型,只是在"object"类型的数据上下文中给出了"无法解析属性'{0}"的消息

自定义标记扩展

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

(允许我让R#了解接口datacontext类型的任何替代方案都会很棒)

谢谢 !

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

N. *_*sev 29

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

代替

<SomeControl d:DataContext={d:DesignInstance commons:IUser}>
    <!--element content here-->
</SomeControl>
Run Code Online (Sandbox Code Playgroud)

你可以写

<SomeControl>
    <d:SomeControl.DataContext>
        <x:Type Type="commons:IUser" />
    </d:SomeControl.DataContext>
    <!--element content here-->
</SomeControl>
Run Code Online (Sandbox Code Playgroud)

是的,这个解决方案看起来并不酷,但绝对不会更糟.

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

在泛型的情况下,只需为您的类型添加一个反引号和多个类型参数:<x:Type Type="commons:User`1" />.

BTW所有这些也适用于样式,<d:Style.DataContext>不会产生错误!

  • 到目前为止最好的答案,我在寻找避免样式错误的方法时发现了它。没有缺点(除了有点冗长),而且能够指定接口(和泛型)是巨大的。 (2认同)

ato*_*ras 18

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

d:DataContext="{d:DesignInstance commons:User, IsDesignTimeCreatable=False}"
Run Code Online (Sandbox Code Playgroud)

这实际上指示设计者仅使用类型进行智能感知和错误突出显示,而不是实际尝试实例化设计实例.


Ben*_*tra 5

我刚刚调查过或多或少相同的问题......实际上,我所做的是遵循MvvMLight的原则.确切地说,我使用了一个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>(); } }
    }
Run Code Online (Sandbox Code Playgroud)

您可以忽略Ninject _kernel,但如果要使用IoC构建ViewModel,则可能需要它(或类似的Ioc).

App.xaml将ViewModelLocator声明为ressource

  <Application.Resources>
    <ResourceDictionary>
      <viewModel:ViewModelLocator x:Key="ViewModelLocator" />
    </ResourceDictionary>
  </Application.Resources>
Run Code Online (Sandbox Code Playgroud)

所述MainWindow.DataContext属性绑定到BasicVM所述的构件ViewModelLocator.Text属性绑定到接口IBasicVMGetContent成员,该成员由R#静态识别(至少R#7.1与VS2012)

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        DataContext="{Binding BasicVm, Source={StaticResource ViewModelLocator}}"
        >
    <Grid>
        <TextBlock  Text="{Binding GetContent}"/>
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

您可以将我创建的存储库作为模板进行检查.