WPF - 很基础的 ListBox.ItemTemplate 问题

18

好的,这看起来是一个非常简单的问题,但却让我发疯。我正在学习DataTemplating,并试图将一个非常非常简单的ItemTemplate应用于ListBox。

然而,当我运行我的应用程序时,模板完全被忽略了,我只看到标准的ListBox,而实际上我期望看到一列带有“Test”旁边复选框的列表。

我已经尝试了几次,结果总是一样。我检查了谷歌上的几个资源,所有的资源都有相同的语法用于在ListBox上定义ItemTemplate,所以我真的看不出我哪里错了。

代码...

<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>
非常感谢任何帮助。对于这样一个看起来很愚蠢的问题,我表示歉意,但是我在这里遇到了第一个障碍 :(
AT
3个回答

25

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中。


8
如果您想要直接将ListBoxItems添加到ListBox中,可以使用ItemContainerStyle而不是ItemTemplate。但是,只有在需要每个项目具有唯一特征的情况下才建议这样做。如果您计划所有项目看起来都相同或使用ItemsSource创建动态列表,则建议将字符串(或其他自定义对象)添加到列表中,并使用ItemTemplate显示项目(请参见Jobi Joy的答案)。以下是使用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>

0

由于某些原因,如果使用ItemsSource填充ListBox,则仍然可以忽略DataTemplate:

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

请注意,此代码绑定到一个包含对象(TextAdapter : INotifyPropertyChanged)的ObservableCollection,该对象具有一个属性:string Text {...}。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接