使用ItemContainerGenerator时WPF中的ListBox返回null

时间:2013-08-19 23:04:54

标签: c# .net wpf xaml

我的XAML中有列表框,很少有复选框和过滤按钮。我的应用程序生成大量日志,我在列表框中显示。 当我在列表框中有数据时,此XAML将执行的操作是用户将选中\取消选中复选框。基于此,单击按钮时将过滤列表框中的数据。根据数据,我想在每个项目上显示不同的前景色和背景色。

private void FilterButton_Click ( object sender , RoutedEventArgs e )
{
   //Whenever filter button is clicked, i will check for checkbox status. whichever //checkbox  is ON I will add checkbox name into Dictionary. Then I will read string from Listbox and extract particular keyword from that and match with Dictionary key. If it //matches then I will modify the background and foreground color for that particualr //listbox items. My problem here is only certain Listbox items get updated rest of them are //unchaged. When debugged i found that itemcontainergenerator returns null for all other //items. 
    for ( int i = 0 ; i < ListBox1.Items.Count ; i++ )
    {

    ListBoxItem item1 = ( ListBoxItem )ListBox1.ItemContainerGenerator.ContainerFromIndex(i);

        string recordType;
        string []  contentArray;

        if ( item1 == null )
            continue;
        if ( item1.Content == "" )
            continue;

        contentArray = item1.Content.ToString().Split( new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries );
        recordType = contentArray [ 1 ];

        if ( checkBoxType.ContainsKey ( recordType ))
            {
               //int code = RecordTypeToColorCode [ recordType ];
                //item1.Foreground = ColorCodeToForeColor [ code ];
                    item1.Foreground = Brushes.DarkCyan;
                    item1.FontSize = 13;
                    item1.Background = Brushes.LightGoldenrodYellow;

            }
        else
            {
                item1.Foreground = Brushes.LightGray;
            }
    }
}

我看到的问题是,如果假设我的列表框有1000个项目,则只更新35-40个项目。休息所有项目都是一样的。我调试了更多的代码,我发现在一些数字35-40后所有项目都是null,我为什么我无法更新列表框中的所有项目。 我没有在我的代码中打开虚拟化。有什么办法可以更新所有项目。任何帮助表示赞赏。我在想如果ItemCOntainerGenerator存在任何问题,因为它只显示某些项目,虚拟化也会关闭。我是WPF的新手,所以如果这是一个愚蠢的问题请跟我一起。

2 个答案:

答案 0 :(得分:0)

enter image description here

请查看以下图表以更清楚地了解问题

答案 1 :(得分:0)

你不应该这样做。相反,您可能在视图模型项类中有一个布尔属性,用于控制项是否实际被过滤(让我们称之为IsFiltered)。然后,您将向ListBox的ItemContainerStyle添加一个DataTrigger,它设置受IsFiltered属性值影响的所有属性。当然,您还必须为该属性实现INotifyPropertyChanged。

<ListBox ...>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Foreground" Value="LightGray"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsFiltered}" Value="True">
                    <Setter Property="Foreground" Value="DarkCyan"/>
                    <Setter Property="Background" Value="LightGoldenrodYellow"/>
                    <Setter Property="FontSize" Value="13"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
    ...
</ListBox>

现在,只要过滤条件发生变化,您将遍历items集合(而不是容器),并为每个项目的IsFiltered属性设置一个值。