Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Winforms列表框显示项目两次_C#_Winforms_Listbox - Fatal编程技术网

C# Winforms列表框显示项目两次

C# Winforms列表框显示项目两次,c#,winforms,listbox,C#,Winforms,Listbox,我在Winforms应用程序中遇到了一个列表框的问题,它以意外的顺序添加了两次条目 到目前为止的故障排除步骤 listStepHistory未在代码中的任何其他位置引用(当然,Designer.cs文件除外)。它没有绑定到数据源 我已双重检查了Job.Progress.StepHistory属性,它两次未包含相同的消息。每一段代码都只提到一次,这是应该的 起初,我认为这是一个多个更新同时发生的问题。但是,我已经将Task.Delay(TimeSpan.frommissions(500))的值

我在Winforms应用程序中遇到了一个
列表框的问题,它以意外的顺序添加了两次条目

到目前为止的故障排除步骤

  • listStepHistory
    未在代码中的任何其他位置引用(当然,Designer.cs文件除外)。它没有绑定到数据源
  • 我已双重检查了
    Job.Progress.StepHistory
    属性,它两次未包含相同的消息。每一段代码都只提到一次,这是应该的
  • 起初,我认为这是一个多个更新同时发生的问题。但是,我已经将
    Task.Delay(TimeSpan.frommissions(500))
    的值减少或增加到极值(1,10100100010000),并且从未见过两个以上的条目,也从未见过两个以下的条目。这似乎排除了并发UI更新是问题的原因
值得注意

如果您回顾屏幕截图,您将看到Winforms选择了代码最高的行(数字),这在导入作业的整个过程中是一致的,最高的数字始终是所选择的。这是有道理的,因为我在处理代码之前对代码进行了排序,所以它们应该按数字顺序进行处理。
如果查看所选项目之后的项目,您将看到这是一个较小的代码。这一行(11004)实际上与列表框顶部的第一行相同。类似地,所选行(73109)与列表框的底部相同

换句话说,复制如下所示(并且粗体选中):

A B C DEA B C D E

这很奇怪,因为我已经指示列表框选择最后一项。请注意我的
UpdateJobInformation()
方法中的最后一步:

if (listStepHistory.Items.Count > 0)
{
    //Select the last item (so that it scrolls to the bottom)
    listStepHistory.SelectedIndex = listStepHistory.Items.Count - 1;
}
即使我两次错误地添加了项目,我也希望列表框仍然选择它的最后一个项目(不管它是否重复),但事实并非如此

在我看来,重复条目是一个“幻影条目”。它们被渲染到屏幕上,但它们不存在于
listStepHistory.Items
属性中

我由此得出结论,列表框呈现的内容与其
属性
中包含的内容不同

有人能解释这种行为吗


附录

根据要求,
作业
作业进度
接口/类定义:

public interface IProgressTrackable
{
    ImportProgress Progress { get; }

    void Start();
    bool Cancel();
}

public class ImportProgress
{
    //redacted for brevity

    public List<string> StepHistory { get; set; } = new List<string>();
}
公共接口IProgressTrackable
{
ImportProgress进度{get;}
void Start();
bool Cancel();
}
公共类导入程序
{
//为简洁而编辑
公共列表历史记录{get;set;}=new List();
}

只需添加数组,而不是使用new ListBox.ObjectCollection

listStepHistory.Items.AddRange(Job.Progress.StepHistory.ToArray());

不使用新的ListBox.ObjectCollection,只需添加数组即可

listStepHistory.Items.AddRange(Job.Progress.StepHistory.ToArray());

在我看来,您正在循环中多次调用
StartProgressTracking()
。这个环是干什么用的?是不是每半秒投票一次?我会尝试通过将500毫秒更改为10000秒来排除重入,只是为了看一看。@EdPlunkett:
StartProgressTracking()
不是从循环内部调用的。此外,尽管问题中的示例中省略了“开始”按钮,但在单击后,“开始”按钮实际上会自动禁用,不能启动两次,也可以通过断点确认)我在第三个故障排除步骤中特别提到了修改延迟时间。重复条目(总是完全是双条目)似乎排除了并发问题(我希望在极短的延迟内有超过2个条目,并且问题会以足够大的延迟自行修复,但两者都不是),这就是“错误”的原因项目被选中是指您两次添加相同的实际对象实例列表。当您告诉它选择一个给定对象时,它会在
Items
中找到与该对象相等的第一个对象并选择它。最后一个对象在其中有两次,但第一次出现是它选择的。对不起,我的意思是从循环中调用
updatejobiformation()
。@EdPlunkett:注意,我设置了
SelectedIndex
,而不是
SelectedItem
SelectedIndex
不检查项目是否相等。另外,我第二次在哪里添加列表?在我看来,您在循环中多次调用
StartProgressTracking()
。这个环是干什么用的?是不是每半秒投票一次?我会尝试通过将500毫秒更改为10000秒来排除重入,只是为了看一看。@EdPlunkett:
StartProgressTracking()
不是从循环内部调用的。此外,尽管问题中的示例中省略了“开始”按钮,但在单击后,“开始”按钮实际上会自动禁用,不能启动两次,也可以通过断点确认)我在第三个故障排除步骤中特别提到了修改延迟时间。重复条目(总是完全是双条目)似乎排除了并发问题(我希望在极短的延迟内有超过2个条目,并且问题会以足够大的延迟自行修复,但两者都不是),这就是“错误”的原因项目被选中是指您两次添加相同的实际对象实例列表。当您告诉它选择一个给定对象时,它会在
Items
中找到与该对象相等的第一个对象并选择它。最后一个对象在其中有两次,但第一次出现是它选择的。对不起,我的意思是从循环中调用
updatejobiformation()
。@EdPlunkett:注意,我设置了
SelectedIndex
,而不是
SelectedItem
SelectedIndex
不检查项目是否相等。还有,我第二次在哪里添加列表?很好的发现!我