Большое спасибо @BionicCode за исчерпывающий ответ. Я закончил тем, что пошел с другим решением, которое может или не может быть хорошим соглашением; Я любитель.
Во-первых, мне не нужна сбор данных / настойчивость.
Что касается решения для модели данных и переопределения ListBoxItem.Template, я использую предопределенный класс 'SyndicationItem' в качестве класса данных (мое приложение - Rss Reader). Чтобы реализовать ваше решение для модели данных, я могу взломать неиспользуемое свойство SyndicationItem или использовать наследование SyndicationItem для пользовательского класса (я полагаю, это наиболее профессиональный способ?)
Моя полная модель данных выглядит следующим образом:
ObservableCollection >>> CollectionViewSource >>> ListBox.
В любом случае, я использовал простой код, который в то время был не таким простым:
Сначала XAML :
<Window.Resources>
<CollectionViewSource x:Key="fooCollectionViewSource" Source="{Binding fooObservableCollection}" >
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="PublishDate" Direction="Descending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<Style x:Key="DeselectedTemplate" TargetType="{x:Type ListBoxItem}">
<Setter Property="Foreground" Value="Gray" />
</Style>
</Window.Resources>
<ListBox x:Name="LB1" ItemsSource="{Binding Source={StaticResource fooCollectionViewSource}}" HorizontalContentAlignment="Stretch" Margin="0,0,0,121" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<TextBlock MouseDown="TextBlock_MouseDown" Grid.Column="0" Text="{Binding Path=Title.Text}" TextWrapping="Wrap" FontWeight="Bold" />
<TextBlock Grid.Column="1" HorizontalAlignment="Right" TextAlignment="Center" FontSize="11" FontWeight="SemiBold"
Text="{Binding Path=PublishDate.LocalDateTime, StringFormat='{}{0:d MMM, HH:mm}'}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Теперь код позади:
Решение 1: это применяет новый стиль, когда listboxitem не выбран. Больше не используется, поэтому событие LB1_SelectionChanged отсутствует в XAML.
private void LB1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.RemovedItems.Count != 0)
{
foreach (var lbItem in e.RemovedItems)
{
//get reference to source listbox item. This was a pain.
int intDeselectedItem = LB1.Items.IndexOf(lbItem);
ListBoxItem lbi = (ListBoxItem)LB1.ItemContainerGenerator.ContainerFromIndex(intDeselectedItem);
/*apply style. Initially, instead of applying a style, I used mylistboxitem.Foreground = Brushes.Gray to set the text color.
Howver I noticed that if I scrolled the ListBox to the bottom, the text color would revert to the XAML default style in my XAML.
I assume this is because of refreshes / redraws (whichever the correct term). Applying a new style resolved.*/
Style style = this.FindResource("DeselectedTemplate") as Style;
lbi.Style = style;
}
}
}
Решение 2. Решение, которое я использовал. Происходит при SelectedItem = true, тот же эффект, что и ваше первое предложение.
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
TextBlock tb = e.Source as TextBlock;
tb.Foreground = Brushes.Gray;
}