0

Ok, I have the folllowing, XAML markup in a Silverlight MVVM Light app. This is part of the view. In the click event of the btnClearBodyMark in the view's codebehind I've tried traversing the tree upward using the .Parent properties, first parent is the horizontal stackpanel, then it's parent is the vertical stackpanel, and its parent is the Grid, but then the Grid's parent is another Grid?? How can I get a reference to the ListBoxItem that the button belongs to???

<ListBox Name="listboxBodyMarkValues" ItemsSource="{Binding}" Height="Auto" Width="Auto" SelectionChanged="listboxBodyMarkValues_SelectionChanged">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <StackPanel x:Name="stackBodyMarkList" Orientation="Vertical" Margin="5" Height="Auto">
                    <StackPanel Orientation="Horizontal" Margin="5" Height="Auto">
                        <TextBlock x:Name="txtId" Width="50" Height="Auto" Margin="10" HorizontalAlignment="Left" VerticalAlignment="Center" FontWeight="Bold" Text="{Binding Id}" />
                        <ComboBox x:Name="comboDom1" Width="100" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center" ItemsSource="{Binding Dom1}" SelectedItem="{Binding Dom1SelectedItem, Mode=TwoWay}" Visibility="{Binding ComboIsVisible}"/>
                        <Button x:Name="btnClearBodyMark" Content="Delete Body Mark" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center" Click="btnClearBodyMark_Click" />                                         
                    </StackPanel>
                    <TextBox x:Name="txtNotes" VerticalAlignment="Stretch" VerticalContentAlignment="Top" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="{Binding ManualText, Mode=TwoWay}" AcceptsReturn="True" Margin="5" MaxWidth="400" MaxHeight="200" VerticalScrollBarVisibility="Auto" IsEnabled="{Binding ManualTextIsEnabled}" />
                </StackPanel>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
mkelley82
  • 177
  • 1
  • 13
  • 1
    Do you need the ListBoxItem or the data item it's bound to? What are you trying to do? – Phil Apr 29 '12 at 20:27

2 Answers2

0

Normally, in MVVM, if you bound the Command, you could pass a CommandParameter and in it put the DataContext, but the MOST important thing to do is to pass the "DataContext". since this is tied to a Click event, typecast the sender as a button, acess the DataContext and this should be the object in the listbox. So if your listbox is bound to an ItemsSource of "Customers", your "DataContext" on the button should be a "Customer" object. It should be passed down since the StackPanel's DataContext will be that object, and all it's children should have the same. E.g.:

public void btnClearBodyMark_Click(object sender, ButtonClickEventArgs e)
{
    var myRef = (sender as Button).DataContext;
}

Something like that.
P.S. since this is most likely bound to a set of "objects". The item is no longer a ListBoxItem per say, but rather a datatype of the bound collection.
Also, you can save yourself the work of "SelectionChanged" event if you bound the SelectedItem property of the ListBox to a property in your ViewModel, with a mode of Mode=TwoWay. Make sure that your property, for example "SelectedListItem" in the ViewModel notifies the property changed event by ensuring that your ViewModel implements INotifyPropertyChanged which is found in System.ComponentModel i think. That way, once the user selects something, there's no need for an even handler ;).

Neel Edwards
  • 308
  • 3
  • 7
0

I struggled with that too. As a sidenote: You shouldn't pass the ListBoxItem. The view-model should not care, how the list is implemented.

What really helped me out here was the MVVM-Light toolkit. You can create your own command that accepts one parameter (of the type of the ListBoxItem's DataContext), and then execute it on your desired event.

Details here: http://www.galasoft.ch/mvvm/#tutorials

LueTm
  • 2,366
  • 21
  • 31