#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
в свой ListBoxItemContainerStyle
, который установит весь шаблон элемента на основеDataType
свойства. Это дает вам более жесткий контроль над тем, как отображаются объекты, чем возня с отдельными свойствами / видимостью.3. ДА… Мне нравится datatrigger в
ItemContainerStyle
, спасибо.