Как вы можете включить автоматический выбор DataTemplate на основе типа данных, как вы можете с помощью элемента управления? - PullRequest
8 голосов
/ 27 сентября 2011

Мы пишем очень специализированный ItemsControl, который на самом деле имеет три ContentPresenter на «строку», каждый из которых привязан к отдельному объекту (подумайте о сетке бедняка) вместо более общего, такого как ListBox.

Теперь с ListBox, если вы не укажете явно либо ItemTemplate, либо ItemTemplateSelector, похоже, существует некий внутренний селектор, который применяет шаблон исключительно на основе типа данных. Однако наши ContentPresenter не собирают их. Мы также попытались вместо этого переключить их на ContentControl, но это тоже не сработало.

Теперь я знаю, что могу просто написать свой собственный DataTypeTemplateSelector, который делает это, но мне интересно, если эта функциональность уже «запечена» где-то, учитывая, что она используется с таким количеством ItemsControl (ListBox, TreeView, ComboBox ', DataGrid и т. Д.) И в соответствии с этой статьей MSDN ...

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}" 

Итак ... кто-нибудь хочет нанести удар, почему бы и нет?

1 Ответ

7 голосов
/ 27 сентября 2011

DataType, по любой безумной причине , имеет тип Object, следовательно, DataTemplates имеет значение string, установленное в этом свойстве, если вы не используете x:Type.


Редактировать: Существует очень веская причина, по которой свойство является объектом, поскольку всегда те, кто может (и делают) читать, явно имеют преимущество:

Если шаблон предназначен для данных объекта, это свойство содержит имя типа объекта данных (в виде строки). Чтобы сослаться на имя типа класса, используйте расширение разметки x: Type. Если шаблон предназначен для данных XML, это свойство содержит имя элемента XML. См. Примечания к документации для получения подробной информации об указании пространства имен не по умолчанию для элемента XML.

...