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 {...}