2009-04-19 21 views
8

Tôi có một ListBox, được gắn với một số ObservableCollection.WPF ListBoxItems với DataTemplates - Làm thế nào để tôi tham chiếu đối tượng CLR bị ràng buộc vào ListBoxItem từ bên trong DataTemplate?

Mỗi ListBoxItem được hiển thị với DataTemplate. Tôi có một nút trong số DataTemplate của mình, khi được nhấp, cần tham chiếu đến thành viên của ObservableCollection đó là một phần của DataTemplate cho. Tôi không thể sử dụng thuộc tính ListBox.SelectedItem vì mục này không được chọn khi nhấp vào nút.

Vì vậy, hoặc: Tôi cần tìm ra cách đặt đúng ListBox.SelectedItem khi di chuột hoặc khi nút được nhấp. Hoặc tôi cần phải tìm ra một cách khác để có được một tham chiếu đến đối tượng CLR ràng buộc với ListBoxItem rằng nút thuộc về. Tùy chọn thứ hai có vẻ sạch hơn, nhưng cả hai cách có thể là OK.

đoạn mã đơn giản dưới đây:

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?"); 
} 

Trả lời

11

người Nói chung sẽ được quan tâm trong một đối tượng CLR ràng buộc trực tiếp đến ListBoxItem, không phải là thực tế ListBoxItem. Nếu bạn đã có một danh sách các bài viết ví dụ bạn có thể sử dụng mẫu hiện tại của bạn:

<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}"/> 

và trong bạn code-behind, Button của bạn 's DataContext bằng DataTemplate của bạn' s DataContext. Trong trường hợp này là 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); 
} 
+0

Điều này là hoàn hảo và bạn cũng đã cố gắng khắc phục từ ngữ của câu hỏi của mình. Tôi sẽ chỉnh sửa nó khi bạn nói đúng, tôi quan tâm đến đối tượng CLR bị ràng buộc, không phải chính ListBoxItem. –

3

Bạn có một số khả năng, tùy thuộc vào việc bạn cần làm.

Trước tiên, câu hỏi chính là: "tại sao bạn cần điều này"? Hầu hết thời gian, không có sử dụng thực sự cho một tham chiếu đến mục container (không nói đây là trường hợp của bạn, nhưng bạn nên xây dựng). Nếu bạn đang databinding hộp danh sách của bạn, hiếm khi có một trường hợp cho điều đó.

Thứ hai, bạn có thể lấy mặt hàng từ Hộp danh sách, sử dụng myListBox.ItemContainerGenerator.ContainerFromItem(), với điều kiện hộp danh sách của bạn có tên là MyListBox. Từ các tham số người gửi, bạn có thể lấy lại mặt hàng thực tế đã được templated qua, ví dụ (nơi XXX là loại cho bạn dữ liệu databound):

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

Bạn có thể tìm thấy một ví dụ một this blog. Cô ấy sử dụng phương thức chỉ mục, nhưng phương thức Item tương tự.

+0

Câu trả lời hay cho câu hỏi như đã được viết. bendewey giả định chính xác tôi không có ý nói những gì tôi đã nói, nhưng điều này cũng được đánh giá cao. Đã bỏ phiếu. –

Các vấn đề liên quan