簡體   English   中英

使用XAML數據綁定獲取單擊的Item對象

[英]Getting clicked Item object using XAML databinding

我將ListBox綁定到一個item集合,其中包含我的Item類的實例。

這部分工作正常。 我遇到的問題是訪問單擊的ListBox項目item實例。 我已經包含了完整的示例和相關的XAML。

我還提供了一個示例,說明如何訪問listBoxItems_PreviewMouseDown事件處理程序內的Item實例。

我認為我缺少明顯的東西,但是當我單擊一個項目時代碼崩潰。 我是否還缺少將所有這些粘合在一起的綁定?

謝謝

后面的代碼

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Threading;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // Item class
        internal class Item : INotifyPropertyChanged
        {
            public Item(string name = null)
            {
                this.Name = name;
            }

            public string Name { get; set; }
            public string ImagePath { get; set; }
            public string SomeString { get; set; }
            public int SomeInt { get; set; }

            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(String propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

        // Item collection
        ObservableCollection<Item> ItemsCollection;

        public MainWindow()
        {
            InitializeComponent();

            // Initialize the items collection
            this.ItemsCollection = new ObservableCollection<Item>();

            for (int i = 0; i < 5; i ++)
            {
                Dispatcher.Invoke(new Action(() =>
                {
                    Item newItem = new Item
                    {
                        Name = "test " + i,
                        ImagePath = @"Images\" + i + ".jpg",
                        SomeString = "example" + i,
                        SomeInt = i,
                    };

                    // Add the new item to the collection
                    this.ItemsCollection.Add(newItem);
                }), DispatcherPriority.Background);
            }

            // Set the items source
            this.listBoxItems.ItemsSource = this.ItemsCollection;
        }

        // Handle mouse down events on listbox items
        private void listBoxItems_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            // Ideally, i'd like to do something like this
            Item item = sender as Item;

            // So then I could do for example
            Console.WriteLine(@"Clicked item SomeString: {0}, SomeInt {1}", item.SomeString, item.SomeInt);
        }
    }
}

XAML

<userControls:MyListBox x:Name="ItemsListBox" ItemsSource="{Binding ItemsCollection}" PreviewMouseDown="listBoxItems_PreviewMouseDown">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <VirtualizingStackPanel>
                <Image Source="{Binding ImagePath}" Width="200" Height="100"/>
                <TextBlock Text="{Binding Name}" />
            </VirtualizingStackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</userControls:MyListBox>

您可以獲取事件的OriginalSource並檢查其DataContext

var item = (e.OriginalSource as FrameworkElement)?.DataContext as Item;
if (item != null) { /* Do something with item... */ }

除了接受的答案,您也可以將PreviewMouseDown事件直接綁定到ListBoxItem

在那種情況下, XAML可以是(強調添加的<ListBox.ItemContainerStyle>節點):

<userControls:MyListBox x:Name="ItemsListBox" ItemsSource="{Binding ItemsCollection}" PreviewMouseDown="listBoxItems_PreviewMouseDown">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <VirtualizingStackPanel>
                <Image Source="{Binding ImagePath}" Width="200" Height="100"/>
                <TextBlock Text="{Binding Name}" />
            </VirtualizingStackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <EventSetter Event="PreviewMouseDown" Handler="listBoxItems_PreviewMouseDown" />
        </Style>
    </ListBox.ItemContainerStyle>
</userControls:MyListBox>

處理程序

    // Handle mouse down events on listbox items
    private void listBoxItems_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {

        // Ideally, i'd like to do something like this
        Item item = (sender as ListBoxItem).DataContext as Item;

        // So then I could do for example
        Console.WriteLine(@"Clicked item SomeString: {0}, SomeInt {1}", item.SomeString, item.SomeInt);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM