WPF ListBox ListBoxItem programmatically selected and changed foreground
//xaml <Window x:Class="WpfApp49.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp49" WindowState="Maximized" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <Style TargetType="{x:Type GroupBox}"> <Style.Triggers> <Trigger Property="IsFocused" Value="True"> <Setter Property="Background" Value="Red"/> </Trigger> </Style.Triggers> </Style> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="FontSize" Value="50"/> <Setter Property="Foreground" Value="Green"/> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="True"/> </MultiTrigger.Conditions> <Setter Property="Foreground" Value="Red"/> <Setter Property="FontSize" Value="60"/> </MultiTrigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition/> </Grid.RowDefinitions> <ComboBox Grid.Row="0" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="30" SelectedItem="{Binding SelectedBook,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Id"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding CbxSelectionChangedCommand}" CommandParameter="{Binding ElementName=lbx}" /> </i:EventTrigger> </i:Interaction.Triggers> </ComboBox> <ListBox x:Name="lbx" Grid.Row="1" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="30" BorderBrush="Black" BorderThickness="3" > <ListBox.ItemTemplate> <DataTemplate> <GroupBox BorderBrush="Blue" BorderThickness="3" Height="300"> <Grid > <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{Binding Id}"/> <TextBlock Grid.Row="1" Text="{Binding ISBN}"/> <TextBlock Grid.Row="2" Text="{Binding Topic}"/> </Grid> </GroupBox> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Window> //xaml.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp49 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); MainVM vm = MainVM.VMInstance; this.DataContext = vm; vm.MainWin = this; this.Loaded += vm.MainWindow_Loaded; } } } //vm.cs using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace WpfApp49 { public class MainVM : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propName)); } } public Window MainWin { get; set; } private static readonly MainVM vmInstance = new MainVM(); public static MainVM VMInstance { get { return vmInstance; } } static MainVM() { } private MainVM() { } public void MainWindow_Loaded(object sender, RoutedEventArgs e) { BooksCollection = new ObservableCollection<Book>(); for(int i=0;i<1000;i++) { BooksCollection.Add(new Book() { Id=$"{i+1}_{Guid.NewGuid()}", Author=$"Author_{Guid.NewGuid()}", ISBN=$"ISBN_{Guid.NewGuid()}", Name=$"Name_{Guid.NewGuid()}", Topic=$"Topic_{Guid.NewGuid()}" }); } } private ObservableCollection<Book> booksCollection; public ObservableCollection<Book> BooksCollection { get { return booksCollection; } set { if(value!=booksCollection) { booksCollection = value; OnPropertyChanged("BooksCollection"); } } } private Book selectedBook; public Book SelectedBook { get { return selectedBook; } set { if(value!=selectedBook) { selectedBook = value; OnPropertyChanged("SelectedBook"); } } } private DelegateCommand cbxSelectionChangedCommand; public DelegateCommand CbxSelectionChangedCommand { get { if(cbxSelectionChangedCommand == null) { cbxSelectionChangedCommand = new DelegateCommand(CbxSelectionChangedCommandExecuted); } return cbxSelectionChangedCommand; } } private void CbxSelectionChangedCommandExecuted(object obj) { var lbx = obj as ListBox; if(lbx!=null && SelectedBook!=null) { lbx.ScrollIntoView(SelectedBook); lbx.SelectedValue = SelectedBook; int pos=lbx.SelectedIndex; ListBoxItem lbi = (ListBoxItem)lbx.ItemContainerGenerator.ContainerFromIndex(lbx.SelectedIndex); if(lbi!=null) { lbi.IsSelected = true; } } } } public class DelegateCommand : ICommand { public event EventHandler CanExecuteChanged; public void RaiseCanExecuteChanged() { var handler = CanExecuteChanged; if (handler != null) { handler?.Invoke(this, EventArgs.Empty); } } private readonly Action<object> _execute; private readonly Predicate<object> _canExecute; public DelegateCommand(Action<object> executeValue, Predicate<object> canExecuteValue) { _execute = executeValue; _canExecute = canExecuteValue; } public DelegateCommand(Action<object> executeValue) : this(executeValue, null) { } public bool CanExecute(object parameter) { if (_canExecute == null) { return true; } return _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } } public class Book { public string Id { get; set; } public string Author { get; set; } public string ISBN { get; set; } public string Name { get; set; } public string Topic { get; set; } } }
Key parts
1.
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
2.
<Style TargetType="{x:Type ListBoxItem}"> <Setter Property="FontSize" Value="50"/> <Setter Property="Foreground" Value="Green"/> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="True"/> </MultiTrigger.Conditions> <Setter Property="Foreground" Value="Red"/> <Setter Property="FontSize" Value="60"/> </MultiTrigger> </Style.Triggers> </Style> <ComboBox Grid.Row="0" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FontSize="30" SelectedItem="{Binding SelectedBook,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Id"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding CbxSelectionChangedCommand}" CommandParameter="{Binding ElementName=lbx}" /> </i:EventTrigger> </i:Interaction.Triggers> </ComboBox>
3.
private DelegateCommand cbxSelectionChangedCommand; public DelegateCommand CbxSelectionChangedCommand { get { if(cbxSelectionChangedCommand == null) { cbxSelectionChangedCommand = new DelegateCommand(CbxSelectionChangedCommandExecuted); } return cbxSelectionChangedCommand; } } private void CbxSelectionChangedCommandExecuted(object obj) { var lbx = obj as ListBox; if(lbx!=null && SelectedBook!=null) { lbx.ScrollIntoView(SelectedBook); lbx.SelectedValue = SelectedBook; int pos=lbx.SelectedIndex; ListBoxItem lbi = (ListBoxItem)lbx.ItemContainerGenerator.ContainerFromIndex(lbx.SelectedIndex); if(lbi!=null) { lbi.IsSelected = true; } } }