WPF - очень простой вопрос ListBox.ItemTemplate
Хорошо, это смущающе простая проблема, но сводит меня с ума. Я изучаю DataTemplating и пытаюсь применить очень ОЧЕНЬ простой ItemTemplate к ListBox.
Однако, когда я запускаю свое приложение, шаблон полностью игнорируется, и я просто получаю стандартный список, тогда как на самом деле я ожидаю увидеть список флажков с тестом "рядом".
Я пробовал это несколько раз и всегда был тем же результатом. Я проверил несколько ресурсов в Google, и все они имеют одинаковый синтаксис для определения и ItemTemplate в ListBox, поэтому я действительно не вижу, где я ошибаюсь.
код...
<Grid x:Name="LayoutRoot">
<ListBox x:Name="TestList"
SelectionMode="Multiple">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox Content="Check this checkbox!"/>
<TextBlock>Test</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Items>
<ListBoxItem>Bob</ListBoxItem>
<ListBoxItem>Jim</ListBoxItem>
<ListBoxItem>Dave</ListBoxItem>
<ListBoxItem>Larry</ListBoxItem>
<ListBoxItem>Tom</ListBoxItem>
</ListBox.Items>
</ListBox>
</Grid>
Любая помощь очень ценится. Извините за такой немой вопрос, но я действительно упал на первое препятствие здесь: (
в
Ответы
Ответ 1
ItemTemplate
не будет работать, если вы поместите ListBoxItem
непосредственно в качестве элементов. Общая концепция заключается в том, что вы привязываете коллекцию CRL к ListBox.ItemsSource
, а затем указываете ItemTemplate
. Проверьте приведенный ниже код.
<Grid x:Name="LayoutRoot">
<ListBox x:Name="TestList" SelectionMode="Multiple">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox Content="Check this checkbox!"/>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Items>
<sys:String>Bob</sys:String>
<sys:String>Jim</sys:String>
<sys:String>Dave</sys:String>
<sys:String>Larry</sys:String>
<sys:String>Tom</sys:String>
</ListBox.Items>
</ListBox>
</Grid>
где sys
- это xmlns:sys="clr-namespace:System;assembly=mscorlib"
Таким образом, 5 ListBoxItems
генерируются в фоновом режиме и добавляются в ListBox
.
Ответ 2
Вы можете использовать ItemContainerStyle вместо ItemTemplate, если хотите добавить ListBoxItems непосредственно в ListBox.
Однако это рекомендуется только тогда, когда вам нужны уникальные характеристики для каждого элемента.
Если вы планируете все элементы, которые выглядят одинаково, или создавая динамический список с помощью ItemsSource, я бы рекомендовал вам добавить в свой список строки (или другой пользовательский объект) и использовать ItemTemplate для отображения ваших элементов. (см. Ответ Джоби Джой)
Вот пример использования ItemContainerStyle:
<ListBox
x:Name="TestList"
SelectionMode="Multiple">
<ListBox.ItemContainerStyle>
<Style
TargetType="ListBoxItem">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="ListBoxItem">
<StackPanel>
<CheckBox
Content="Check this checkbox!" />
<TextBlock
Text="{TemplateBinding Content}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Items>
<ListBoxItem>Bob</ListBoxItem>
<ListBoxItem>Jim</ListBoxItem>
<ListBoxItem>Dave</ListBoxItem>
<ListBoxItem>Larry</ListBoxItem>
<ListBoxItem>Tom</ListBoxItem>
</ListBox.Items>
</ListBox>
Ответ 3
По какой-то причине DataTemplate все равно можно игнорировать, если ListBox заполняется с помощью ItemsSource, например:
<ListBox Name="Test" x:FieldModifier="public" ItemsSource="{Binding UpdateSourceTrigger=PropertyChanged}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Обратите внимание, что это связано с объектами ObservableCollection, содержащими объекты (TextAdapter: INotifyPropertyChanged), с одним свойством: string Text {...}