Reputation: 5055
I have a data template in WPF that is attached to a ResultsViewModel class and renders the VM in a table format. A bunch of these make up ListBoxItems in a ListBox. What I want is in each individual table to have a little X at the top right of the border where if you click it, it calls a function that removes that item from the listbox.
I have tried with a Hyperlink and event OnClick but then I have to have the DataTemplate in the main XAML and not in a resource dictionary as it needs a x:Class tag to use events, but then the event gets fired in the MainViewModel, which isn't the worst thing in the world as the observable list is held in the MainViewModel and needs to be removed at that point anyway, but I can't figure out how to get a reference to the ResultsViewModel of the list box item that contained the data template that was clicked
<DataTemplate x:Key="ErroredResultsTemplate" DataType="x:Type vm:ResultsViewModel" >
<Border x:Name="Border" BorderBrush="{StaticResource ResultProcessedBorder}" Background="{StaticResource ResultFill}" BorderThickness="4" CornerRadius="10" Margin="6" Padding="5" Width="110" Height="110">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="83" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Foreground="{StaticResource ResultGrayText}" FontWeight="Bold" HorizontalAlignment="Right" VerticalAlignment="Top">
<Hyperlink Click="Close_Results">X</Hyperlink>
</TextBlock>
<TextBlock Width="90" Text="An error occurred calculating results" TextWrapping="Wrap" Foreground="{StaticResource ResultGrayText}" FontWeight="Bold" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Top" TextAlignment="Center" />
</Grid>
</Border>
</DataTemplate>
Upvotes: 0
Views: 1176
Reputation: 69979
You can achieve this in two ways:
Create a property of type ResultsViewModel
in your parent view model (that contains your collection of ResultsViewModel
objects) and bind that to the SelectedItem
property of your ListBox
. Add some kind of RelayCommand
to the parent view model to handle the delete action, add a Button
to your DataTemplate
and bind its Command
property to the new command. Then, when any delete button is clicked, you can just remove the item found in the SelectedItem
property from your collection and the UI should update accordingly (assuming that you've implemented the INotifyPropertyChange
interface).
You can simply bind from the DataTemplate
of each item in the ListBox
to the parent view model directly. This assumes that you have a Command
in your parent view model named Delete
and that the parent view model is bound to the DataContext
property of the Window
or UserControl
that the ListBox
appears in. Also note the important CommandParameter="{Binding}"
part which passes the data object from each item in the collection to the object
parameter in the Command
when a Command
is called.
Example:
<Button Content="X" Command="{Binding DataContext.Delete,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type
XmlNameSpace:WindowOrUserControlName}}, Mode=OneWay}"
CommandParameter="{Binding}" />
Upvotes: 1