Fabian
Fabian

Reputation: 356

Button in ListBox item's ItemsControl doesn't fire in WPF XAML

I've got the following setup for my ListBox in wpf:

Somehow when I click on one of the buttons in the ItemsPanel, the ICommand wont fire in the ViewModel class which is bound to the View.xaml. It looks like I'm selecting the ListBox item and not the item within the ItemsControl.

Here's the xaml code

<ListBox 
   Background="Transparent" 
   ItemTemplate="{StaticResource ProductGroupTemplate}" 
   FocusVisualStyle="{x:Null}" 
   VerticalContentAlignment="Top" 
   ItemsSource="{Binding NodeHeaders}" 
   Grid.Row="1" 
   Grid.ColumnSpan="3" 
   Grid.Column="0" 
   Grid.RowSpan="2" 
   SelectedItem="{Binding CurrentItem}" 
   BorderBrush="Transparent" 
   ScrollViewer.HorizontalScrollBarVisibility="Auto" 
   ScrollViewer.VerticalScrollBarVisibility="Disabled" 
   Margin="30,0,55,0" 
   VerticalAlignment="Top">
   <ListBox.Style>
      <Style TargetType="ListBox">
         <Setter Property="Visibility" Value="Collapsed" />
         <Style.Triggers>
            <DataTrigger Binding="{Binding HasParent}" Value="True">
               <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </ListBox.Style>
   <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
         <StackPanel Orientation="Horizontal" IsItemsHost="True"/>
      </ItemsPanelTemplate>
   </ListBox.ItemsPanel>
</ListBox>

And the DataTemplate

<DataTemplate x:Key="ProductGroupTemplate">
    <Grid Margin="0,0,20,0">          
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>


        <TextBlock Text="{Binding Description}" FontSize="20" Grid.Row="0" Grid.Column="0" Foreground="{StaticResource DefaultLabelColor}" />
        <ItemsControl ItemsSource="{Binding Nodes}" Grid.Row="1" Grid.Column="0">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical"  IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Text="{Binding Description}" Height="75" Width="150" Padding="5" Margin="5" Background="{StaticResource SalesItemsBackground}" 
                                Foreground="{StaticResource SalesItemsForeground}" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Left" Command="{Binding RelativeSource=
        {RelativeSource FindAncestor, 
        AncestorType={x:Type ContentControl}}, 
        Path=DataContext.Select}" CommandParameter="{Binding}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</DataTemplate>

Upvotes: 0

Views: 814

Answers (2)

Jay
Jay

Reputation: 841

That's because your data template's DataContext is set to an item from the listbox. If you have List<Person> bound to your list box every list box item's DataContext would be a Person which is why you can write something like "{Binding Description}". You have two ways to execute a command from DataTemplate one of them is the one that "Sheridan" told you. As an alternative you could set your element's DataContext to your parent View or ViewModel.

<DataTemplate>
    <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type View/ViewModel}}">
    </Grid>
</DataTemplate>

Upvotes: 0

Sheridan
Sheridan

Reputation: 69959

If you have a view model that declares an ICommand instance and is set as the DataContext of a view (UserControl, or Window), then you can use that property to access your ICommand instance. From the Button in your DataTemplate, you can use this RelativeSource Binding:

<Button Text="{Binding Description}" Height="75" Width="150" Padding="5" Margin="5" 
    Background="{StaticResource SalesItemsBackground}" TextAlignment="Left" 
    Foreground="{StaticResource SalesItemsForeground}" HorizontalAlignment="Center" 
    VerticalAlignment="Center" Command="{Binding DataContext.Select, RelativeSource={
    RelativeSource AncestorType={x:Type YourViewsPrefix:YourView}}}"
    CommandParameter="{Binding}"/>

Upvotes: 1

Related Questions