我可以在WPF/XAML中获得强类型绑定吗?

16
使用MVVM模式,您可以将DataContext设置为特定的ViewModel。现在有没有办法告诉XAML DataContext的类型,以便它验证我的绑定?类似于ASP.NET MVC中的类型视图数据。
5个回答

4

您可以以强类型的方式编写每个单独的绑定:

<TextBox Text="{Binding Path=(vm:Site.Contact).(vm:Contact.Name)}" />

然而,这并不能验证TextBox DataContext的类型是ViewModel.Site(我认为这是不可能的,但我可能错了)。


3

FrameworkElement.DataContext是一种依赖属性,它使数据绑定成为可能,其类型为object

正如其他人所指出的那样,您可以为称为DataTemplate的特殊模板指定DataContext的预期类型。许多控件(例如ItemsControlControlControl)提供了访问DataTemplates的功能,以允许您设置可视化表示对DataContext类型的期望。

Bryan是正确的,他没有测试他的代码。

应用正确的类型化DataTemplate的方法如下:

<Window>
    <Window.Resources>
        <DataTemplate x:Key="TypedTemplate" DataType="{x:Type myViewModel}">
        ...
        </DataTemplate>
    </Window.Resources>
    <ContentControl Content="{Binding}" ContentTemplate="{StaticResource TypedTemplate}" />
</Window>

ContentPresenter 直接继承自 FrameworkElement,并且没有 Template 属性。此外,Template 属性通常是指 ControlTemplate 类型的 Control.Template,它与 DataTemplate 完全不同。

我认为 Bryan 想到的是 ContentControl,它是两种根控件类型之一(另一个是 ItemsControl)。ContentControl 确实继承自 Control。因此,如果我们选择,我们可以在其上指定 Template 属性。

<Window>
   <Window.Resources>
      <DataTemplate x:Key="TypedTemplate" DataType="{x:Type myViewModel}">
      ...
      </DataTemplate>
      <ControlTemplate x:Key="ControlSkin" TargetType="{x:Type ContentControl}">
      ...
      </ControlTemplate>
   </Window.Resources>
   <ContentControl Content="{Binding}" ContentTemplate="{StaticResource TypedTemplate}" Template="{StaticResource ControlSkin}" />
</Window>

3

不,目前的规范在Xaml中没有强类型。我相信随着.Net 4.0的出现,Xaml应该会具备泛型的能力。有了这个,我认为在Xaml中实现强类型会更加容易。


2

我个人为我的ViewModel中的每个属性声明一个静态PropertyPath,并使用x:static作为绑定路径进行引用 - 例如:

public class MyViewModel
{
  public static PropertyPath MyPropertyPath = new PropertyPath("MyProperty");
  public bool MyProperty{get; set;}
}

这样做可以在构建时验证所有绑定。xaml代码如下:{Binding Path={x:Static local:MyViewModel.MyPropertyPath}},请注意保留HTML标签。

1

试试这个:

<Window>
    <Window.Resources>
        <DataTemplate x:Key="TypedTemplate" DataType="{x:Type myViewModel}">
            ...
        </DataTemplate>
    </Window.Resources>

    <ContentPresenter Content="{Binding}" Template="{StaticResource TypedTemplate}" />
</Window>

我还没有测试过这段代码,但它应该能给你一个想法。内容呈现器将显示当前的DataContext,它将使用DataTemplate。虽然编译器中它不是强类型的,但会在加载时立即抛出运行时错误(在窗口的InitializeComponent中)。如果出现问题,你应该能够在测试中轻松捕获到这个错误。


.Net 3.5没有DataTemplate.TargetType属性。 - Brian Low
@Brian 你说得对,应该是 DataType。我之前说的是未经测试的。我已经更新了答案来修复这个错误。 - Bryan Anderson

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