0

我在 C# (VS 2008) 中有一个 System Windows Forms ListView 和AutoArrange=falseLargeIconView。我让用户在我的 ListView 中更改项目的位置,并将所有位置更改保存在 txt 文件中。然后我从 txt 文件中加载它并验证我的信息是好的,但无论如何如果我尝试将位置设置回我的 ListViewItems 它不会改变任何东西。如果我只使用硬编码值直接处理一项,它似乎可以工作。我不知道是怎么回事。如何将保存的位置设置回我的 ListViewItems?

我将加载部分从Form_Load 移动到 Form_Shown 事件只是为了确保在我尝试分配位置时肯定会加载 ListView,但这对此事没有帮助。listViewItem 位置不会更改为已保存的位置,但它们具有默认对齐方式。我检查了我是否已将 autoarrange 设置为 false,但我没有发现更多我可以在这里做的事情。也许你知道?也许另一个设置起作用?

如果我只对一个项目执行此操作,它会毫无问题地更改,但加载的值不适用。

listView1.Items[0].Position = new Point(300, 400);

在这里,我将值加载到 ListViewItem 的 .Tag 中并获取 POINT-Data。POINT-Data 是有效的并且确实存在,我验证了它。但它以某种方式不起作用。项目保持默认对齐方式排列,位置不变。

private void Form1_Shown(object sender, EventArgs e)
    {
        foreach (ListViewItem LVI in listView1.Items)
        {
            Point PNT1 = (Point)LVI.Tag;
            int x = PNT1.X;
            int y = PNT1.Y;
            LVI.Position = new Point(x, y);
        }
    }

进一步测试后更新: 由于我向我的 ListView 添加了大约 25000 个项目,因此我使用AddRange Method。AddRange方法似乎将我之前设置的 Position 设置为 ListViewItems列表中的所有 ListViewItems。使用 AddRange 可以在不到 1-2 分钟的时间内添加这些项目,并保留 .Add-Method 位置,但我不能只使用.Add。它看起来像微软的一个错误。我能做些什么呢?.Add-Method 是没有问题的,在这里添加项目需要 1 小时 47 分钟而不是 1-2 分钟。

List<ListViewItem> L1 = new List<ListViewItem>();
//...Load data from file - the data is valid loaded (checked / debugged)
 ListViewItem LV1 = new ListViewItem();
            LV1.Tag = P1;
            LV1.Text = Text1;
            LV1.ImageKey = Name1;
            LV1.ToolTipText = ToolTip1;
            LV1.ForeColor = ForeColor1;
            LV1.BackColor = BackColor1;
            LV1.Position = Position1; //here comes the problem, that seems to be lost
            L1.Add(LV1);
            //listView1.Items.Add(LV1); //this would work but it is to slow - AddRange required
        }
        listView1.Items.AddRange(L1.ToArray()); //here the position seems to get lost
4

2 回答 2

0

好吧,你正在做的是你正在获取每个项目并从中获取 X/Y 值(当它已经被放入列表时)并将相同的 X/Y 值分配回它,导致没有净值改变。

您需要从文件中加载点数据,然后将其分配给视图中的项目。例如:

for(int I = 0; I < listView1.Items.Count(); I++)
{
    listView1.Items[I].Position = new Point(GetYourXForIndex(I),GetYourYForIndex(I));
}

GetYourXForIndex(int)您定义的函数在哪里返回给定索引的正确 X 值。对GetYourYForIndex(int).

于 2013-10-16T19:02:47.197 回答
0

我收到的关于该主题的一个答案不符合我的问题/与我的问题无关,所以我不能选择它。我自己找到了解决方案。Microsoft 不会序列化 ListViewItem 的位置属性,并且在 ListViewItem-List 上执行 .AddRange 方法时不会考虑该属性。它可以被认为是微软的错误/限制(我个人的看法)。我完全重新编码了结构并对 ListView 进行了一些覆盖以修复这些内容。由于“修复代码”大约有几页,并且与我的问题中的代码不兼容,所以它不适合这里,但我告诉了如何处理这个问题。为了进行序列化,我编写了一个自己的类型 ListViewItem2(我标记为可序列化的类型),它存储了我想要保存的所有属性,包括位置。然后,我重写 OnItemAdded 事件,以便在通过 AddRange 方法添加项目时保留项目的位置。我希望这对遇到类似困难的人有所帮助。ListView 的 autoarrange-property 也必须关闭才能设置位置。

于 2013-12-08T02:55:59.513 回答