Trigger SelectedIndex has changed by clicking on any control in the ListBoxItem area

I have a data template for ListBoxItem that contains several buttons and several custom controls such as Grid or Chart. Each button is bound to a corresponding command handler; the SelectedIndex property of the ListView control is also bound to the ViewModel.

Problem : in command handlers (which are attached to buttons) I can’t allow the currently selected item / index because it does not change by clicking a button or another control in a ListBox, but when I click on the ListBoxItem area - SelectedIndex changes.

The question is , how do I call SelectedIndex to change when I click on any control in ListBoxItem?

+3
source share
4 answers

Add this to your ListBox.Resources

<ListBox.Resources>
    <Style TargetType="{x:Type ListBoxItem}">
        <Style.Triggers>
            <Trigger Property="IsKeyboardFocusWithin" Value="True">
                <Setter Property="IsSelected" Value="True" />
            </Trigger>
        </Style.Triggers>
    </Style>
</ListBox.Resources>

EDIT

The previous method only makes ListBoxItem selected as long as it has keyboard focus. If you move focus from a ListBoxItem, it will be canceled again.

Here's another easy way to select a ListBox when the keyboard focus moves inside the element and it remains selected when the focus is removed from the ListBoxItem.

<Style TargetType="{x:Type ListBoxItem}">
    <EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
</Style>

And in the code below

protected void SelectCurrentItem(object sender, KeyboardFocusChangedEventArgs e)
{
    ListBoxItem item = (ListBoxItem)sender;
    item.IsSelected = true;
}
+6
source

Can you set the item as the selected item in a related command? If the view ItemList of your list has access to any viewBoxes model, you should be able to set the property that you bound there.

Private Sub ButtonClickExecute()
     ListBoxVM.SelectedItem = Me.MyModelItem
End Sub

, , SelectedItem bound /, PropertyChangeNotification .

ViewModel , , .

, #. :

ListBoxVM.selectedItem = this.myModelItem;
+1

XAML:

ItemContainerStyle , . ( , , ...)

:

  <Grid>  
    <Grid.Resources>
      <x:Array x:Key="strings" Type="sys:String" >
        <sys:String>test</sys:String>
        <sys:String>test</sys:String>
        <sys:String>test</sys:String>
        <sys:String>test</sys:String>
      </x:Array>
      <Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">     
      <Setter Property="ContentTemplate">
        <Setter.Value>
          <DataTemplate>
            <ContentPresenter />
          </DataTemplate>
        </Setter.Value>
      </Setter>
      <Style.Triggers>         
      <Trigger Property="IsKeyboardFocusWithin" Value="True">          
        <Setter Property="IsSelected" Value="True" />
      </Trigger>     
      </Style.Triggers>
      </Style>
    </Grid.Resources>
  <ListBox ItemsSource="{Binding Source={StaticResource strings}}"  ItemContainerStyle="{StaticResource ContainerStyle}" >
  <ListBox.Resources>
  <DataTemplate DataType="x:Type ListBoxItem">
    <ListBoxItem IsSelected="{Binding IsKeyboardFocusWithin}" />
  </DataTemplate>

  </ListBox.Resources>
  <ListBox.ItemTemplate>
  <DataTemplate>
      <Button Content="{Binding}" />
    </DataTemplate>
  </ListBox.ItemTemplate>
  </ListBox>
  </Grid>
+1

If you are only interested in the element under the data template, you can use a CommandParameter with a binding as an argument.

CommandParameter = {Binding}

This will pass the current item as a parameter to the command, so there is no need to track the selected item.

+1
source

All Articles