Текстовое поле или средство выбора даты в DataTemplate. В зависимости от типа данных я хочу одно, но не оба

#wpf #vb.net

#wpf #vb.net

Вопрос:

У меня есть datatemplate для моего listbox:

 <DataTemplate x:Key="CheckBoxTextBoxItemTemplate">
    <StackPanel Orientation="Horizontal">
        <CheckBox Focusable="False" IsChecked="{Binding IsChecked}" VerticalAlignment="Center"/>
        <ContentPresenter Content="{Binding Name, Mode=OneTime}" Margin="2,0" Width="140" VerticalAlignment="Center"/>
        <TextBox Text="{Binding FieldData}" Margin="2,0" Width="200" Visibility="{Binding FieldDataVisible}"/>
    </StackPanel>
</DataTemplate>
  

Однако элементы в списке, к которым привязан listbox, не все являются строковыми типами. Некоторые из них являются DateTime, а некоторые — целыми числами. Я хотел бы, чтобы вместо текстового поля для типов DateTime отображался datetimepicker. Как я могу это сделать.

Чтобы прояснить некоторые моменты, список заполняется во время выполнения с использованием отражения, поэтому я не знаю, какие поля относятся к каким типам заранее.

Ответ №1:

В блоке ресурсов ListBox вы могли бы указать DataTemplate для каждого типа (псевдокод):

 <ListBox.Resources>
  <DataTemplate DataType="{x:Type String}">
    <TextBlock />
  </DataTemplate>
  <DataTemplate DataType="{x:Type DateTime}">
    <DateTimePicker />
  </DataTemplate>
</ListBox.Resources>
  

Обратите внимание, что вы не ссылаетесь на эти шаблоны по идентификатору; они просто будут применены к любому экземпляру указанного типа данных в их области видимости (ListBox).

В качестве альтернативы вы можете реализовать DataTemplateSelector, чтобы возвращать разные шаблоны для каждого типа.

Комментарии:

1. Объекты в listbox имеют тип CheckableField, и у каждого есть свойства IsChecked, DataType, FieldDataVisible и FieldData, поэтому я не уверен, что первое решение сработает. Я думал о добавлении еще двух свойств, DateTime и DateTimeVisible. Во время заполнения списка я могу настроить видимые свойства на отображение / скрытие в зависимости от типа данных. Есть ли что-то неправильное в этом подходе?

2. Лучший выбор в этом случае — поместить DataTrigger в DataTemplate для CheckableField, который устанавливает видимость на основе типа данных. Но: в этом случае вы все равно можете использовать DataTemplateSelector (использовать CheckableField.DataType для управления выбором), или вы можете поместить DataTrigger в свой ListBox ItemContainerStyle , который установит весь шаблон элемента на основе DataType свойства. Это дает вам более жесткий контроль над тем, как отображаются объекты, чем возня с отдельными свойствами / видимостью.

3. ДА… Мне нравится datatrigger в ItemContainerStyle , спасибо.