9

我有一个 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?");
}
4

2 回答 2

12

一般来说,人们会对直接绑定的 CLR 对象感兴趣ListBoxItem,而不是实际的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的 'sDataContext等于您DataTemplate的 's DataContext。在这种情况下,一个Post.

private void DeleteButton_Click(object sender, RoutedEventArgs e){
  var post = ((Button)sender).DataContext as Post;
  if (post == null)
    throw new InvalidOperationException("Invalid DataContext");

  Console.WriteLine(post.author);
}
于 2009-04-19T20:13:39.077 回答
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.
}

您可以在此博客中找到一个示例。她使用 index 方法,但 Item 方法类似。

于 2009-04-19T20:22:14.967 回答