WPF ListBox使用ItemsSource和ItemTemplate

3

当我在WPF ListBox中同时拥有ItemsSourceItemTemplate时,我对绑定是如何解析感到困惑。

我有一个名为ListOfIndexesObservableCollection<int>。 对于每个索引,我希望在数据库表中查找其记录。 我希望在IndexToObjectDescriptionConverter中实现这个功能。

<ListBox ItemsSource="{Binding ListOfIndexes}" 
         ItemTemplate="{Binding Converter={StaticResource IndexToObjectDescriptionConverter}}" />

但是我在转换器中设置断点后发现,被ItemTemplate绑定读取的值是窗口本身 - 也就是说,ItemsSourceItemsTemplateDataContext是相同的。

不好意思直言,但这似乎很愚蠢。 ItemTemplate 的整个作用是渲染ItemsSource中的每个元素,因此我猜想ItemTemplateDataContext将是正在呈现的单个元素。

所以,我的问题是如何告诉ItemTemplate它应该关注由ItemsSource表示的单个元素,而不是使用整个窗口的DataContext

2个回答

6
您需要使用数据模板来设置ItemTemplate。然后将其应用于列表中的每个项。
MSDN文档在这里: http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplate(v=vs.110).aspx 问题在于数据上下文范围。当您将ListBox的任何属性绑定时,它将使用ListBox的数据上下文 - 这就是为什么该数据上下文会传递给转换器的原因。如果您在ItemTemplate内设置数据模板,则它将将该模板应用于列表中的每个项。根据您提供的简单代码,我猜您需要在数据模板中放置转换器。
<ListBox ItemsSource="{Binding ListOfIndexes}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <ContentControl Content="{Binding Converter={StaticResource IndexToObjectDescriptionConverter}}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

在这种情况下,ContentControl将为每个项目呈现,并以该项目作为其数据上下文。

1
太好了。我想我没有意识到ItemTemplate中的DataTemplate会正确地识别数据上下文,而只是在ItemTemplate中定义绑定则使用控件的作用域。谢谢! - James Cronen

1
首先,我建议您仔细阅读MSDN中的数据模板概述页面,以便更好地了解此数据绑定过程。

我想在数据库表中查找它的记录。 我希望在IndexToObjectDescriptionConverter中这样做。

那是您的第一个错误。 IValueConverter负责转换数据绑定值,而不是访问数据库。 在视图模型中访问数据并使用结果填充公共属性。 然后将这些属性与XAML中的UI控件进行数据绑定。

请原谅我有点直言不讳,但这似乎很愚蠢

只有那些不了解情况的人才会这样认为。

我该如何告诉ItemTemplate它应该关注ItemsSource表示的单个元素,而不是使用整个窗口的DataContext?

您不需要告诉它任何内容...只需定义正确的XAML即可:
资源中:
<DataTemplate x:Key="SomeDataTemplate">
    <!-- The DataContext here is set to an item from the data bound collection -->
</DataTemplate>

在XAML中:

<ListBox ItemsSource="{Binding ListOfIndexes}" 
     ItemTemplate="{StaticResource SomeDataTemplate}" />

那就这样了。

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