C# 使用ItemContainerGenerator时WPF中的ListBox返回null

C# 使用ItemContainerGenerator时WPF中的ListBox返回null,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我的XAML中有列表框、少数复选框和过滤器按钮。我的应用程序生成大量日志,并显示在列表框中。 当列表框中有数据时,此XAML将执行的操作是用户选中\n取消选中复选框。基于此,单击按钮时将过滤列表框中的数据。根据数据,我想在每个项目上显示不同的前景色和背景色 private void FilterButton_Click ( object sender , RoutedEventArgs e ) { //Whenever filter button is clicked, i will ch

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

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;
            }
    }
}
private void filter按钮单击(对象发送器,路由目标)
{
//每当单击筛选按钮时,我都会检查复选框状态。无论哪个//复选框处于启用状态,我都会将复选框名称添加到字典中。然后我将从列表框中读取字符串,并从中提取特定关键字,然后与字典键匹配。如果它//匹配,则我将修改该特定列表的背景色和前景色x项。我的问题是,只有某些列表框项得到更新,其余项//未缓存。调试时,我发现itemcontainergenerator为所有其他//项返回null。
对于(int i=0;i
我看到的问题是,如果我的列表框有1000个项目,那么只更新35-40个项目。其余所有项目均相同。我对代码进行了更多的调试,发现在35-40个数字之后,所有的项都变成了null,这就是为什么我不能更新列表框中的所有项。 我的代码中没有启用虚拟化。有什么方法可以更新所有的项目吗。感谢您的帮助。我在想,如果ItemCOntainerGenerator有任何问题,因为它只显示某些项目,虚拟化也会关闭。


请查看下面的图表,以便更清楚地了解:;你理解这个问题

你不应该那样做。相反,您的视图模型项类中可能有一个布尔属性,用于控制项是否实际被过滤(我们称之为
IsFiltered
)。然后,您将向列表框的
ItemContainerStyle
添加一个数据触发器,该触发器设置受
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
属性设置一个值。

@HighCore每当单击filter按钮时,我都会检查复选框状态。无论哪个复选框处于启用状态,我都会将复选框名称添加到字典中。然后我将从列表框中读取字符串,并从中提取特定的关键字,然后与字典键匹配。如果它//匹配,那么我将修改该特定列表框项目的背景色和前景色。我在这里的问题是,只有某些列表框项目得到更新,而其余的项目没有被归档。调试时,我发现itemcontainergenerator为所有其他项返回null。我的观点仍然成立。您需要在ViewModel级别处理所有数据,而不使用UI。发布一个你需要的截图,我可以告诉你在WPF中的正确方式。@HighCore请参阅下面我附上截图的帖子。我已经有了该系列的MVVM模型。但是我想根据内容过滤和修改模板。我在列表框中的数据是动态的。收到数据后,我想从每个列表框项目中找出一些关键字。基于这个关键字,我想应用背景色和前景色。对于listBox的每个项,此颜色可能不同。然后将其设置为enum属性而不是bool,并具有多个DataTriggers。我的视图模型集合的类型为string。另外,它来自另一个项目,所以我不能修改它。我所拥有的只是我收集的所有信息。每当我点击Filter按钮时,它都会检查我的xaml中复选框的状态。无论哪个复选框处于启用状态,它都将获得它的名称并在listboxitem内容中搜索它。我的listboxitem将包含122:343:33、ABC、a、a、d、f之类的内容。我的复选框名称将是ABC。所以,如果我在ListBoxitem中找到ABC,我想更改bckgrnd和foregrnd颜色。像ABC一样,我们需要在listboxitem中搜索15-20个stinrg。
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;
            }
    }
}