C# 具有范围的ObservableCollection会导致UI出现问题
我有一个程序,显示项目列表,每个项目都有一些额外的细节,可以通过按钮显示和隐藏。源集合是一个名为ObservaleCollectionWithRange的自定义类,它只是ObservaleCollection的一个简单扩展,允许您批量添加对象(我相信我是从这里的某个地方得到的,但不记得了)。下面是它的代码:C# 具有范围的ObservableCollection会导致UI出现问题,c#,wpf,observablecollection,C#,Wpf,Observablecollection,我有一个程序,显示项目列表,每个项目都有一些额外的细节,可以通过按钮显示和隐藏。源集合是一个名为ObservaleCollectionWithRange的自定义类,它只是ObservaleCollection的一个简单扩展,允许您批量添加对象(我相信我是从这里的某个地方得到的,但不记得了)。下面是它的代码: public class ObservableCollectionWithRange<T> : ObservableCollection<T> { publi
public class ObservableCollectionWithRange<T> : ObservableCollection<T>
{
public void AddRange(IEnumerable<T> items)
{
this.CheckReentrancy();
foreach (var item in items)
this.Items.Add(item);
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public void RemoveRange(IEnumerable<T> items)
{
this.CheckReentrancy();
foreach (var item in items)
this.Items.Remove(item);
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
公共类ObservableCollectionWithRange:ObservableCollection
{
公共无效添加范围(IEnumerable items)
{
this.CheckReentrancy();
foreach(项目中的var项目)
此.Items.Add(item);
this.OnCollectionChanged(新建NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
公共无效删除范围(IEnumerable items)
{
this.CheckReentrancy();
foreach(项目中的var项目)
此。项。删除(项);
this.OnCollectionChanged(新建NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
我的程序也使用分页加载这些项目(加载前10个,如果用户向下滚动足够远,则加载下10个,以此类推)。现在是一个奇怪的错误。如果我做了一个初始搜索,它显示了第一组结果,我可以显示额外的细节,一切看起来都很好。但是,如果我折叠细节,然后滚动到底部,以便加载下一组,然后重新展开相同的项目,细节只是空白
下面是它第一次应该是什么样子,它确实是什么样子:
以下是展开、关闭然后加载下一组后的外观:
(我知道它们是不同的对象,它们来自不同的搜索,但它确实发生在同一个对象上)
最奇怪的是,我检查了代码,对象仍然在那里,细节中显示的对象列表仍然在那里,所有属性都是正确的。它也会为每个细节项创建一个ListViewItem,这就是为什么它是一个很高的空白而不是很薄的空白,只是它应该显示的数据是空白的
我确实为ListView和ListViewItem应用了一些自定义样式,但我尝试删除它们,结果是一样的(当然除了样式)
现在是踢球者。我切换到一次添加一个项目,而不是使用“AddRange”功能。。。而且工作正常。由于我不是一次添加很多项目,这对我来说可能是一个可行的解决方案,但它让我严重挠头,想知道到底是什么导致了这种行为,我想了解它
以下是显示详细信息的控件的相关代码:
<StackPanel Visibility="{Binding ShowParameters, Converter={StaticResource BoolToVis}}">
<TextBlock Text="Dimensions" Style="{StaticResource st_SearchTitles}" />
<ListView ItemsSource="{Binding DimensionParameters}" Style="{StaticResource st_ListViewNoScroll}"
ItemContainerStyle="{StaticResource st_ListViewNoSelection}">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource st_ColumnHeaderBlank}">
<GridViewColumn DisplayMemberBinding="{Binding Definition.Name}" />
<GridViewColumn DisplayMemberBinding="{Binding Value}" />
</GridView>
</ListView.View>
</ListView>
<TextBlock Text="Classifications" Style="{StaticResource st_SearchTitles}" />
<ListView ItemsSource="{Binding ClassificationParameters}" Style="{StaticResource st_ListViewNoScroll}"
ItemContainerStyle="{StaticResource st_ListViewNoSelection}">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource st_ColumnHeaderBlank}">
<GridViewColumn DisplayMemberBinding="{Binding Definition.Name}" />
<GridViewColumn DisplayMemberBinding="{Binding Value}" />
</GridView>
</ListView.View>
</ListView>
<TextBlock Text="Properties" Style="{StaticResource st_SearchTitles}" />
<ListView ItemsSource="{Binding PropertyParameters}" Style="{StaticResource st_ListViewNoScroll}"
ItemContainerStyle="{StaticResource st_ListViewNoSelection}">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource st_ColumnHeaderBlank}">
<GridViewColumn DisplayMemberBinding="{Binding Definition.Name}" />
<GridViewColumn DisplayMemberBinding="{Binding Value}" />
</GridView>
</ListView.View>
</ListView>
<TextBlock Text="Formulas" Style="{StaticResource st_SearchTitles}" />
<ListView ItemsSource="{Binding FormulaParameters}" Style="{StaticResource st_ListViewNoScroll}"
ItemContainerStyle="{StaticResource st_ListViewNoSelection}">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource st_ColumnHeaderBlank}">
<GridViewColumn DisplayMemberBinding="{Binding Definition.Name}" />
<GridViewColumn DisplayMemberBinding="{Binding Formula}" />
</GridView>
</ListView.View>
</ListView>
<TextBlock Text="Links" Style="{StaticResource st_SearchTitles}" />
<ListView ItemsSource="{Binding UrlParameters}" Style="{StaticResource st_ListViewNoScroll}"
ItemContainerStyle="{StaticResource st_ListViewNoSelection}">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource st_ColumnHeaderBlank}">
<GridViewColumn DisplayMemberBinding="{Binding Definition.Name}" />
<GridViewColumn DisplayMemberBinding="{Binding Value}" />
</GridView>
</ListView.View>
</ListView>
<Button Style="{StaticResource st_ToolButton}" Padding="0" HorizontalAlignment="Stretch" Name="btn_Collapse">
<Image Source="../Images/Glyph_Contract.png" Stretch="None">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding ShowParameters}" Value="False">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="45" />
</Setter.Value>
</Setter>
<Setter Property="Margin" Value="0,-5,0,0" />
</DataTrigger>
<DataTrigger Binding="{Binding ShowParameters}" Value="True">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-135" />
</Setter.Value>
</Setter>
<Setter Property="Margin" Value="0,0,0,-5" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
</StackPanel>
如您所见,详细信息只是一个堆栈面板,其中包含一些ListView和基于视图模型中的“ShowParameters”布尔参数的可见性。有一个按钮显示它,但它只是切换该属性。ListView的ItemsSource只是CollectionViewSource对象,具有基于公共集合的不同过滤器
有人知道这里发生了什么和/或如何使AddRange正常工作吗?很难说清楚,但很可能是因为您使用了
NotifyCollectionChangedAction.Reset
。这意味着集合已完全更改(只有在调用Clear时,默认可观察集合才会使用它)。因此,所有UI控件都应该完全重新绘制,这会导致您看到的内容。如果没有更多的代码(与如何显示这些细节相关),很难说出更多的内容。我为细节部分添加了XAML代码,并简要解释了相关要点。我知道重置使它重新绘制,这一定是不同的,但我不明白为什么。如果你重画了所有的对象,那为什么会创建某种类型的空白对象呢?特别是在副名单上?这是正在重置的主要对象集合,我对