gpt4 book ai didi

wpf - DataGrid 通过滚动抛出 InvalidOperationException

转载 作者:行者123 更新时间:2023-12-04 14:07:05 25 4
gpt4 key购买 nike

我想在 DataGrid 中显示文件的内容。 (该文件包含超过 200,000 行)

用数据显示网格很快。

但是当我使用滚动条(向下滚动)时,我遇到了以下异常:

System.InvalidOperationException:
{"An ItemsControl is inconsistent with its items source.\n See the inner exception for more information."}

内部异常:
Information for developers (use Text Visualizer to read this):
This exception was thrown because the generator for control 'System.Windows.Controls.DataGrid Items.Count:0' with name '(unnamed)' has received sequence of CollectionChanged events that do not agree with the current state of the Items collection. The following differences were detected:
Accumulated count 0 is different from actual count 200000. [Accumulated count is (Count at last Reset + #Adds - #Removes since last Reset).]

One or more of the following sources may have raised the wrong events:
System.Windows.Controls.ItemContainerGenerator
System.Windows.Controls.ItemCollection
System.Windows.Data.ListCollectionView
System.Collections.Generic.List`1[[WpfApplication3.Entry, WpfApplication3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
(The starred sources are considered more likely to be the cause of the problem.)

The most common causes are (a) changing the collection or its Count without raising a corresponding event, and (b) raising an event with an incorrect index or item parameter.

The exception's stack trace describes how the inconsistencies were detected, not how they occurred. To get a more timely exception, set the attached property 'PresentationTraceSources.TraceLevel' on the generator to value 'High' and rerun the scenario. One way to do this is to run a command similar to the following:
System.Diagnostics.PresentationTraceSources.SetTraceLevel(myItemsControl.ItemContainerGenerator, System.Diagnostics.PresentationTraceLevel.High)
from the Immediate window. This causes the detection logic to run after every CollectionChanged event, so it will slow down the application.

异常告诉它:“已收到与 Items 集合的当前状态不一致的 CollectionChanged 事件序列。”

那是代码:

MainWindow.xaml
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication3="clr-namespace:WpfApplication3"
Title="MainWindow" Height="350" Width="525">
<Grid Name="Test">
<WpfApplication3:Viewer x:Name="LogUC" />
</Grid>
</Window>

MainWindow.xaml.cs
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
Test.DataContext = this;

LogUC.Loaded += LogUcOnLoaded;
}

private void LogUcOnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
LogUC.Test();
}
}

查看器.xaml
<UserControl x:Class="WpfApplication3.Viewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid Name="Container">
<DataGrid ItemsSource="{Binding Path=EntryCollection, Mode=OneTime}"
AutoGenerateColumns="False"
CanUserResizeColumns="True"
CanUserResizeRows="True"
CanUserAddRows="False"
CanUserDeleteRows="False"
IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ErrorCode}" Header="" />
<DataGridTextColumn Binding="{Binding Time}" Header="Time" />
<DataGridTextColumn Binding="{Binding Content}" Header="Content" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>

查看器.xaml.cs
public partial class Viewer : INotifyPropertyChanged
{
public Viewer()
{
EntryCollection = new List<Entry>();
InitializeComponent();
Container.DataContext = this;
}

public List<Entry> EntryCollection { get; set; }

internal void Test()
{
List<Entry> test = new List<Entry>();

for (int i = 0; i < 200000; i++)
{
Entry entry = new Entry(){
ErrorCode = 0,
Time = DateTime.Now.ToString(),
Content = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
};
test.Add(entry);
}

EntryCollection.AddRange(test);
OnPropertyChanged("EntryCollection");
}

#region Implementation of INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

#endregion Implementation of INotifyPropertyChanged
}

入口.cs
public class Entry
{
public int ErrorCode { get; set; }

public string Time { get; set; }

public string Content { get; set; }
}

有什么问题?

最佳答案

我不确定为什么会发生这种情况,但我可以告诉你如何让它工作。

通过引发适当的事件,您似乎永远不会告诉 DataGrid EntryCollection 中的项目已更改。
OnPropertyChanged("EntryCollection")调用您的 Test方法无效,因为您有 Mode=OneTime在 DataGrid 绑定(bind)上,并且由于 EntryCollection对象是 List而不是 ObservableCollection ,向其中添加项目不会引发任何事件来通知 DataGrid。

在我看来,你可以做两件事来解决这个问题。

  • 制作 EntryCollection一个 ObservableCollection因此在添加/删除项目时会通知 DataGrid。然后您可以删除 OnPropertyChanged打电话,还有Mode=OneTime .
    public Viewer()
    {
    EntryCollection = new ObservableCollection<Entry>();
    InitializeComponent();
    Container.DataContext = this;
    }

    public ObservableCollection<Entry> EntryCollection { get; set; }

    internal void Test()
    {
    for (int i = 0; i < 200000; i++)
    {
    Entry entry = new Entry()
    {
    ErrorCode = 0,
    Time = DateTime.Now.ToString(),
    Content = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
    };

    EntryCollection.Add(entry);
    }
    }
  • 而不是将项目添加到 EntryCollection ,将其设置为新实例并引发 PropertyChanged事件。这样做,您需要删除 Mode=OneTime XAML 中的设置。
    public Viewer()
    {
    EntryCollection = new List<Entry>();
    InitializeComponent();
    Container.DataContext = this;
    }

    public List<Entry> EntryCollection { get; set; }

    internal void Test()
    {
    List<Entry> test = new List<Entry>();

    for (int i = 0; i < 200000; i++)
    {
    Entry entry = new Entry()
    {
    ErrorCode = 0,
    Time = DateTime.Now.ToString(),
    Content = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
    };
    test.Add(entry);
    }

    EntryCollection = test;
    OnPropertyChanged("EntryCollection");
    }
  • 关于wpf - DataGrid 通过滚动抛出 InvalidOperationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13374957/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com