带有DataTemplates的WPF ListBoxItems - 如何从DataTemplate中引用绑定到ListBoxItem的CLR对象?

时间:2009-04-19 20:01:52

标签: wpf listbox datatemplate listboxitem

我有一个ListBox,它绑定到ObservableCollection

每个ListBoxItem都会显示DataTemplate。我的DataTemplate中有一个按钮,单击该按钮时,需要引用ObservableCollection的成员,它是DataTemplate的一部分。我无法使用ListBox.SelectedItem属性,因为单击按钮时项目未被选中。

所以要么:我需要弄清楚当鼠标悬停或点击按钮时如何正确设置ListBox.SelectedItem。或者我需要弄清楚另一种方法来获取对绑定到该按钮所属的ListBoxItem的CLR对象的引用。第二个选项似乎更清晰,但无论哪种方式都可以。

以下简化的代码段:

XAML:

<DataTemplate x:Key="postBody">
    <Grid>
        <TextBlock Text="{Binding Path=author}"/>
        <Button Click="DeleteButton_Click">Delete</Button>
    </Grid>
</DataTemplate>

<ListBox ItemTemplate="{StaticResource postBody}"/>

C#:

private void DeleteButton_Click(object sender, RoutedEventArgs e)
{
    Console.WriteLine("Where mah ListBoxItem?");
}

2 个答案:

答案 0 :(得分:12)

一般来说,人们会对直接绑定到ListBoxItem的CLR对象感兴趣,而不是真正的ListBoxItem。如果你有一个帖子列表,例如你可以使用你现有的模板:

<DataTemplate x:Key="postBody" TargetType="{x:Type Post}">
  <Grid>
    <TextBlock Text="{Binding Path=author}"/>
    <Button Click="DeleteButton_Click">Delete</Button>
  </Grid>
</DataTemplate>
<ListBox ItemTemplate="{StaticResource postBody}" 
  ItemSource="{Binding Posts}"/>

在您的代码隐藏中,您的Button DataContext等于DataTemplate的{​​{1}}。在这种情况下,DataContext

Post

答案 1 :(得分:3)

根据您的需要,您有多种可能性。

首先,主要问题是:“你为什么需要这个”?大多数情况下,对容器项的引用没有实际用途(不是说这是你的情况,但你应该详细说明)。如果您正在对列表框进行数据绑定,那么很少有这种情况。

其次,如果您的列表框名为myListBox.ItemContainerGenerator.ContainerFromItem(),则可以使用MyListBox从列表框中获取该项目。从sender参数中,您可以获取通过模板化的实际项目,例如(其中XXX是数据绑定数据的类型):

Container = sender as FrameworkElement;
if(sender != null)
{
    MyItem = Container.DataContext as XXX;
    MyElement = MyListBox.ItemContainerGenerator.ContainerFromItem(MyItem); // <-- this is your ListboxItem.
}

您可以找到this blog的示例。她使用索引方法,但Item方法类似。