tags:

views:

20

answers:

2

I am attaching a PreviewMouseLoeftButtonDown event handler to a ListBox. The aim is to obtain the clicked ListBoxItem from the "e.Source" parameter in the event handler. This works perfectly with the following code:

</ListBox>
  <ListBox Name="listBox3">
  <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Horizontal"></StackPanel>
    </ItemsPanelTemplate>
  </ListBox.ItemsPanel>
  <ListBoxItem>
    <Rectangle Height="25" Width="30">
  </ListBoxItem>
</ListBox>

listBox3.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(PreviewMouseLeftButtonDown);
private void PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {}

On execution, "e.Source" is populated with the ListBoxItem I clicked. This is what I want to happen.

However the code below not behave the same.

<ListBox Name="listBox3">
  <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Horizontal"></StackPanel>
    </ItemsPanelTemplate>
  </ListBox.ItemsPanel>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Rectangle Width="30" Height="25"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

List<int> items = new List<int> {1};
listBox3.ItemsSource = items;

listBox3.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(PreviewMouseLeftButtonDown);
private void PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {}

In this case, the rectangle in the ListBox displays OK. However in this case, "e.Source" is populated with the ListBox containing the item I clicked. This is not what I desire, I want e.Source to contain the ListBoxItem I clicked, just like is happening in the 1st piece of code I attached above.

Any ideas?

A: 

e.OriginalSource will give the ListboxItem

Ragunathan
Interestingly e.OriginalSource returns a "Border" object in the first example I posted, and a "Rectangle" in the second. Never a ListBoxItem.I guess this is what frustrates me, the inconsistency of MouseEventArgs values for a ListBox Preview event...
Andrew
+1  A: 

In stead of relying on the Source or OriginalSource to be the ListBoxItem, why not set the event on the ListBoxItem itself through the Style?

<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
         <EventSetter Event="PreviewMouseLeftButtonDown" Handler="PreviewMouseLeftButtonDown"/>
    </Style>
</ListBox.ItemContainerStyle>

This way you will make sure that the source will always be the ListBoxItem.

Arcturus