控件模板的设计时数据

7
使用d:DataContext提供设计时数据对于DataContext很容易,但是如何为在Style.Template中引用{TemplateBinding}{RelativeSource TemplatedParent}的控件属性提供设计时数据呢?
我可以在构造函数/加载事件中使用样例数据填充控件,当DesignerProperties.GetIsInDesignMode(this)返回true时,但这样做会破坏正常的设计体验,所以不能这样做。
那么对于无法修改的第三方控件呢?
1个回答

6

对于我自己的控件,通常会做如下处理:

<Style x:Key="FooStyle>
  <Setter Property="Template>
    <Setter.Value>
      <ControlTemplate TargetType="FooControl">
        <Grid d:DataContext="{d:DesignInstance FooDesignTimeData, IsDesignTimeCreatable=True}">
          ... guts of control template go here ...
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

"FooDesignTimeData"是一个类,提供适当形式的设计时数据(在运行时视图模型中实现接口是个好习惯)。

我认为这对于第三方控件也可以使用。您甚至可能不需要重新定制控件 - 您可能只需在样式中指定第三方控件并按上述方式提供设计时数据上下文,但我尚未尝试过该场景。我假设您之所以要费这么大劲是因为被迫使用一个没有良好设计时间体验的控件(例如通过提供Vendor.Controls.Design.dll或Vendor.Controls.Expression.Design.dll文件)。

要使用TemplateBindings,我没有很好的解决方案。通常我会创建一个测试页面来显示我的控件,并允许我切换模板。在集成期间,您将有一个额外的视图(无论是在应用程序内还是作为单独的应用程序),使您能够根据需要创建和操作控件的实例。 Blend SDK中的GoToStateAction目标触发操作在这里通常很有用。例如,为每个可视状态创建一个按钮,然后使用单击事件触发到达特定状态的转换。因此,您可以轻松地测试所有状态以及绑定到测试数据时的转换。这很低效且不真正提供设计时数据,但它可以工作。


正如我所说的,由于 d:DataContext{Binding} 很容易实现,但我需要的是 {TemplateBinding} - Marcin Wisnicki
你尝试过上述方法,但将d:DataContext作为样式的一部分进行赋值吗?对于这种情况,我没有一个很好的解决方案:通常我会创建一个测试页面来显示我的控件,并允许我切换模板。虽然有点取巧,但它确实有效。 - Mike Post
这看起来很合理。我得自己试试。但是你必须为集成版本更改XAML,或者你也可以在那里提供绑定吗? - Mare Infinitus
控件的XAML在集成和生产之间不会改变。唯一的区别是,在集成期间,您将拥有一个额外的视图(可以是您的应用程序内部或作为单独的应用程序),允许您根据需要创建和操作控件的实例。Blend SDK中的GoToStateAction目标触发器动作在这里通常很有用。例如,为每个可视状态创建一个按钮,然后使用Click事件触发到特定状态的转换。因此,您可以轻松测试所有状态以及绑定到测试数据时的转换。 - Mike Post
这种方法(测试页面)适用于简单的控件,但对于更复杂的控件则无法胜任,例如在显示测试页面中所显示的内容时,我无法找到编辑ItemContainerStyle的方法。无论如何,我猜这是最好的方法,人们要么这样做,要么手动编写XAML。如果您想获得赏金,请提供一个分开的答案,阐述您使用测试页面的想法(否则我将标记此答案)。 - Marcin Wisnicki
编辑以包括测试页面内容。 - Mike Post

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接