Clicking a button on a listviewitem that is not selected and gets the selected item

I have a question about setting up listview, as in the example below. When I click the button below in the expander header, I want this item to be selected as well, but what I see while the button command is working is that the selected item is still the previous selected item, and not the item that my button is on How Can I select an item when I click a button?

I tried to configure the ControlTemplate like this, but it did not work.

<Style TargetType="{x:Type ListViewItem}"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListViewItem}"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> <ControlTemplate.Triggers> <Trigger Property="IsKeyboardFocusWithin" Value="True"> <Setter Property="IsSelected" Value="True" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <ListView ItemsSource="{Binding MyItemSource, Mode=TwoWay}" SelectedItem="{Binding MySelectedItem, Mode=TwoWay}"> <ListView.ItemTemplate> <DataTemplate> <Expander IsExpanded="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}"> <Expander.Header> <Button Command={Binding MyCommand}>Click Me</Button> </Expander.Header> <!-- content here --> </Expander> </DataTemplate> </ListView.ItemTemplate> </ListView> 
0
source share
2 answers

I would suggest defining the SelectItem command in the main ViewModel, which takes the element to be selected as a parameter. Then, the method for executing this command can set the MySelectedItem property, set the IsSelected property in the ViewModel to true and call all further actions of the element itself (that is, what MyCommand is now executing). With the selection logic in the ViewModel and pure binding, you donโ€™t need to use a ListView , but you can stick with a simple ItemsControl :

Then XAML looks like this:

 <ItemsControl ItemsSource="{Binding MyItemSource}"> <ItemsControl.ItemTemplate> <DataTemplate> <Expander IsExpanded="{Binding IsSelected}"> <Expander.Header> <Button Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}, Path=DataContext.SelectItem}" CommandParameter="{Binding"}>Click Me</Button> </Expander.Header> <!-- content here --> </Expander> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 

MainViewModel will look something like this:

 public class MainViewModel : INotifyPropertyChanged { public ObservableCollection<ItemViewModel> MyItemsSource { get; private set; } public ItemViewModel SelectedItem { get... set... } public ICommand SelectItem { get; private set; } ctor()... private void ExecuteSelectItem(ItemViewModel item) { SelectedItem = item; foreach (var i in MyItemsSource) i.IsSelected = false; item.IsSelected = true; item.DoSomething(); } } 

It has always been easier for me to use the ItemsControl implement several lines of selection logic myself, instead of dealing with the messy binding of the ListView selection. In my opinion, it is quite intuitively clear how to implement custom selection behavior (several elements that allow only certain combinations, etc.). You can easily use the IsSelected property to apply an individual style to selected elements.

+1
source

You can try something like this in your view model, add an if statement to setter:

 private object _mySelectedItem; public object MySelectedItem { get { return _mySelectedItem; } set { if (_mySelectedItem != value && value != null) { _mySelectedItem = value; OnPropertyChanged("MySelectedItem"); } } } 
0
source

Source: https://habr.com/ru/post/945542/


All Articles