39799

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

Answer1:

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.

Answer2:

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);

Answer3:

have you tried ListBox.SelectedItem?

Answer4:

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)

Recommend

  • How can i receive a reference to a control in WPF (MVVM)?
  • Search in A ListBox
  • does c++ have an equivalent boost::numeric_cast(SourceType)?
  • Windows Phone 7 - Playing streaming video
  • C# InvokeRequired with property getter
  • Enable text box based on radio button selected
  • No server chosen by WritableServerSelector from cluster
  • finding values in pandas series - Python3
  • .exe processes are not running from a C# application when called
  • How to detect in selenium whether loading of a javascript file is loaded via ajax?
  • How to install dependencies while creating a .deb installer?
  • DataGrid: Help accessing a control defined in a CellEditingTemplate
  • Creating account using accounts-password in meteor
  • Glassfish/Wildfly not failing if @Resource cannot be resolved?
  • Xpath how to get element by index AND attribute
  • Is there a pre-defined built-in function to convert a number to its binary format in C++?
  • how to append two or more dataframes in pandas and do some analysis
  • pandas mix position and label indexing without chaining
  • Compare Pandas dataframes and add column
  • Open pdf.js with a data URL in IE11
  • Why do empty folders disappear when adding Visual Studio solution to TFS?
  • Can TextIO write to prefixes derived from the window maxTimestamp?
  • No internet connectivity inside docker container running inside kubernetes with weave as networking
  • Change Font Style (bold, Italic, bold italic) in C# [duplicate]
  • JFreeChart BarChart - Category Markers
  • Check multiple file exists or not using ANT
  • Display Custom Marker in Google Maps Using Relative File Path [duplicate]
  • 502 - Web server received an invalid response while acting as a gateway or proxy server
  • JSONPath Syntax when dot in key
  • What is the use of the SHT_NULL section in ELF?
  • YQL finance gets null in results
  • C# where to add a method
  • Binding a list with another list with WPF
  • In App Purchase functionality is not present in your binary
  • How to remove comma or any characters from Python dataframe column name
  • calling a fragment from fragment
  • Passing information to server-side function in a Google Docs Add On
  • What's the syntax to inherit documentation from another indexer?
  • Is there any way to access browser form field suggestions from JavaScript?
  • jQuery tmpl and DataLink beta