WPF ListBoxItem (s) теряет программно установленные стили после прокрутки - PullRequest
1 голос
/ 26 мая 2009

Итак, у меня есть ListBox, который привязан к списку бизнес-объектов, используя DataTemplate:

<DataTemplate x:Key="msgListTemplate">
    <Grid Height="17">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="{Binding MaxWidth}" />
            <ColumnDefinition Width="*" />
         </Grid.ColumnDefinitions>
         <TextBlock Grid.Column="0" Foreground="Silver" Text="{Binding SequenceNo}" />
         <TextBlock Grid.Column="1" Text="{Binding MessageName}" />
    </Grid>
</DataTemplate>


<ListBox Name="msgList" 
    Grid.Column="0"
    ItemTemplate="{StaticResource msgListTemplate}"
    SelectionChanged="msgList_SelectionChanged"
    VirtualizingStackPanel.IsVirtualizing="True"
    ScrollViewer.HorizontalScrollBarVisibility="Hidden">
</ListBox>

Через некоторое время после привязки я хочу раскрасить определенные элементы в списке, чтобы отличать их от других. Я делаю это в фоновом потоке:

if(someCondition)
{
    msgList.Dispatcher.BeginInvoke(new Fader(FadeListItem), DispatcherPriority.Render, request);
}

delegate void Fader(GMIRequest request);
void FadeListItem(GMIRequest request)
{
    ListBoxItem item =
           msgList.ItemContainerGenerator.ContainerFromItem(request) as ListBoxItem;

    if(item!=null)
            item.Foreground = new SolidColorBrush(Colors.Silver);
}

Все это работает нормально, а некоторые элементы списка отображаются серым, как и ожидалось. Однако, если я прокручиваю так, что серые элементы больше не отображаются, затем снова возвращаюсь к тому месту, где они были, они больше не серебристые и возвращаются на черный передний план по умолчанию.

Есть идеи, почему это так, или как это исправить? Это потому, что я установил IsVirtualizing в значение true? Список обычно содержит много элементов (20 000 - не редкость).

1 Ответ

3 голосов
/ 26 мая 2009

Это потому, что я установил IsVirtualizing в значение true? Список обычно содержит много элементов (20 000 - не редкость).

Вы прибили это - элемент, на который вы установили цвет переднего плана, становится уничтоженным, когда пользователь прокручивает прочь.

Несмотря на то, что у вас есть правильное общее представление, способ сделать это - очень не-WPFy способ сделать это - лучший способ сделать это - иметь bool DP в вашем классе бизнес-объектов ( или сделайте так, чтобы BO реализовал INotifyPropertyChanged), затем привяжите bool к цвету переднего плана с помощью пользовательского возвращаемого IValueConverter (isTrue? whiteBrush: greyBrush).

Поскольку вы, возможно, не захотите / не сможете изменить свой бизнес-объект для поддержки INotifyPropChanged, это является причиной для шаблона MV-VM - создайте класс, который обертывает объект, который является DependencyObject, и предоставляет только свойства Вы заинтересованы в отображении.

...