Search code examples
c#wpflistboxselectionchanged

Listbox SelectionChanged not working with Button in its ItemTemplate


Code below does not work when I select item in listbox, do you happen to know why?

<ListBox BorderBrush="Transparent" Background="Transparent" Name="listbox" HorizontalAlignment="Center" VerticalAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="selection_changed">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate> 
            <Button Height="90" Width="150" Template="{StaticResource cbutton}"/>                
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox> 

And template cbutton looks like this

 <ControlTemplate x:Key="cbutton" TargetType="Button">
            <Border CornerRadius="3" BorderThickness="3.5" BorderBrush="White">
                <Border.Background>
                    <LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
                        <GradientStop Color="DarkOrange" Offset="0.1"/>
                        <GradientStop Color="Orange" Offset="0.85"/>
                    </LinearGradientBrush>
                </Border.Background>
                <TextBlock FontWeight="ExtraBold" Foreground="White" TextAlignment="Center" TextWrapping="Wrap" FontSize="15" Text="{Binding name}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Border>
        </ControlTemplate>

Solution

  • The SelectionChanged event is not fired because the button is the control who captures the mouse click, not the ListBox.

    You can set your event handler to the button's click event instead.

       <Button Height="90" Width="150" Click="myClickEventHandler"/>  
    

    Regardless, I recommend you to use MVVM, instead of Code-Behind event handler.

    you could set a command which will fire when the button's click and send the command the button's content for example

      <Button Name="myButton" Height="90" Width="150" Template="{StaticResource cbutton}">     
          <i:Interaction.Triggers>
                 <i:EventTrigger EventName="SelectionChanged">
                       <i:InvokeCommandAction Command="{Binding DoSomething}"  CommandParameter="{Binding ElementName=myButton, Path=Content}"/>
                </i:EventTrigger>
          </i:Interaction.Triggers>
      </Button>
    

    ViewModel

    DoSomething = new DelegateCommand<object>(content=> 
    {
        // Do whatever you want 
    
    });
    

    If your not familar with MVVM, it will take some time to learn it, but it is definetly worth it :)