如何像使用项目控件一样根据数据类型启用自动数据模板选择?

发布于 2024-12-06 13:19:53 字数 1866 浏览 0 评论 0原文

我们正在编写一个非常专业的 ItemsControl,它实际上每“行”有三个 ContentPresenter,每个都绑定到不同的对象(想想穷人的网格),而不是更常见的一种,例如 ListBox

现在,如果您没有显式指定 ItemTemplateItemTemplateSelector,则使用 ListBox ,似乎有一些应用模板的内部选择器纯粹基于数据类型。然而,我们的 ContentPresenter 并没有接收到它们。我们还尝试将它们切换为 ContentControl,但这也没有奏效。

现在我知道我可以简单地编写自己的 DataTypeTemplateSelector 来执行此操作,但我想知道该功能是否已经“烘焙”在某个被认为与如此多的 ItemsControl 一起使用的地方的(ListBoxTreeViewComboBox'、DataGrid 等)并根据此 MSDN 文章。 ..

<一href="http://msdn.microsoft.com/en-us/library/ms742521.aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/ms742521.aspx

...它应该默认工作!但话又说回来,事实并非如此。

这是我们的(伪)代码...

<UserControl.Resources>

    <!-- These all work when the relevant items are in a ListBox,
         but not with stand-alone ContentPresenters or ContentControls -->

    <DataTemplate DataType="local:SomeTypeA">
        <TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Blue" />
    </DataTemplate>

    <DataTemplate DataType="local::SomeTypeB">
        <TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Purple" />
    </DataTemplate>

    <DataTemplate DataType="local::SomeTypeC">
        <TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Purple" />
    </DataTemplate>

</UserControl.Resources>

<!-- These don't pick up the templates -->
<ContentControl Content="{Binding Field1}" />
<ContentPresenter Content="{Binding Field2}" />

<!-- This however does -->
<ListBox ItemsSource="{Binding AllItems}" 

那么...有人想尝试一下为什么不呢?

We're writing a very specialized ItemsControl which actually has three ContentPresenter's per 'row', each bound to a different object (think poor-man's grid) instead of the more common one, like a ListBox.

Now with a ListBox if you don't explicitly specify either an ItemTemplate or an ItemTemplateSelector, there seems to be some internal selector that applies the template based purely on data type. However, our ContentPresenter's aren't picking them up. We've also tried switching them to ContentControl's instead, but that hasn't worked either.

Now I know I can simply write my own DataTypeTemplateSelector that does this, but I'm wondering if that functionality is already 'baked in' somewhere considered its used with so many ItemsControl's (ListBox, TreeView, ComboBox', DataGrid, etc.) and according to this MSDN article...

http://msdn.microsoft.com/en-us/library/ms742521.aspx

...it should work by default! But again, it doesn't.

Here's our (pseudo) code...

<UserControl.Resources>

    <!-- These all work when the relevant items are in a ListBox,
         but not with stand-alone ContentPresenters or ContentControls -->

    <DataTemplate DataType="local:SomeTypeA">
        <TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Blue" />
    </DataTemplate>

    <DataTemplate DataType="local::SomeTypeB">
        <TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Purple" />
    </DataTemplate>

    <DataTemplate DataType="local::SomeTypeC">
        <TextBlock Text="{Binding Converter={c:DataTypeNameConverter}}" Foreground="Purple" />
    </DataTemplate>

</UserControl.Resources>

<!-- These don't pick up the templates -->
<ContentControl Content="{Binding Field1}" />
<ContentPresenter Content="{Binding Field2}" />

<!-- This however does -->
<ListBox ItemsSource="{Binding AllItems}" 

So... anyone want to take a stab at why not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

万水千山粽是情ミ 2024-12-13 13:19:53

数据类型无论出于什么疯狂的原因,都是Object类型,因此DataTemplates在该属性中设置了一个string,除非您使用x:Type


编辑:属性作为对象是有充分理由的,因为那些能够(并且确实)阅读的人显然具有优势:

如果模板用于对象数据,则此属性包含数据对象的类型名称(作为字符串)。要引用类的类型名称,请使用 x:Type 标记扩展。如果模板用于 XML 数据,则此属性包含 XML 元素名称。有关为 XML 元素指定非默认命名空间的详细信息,请参阅文档注释。

DataType, for whatever crazy reason, is of type Object, the DataTemplates hence have a string set in that property unless you use x:Type.


Edit: There is a very good reason for the property being an object, as always those who can (and do) read are clearly at an advantage:

If the template is intended for object data, this property contains the type name of the data object (as a string). To refer to the type name of the class, use the x:Type Markup Extension. If the template is intended for XML data, this property contains the XML element name. See the documentation remarks for details about specifying a non-default namespace for the XML element.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文