Get the ListBox row object from a button that is on the DataTemplate
I have a ListBox
with a DataTemplate
. The template has a Button
on it. When the Button
is clicked I want to do some logic with the object that is each row (in this case an object called WorkItemTypeMappings
).
In theOnClick
how can I go from the Button
(object sender
) to the object that is row that the button is on?
Here is the XAML of my ListBox
:
<ListBox ItemsSource="{Binding Source={StaticResource WorkItemTypeMappingsCollectionView}}开发者_C百科" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Name="lstWITypes">
<ListBox.GroupStyle>
<x:Static Member="GroupStyle.Default"/>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding SourceType, Converter={StaticResource WorkItemTypeToStringConverter}}"/>
<ComboBox Grid.Column="1" SelectedItem="{Binding DestType}" ItemsSource="{Binding WorkItemTypesForCurrentDestProject, Source={x:Static loc:MainMediator.Instance}, diagnostics:PresentationTraceSources.TraceLevel=High}" DisplayMemberPath="Name" />
<!-- This is the button-->
<Button Grid.Column="2" Content="{Binding PercentMapped}"
Click="ManualMappingClick"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What you can do as an alternative is to use Command instead of Event. If you bind your button to a command and pass along with it a command parameter, you should be able to get the item that is related to that button. Example code:
<!-- This is the button-->
<Button
Grid.Column="2"
Content="{Binding PercentMapped}"
Command="SolutionNamespace:CommandClass.ButtonClickedCommand"
CommandParameter="{Binding}" />
I am not sure how familiar you are with WPF commanding but you will notice that the CommandParameter binds to the context without a path name, that is to say it binds to the WorkItemTypeMappings that you need.
Command Example Code:
public static SimpleCommand ButtonClickedCommand { get; set; }
static CommandClass()
{
ButtonClickedCommand = new SimpleCommand
{
ExecuteDelegate =
x=> ButtonClicked(x as WorkItemTypeMappings)
};
}
public static ButtonClicked(WorkItemTypeMappings mappings)
{
if(mappings != null) MessageBox.Show(mapping.PercentMapped)
}
You will notice that the ButtonClickedCommand is static, this is required because the button cannot access the command from its current binding context.
SimpleCommand
is just a simplified implementation of the ICommand, can Google this one if you're not sure. I hope this is not an overkill to your problem, but you cannot go wrong with WPF Commands.
Good luck.
Try using VisualTreeHelper to find the parent ListBoxItem for the button. A few good general all-purpose helper functions can be found here:
How can I find WPF controls by name or type?
so, for example, you could find the ListBoxItem from the click event with a call like this:
ListBoxItem item = UIHelper.FindVisualParent<ListBoxItem>(sender);
have you tried ListBox.SelectedItem?
Additionally, if you have a reference to the ListBoxControl already, and you also have the data item representing the row (I assume so since you have the binding, and thus can drag it out of the DataContext on the button), you can ask the ItemsContainerGenerator. ContainerFromItem to give you give you the actual UIElement for the row.
The itemcontainergenerator can be found as a property on the listview itself. (technically the itemscontrol, since thats where it's defined)
精彩评论