繁体   English   中英

编写绑定时,如何提供供Visual Studio XAML设计器使用的自定义属性名称列表?

[英]How to provide a list of custom property names for use by the Visual Studio XAML Designer when writing Bindings?

我有一个名为Model<T>的类,该类实现IDynamicObjectProvider并包装类型为T的对象,将属性访问转发给基础值,同时添加其他内容(例如, Model<T>实现INotifyPropertyChangedT不实现)。

我将这些Model<T>对象用作WPF中DataContext属性,本质上是:

public class Person { public string Name { get; set; } }

public class EditPersonViewModel {
    public Model<Person> Person { get; set; }
    public ICommand SavePersonCommand { get; set; }
}
<StackPanel d:DataContext="{d:DesignInstance vm:EditPersonViewModel}">
    <TextBox Text="{Binding Person.Name}" />
    <Button Command="{Binding SavePersonCommand}" /> 
</StackPanel>

WPF绑定引擎成功绑定到Model<Person>动态获取器和设置器。

现在,当我编写以Person.开头的绑定时,我想从XAML设计器中Person类型的属性中自动完成Person. ,从而需要尽可能少的应用程序代码; 理想情况下,它可以完全由定义Model<T>的库提供程序实现。 (我是写该库的人,我希望我的客户能够尽可能少地使用Model<T>类)。

以下是我知道的工作方式,以及我对它们的反对意见:

  1. 定义一个新类EditPersonViewModelDesign ,该类将镜像所有EditPersonViewModel属性,并将其用作设计实例。

     public class EditPersonViewModelDesign { public Person Person { get; set; } public ICommand SavePersonCommand { get; set; } } 
     <StackPanel d:DataContext="{d:DesignInstance vm:EditPersonViewModelDesign}"> <TextBox Text="{Binding Person.Name}" /> <Button Command="{Binding SavePersonCommand}" /> </StackPanel> 

    虽然不需要太多代码,但除非我要求人们使构建复杂化(无论他们是否仅添加这些类的项目,还是添加构建变量),否则此类仍会在运行时保留在库中,这一事实与我完全不合身 而且,Design和View模型类更容易分开。

  2. 完善内部元素的数据上下文并对其影响新的设计实例,例如:

     <StackPanel d:DataContext="{d:DesignInstance vm:EditPersonViewModel}"> <TextBox DataContext="{Binding Person}" d:DataContext="{d:DesignInstance m:Person}" Text="{Binding Name}" /> <Button Command="{Binding SavePersonCommand}" /> </StackPanel> 

    尽管该解决方案不需要创建新的类型,但是添加的XAML代码对我来说非常具有侵入性。

我认为这里实际上没有令人满意的解决方案,因为唯一真正的“非解决方法”是对动态绑定目标(即在设计实例的GetMetaObject()返回的DynamicMetaObject上调用GetDynamicMemberNames对IntelliSense的本机支持。的Model<T>所以,我建议一个特征请求 ,首先。

如果我是您的客户,我将不会花很多精力在所有地方都为IntelliSense支持而定义设计时间绑定。 与记住或查找并键入属性名称相比,需要更多的思考来指定正确的绑定。

这是一个想法,可能可行。 当然,我还没有测试过,但是经过一些研究,它可能会带您到那里。 您似乎知道自己在做什么:

看一下System.ComponentModel静态DesignerProperties类的IsInDesignTool属性:

DesignerProperties.IsInDesignTool

A类if DesignMode do this, else do that的办法,可以在的ViewModels实施,提出在这里 这可能是返回内部模型 (类型T)而不是包装模型(模型)的方法。 不知道它是否可以带您到任何地方,但是仔细考虑可能值得。 无论如何,这是一个有趣的功能……

最后一个想法:通过发布代码段来改善用户体验,并想到一种区分设计时间绑定和运行时绑定的直观方法。 也许像:

public abstract class ViewModelBase<T>
{
    public Model<T> Model { get; }

    // Maybe use compiler directives to throw exception if requested at runtime
    public T DesignModel { get; }
}

创建的代码段

d:Text="{Binding DesignModel.Name}" Text="{Binding Model.Name}"

不知道,VS代码段的功能多么强大,因为我正在使用ReSharper,但是使用ReSharper,您会将控件的DP设置为变量$ControlProp$ ,将属性名称$PropName$变量。 然后,如果您按Enter键,则IntelliSense将在设计时绑定上起作用,并将属性名称自动复制到第二个绑定。

您将输入一些快捷方式pbind ,然后输入Text ,Enter和N ,这将触发IntelliSense,选择Name ,Enter。 完成。 至少会很容易。

底线:对于您的问题,我没有即插即用的答案,但我的观点可能会有所启发...至少我希望如此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM