Question

I have a System Windows Forms ListView in C# (VS 2008) with AutoArrange=false and LargeIconView. I let the user change the position of an item in my ListView and save all position changes in a txt file. Then I load it back from txt file and I verified that my information is allright but anyway if I try to set the position back to my ListViewItems it won't change anything. If I directly address just one item with hard-coded values it seems to work. I have no idea what's going on. How can I set the saved positions back to my ListViewItems?

I moved the loading part from Form_Load to Form_Shown event just for a case to ensure the ListView would be surely loaded while I try to assign the positions, but it did not helped on this matter. The listViewItem positions won't change to the saved ones, but they have like a default align. I have checked that I have autoarrange set to false and I found nothing more what I could do here. Maybe you know? Maybe another setting plays a role?

If I do just this to the one item it changes without a problem, but the loaded values don't apply.

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

Here I load my values in the .Tag of my ListViewItem and get the POINT-Data. The POINT-Data is valid and is really there, I verified it. But it doesn't work somehow. The items stay arranged in the default alignment and the position doesn't change.

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);
        }
    }

Update after further testing: Since I add about 25000 items to my ListView I use the AddRange Method. The AddRange Method seems to drop my Position previously set to all ListViewItems in the List of ListViewItems. With AddRange this items are being added in less than 1-2 minutes, with the .Add-Method Position is preserved, but I can't use just .Add. It looks like a bug of Microsoft in place here. What can I do instead? The .Add-Method is out of question, adding the items would take here 1 hour and 47 minutes instead of 1-2 minutes.

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
Was it helpful?

Solution 2

The one answer which I received on that topic doesn't meet my problem / has nothing to do with my problem, so I can't choose it. I found the solution myself. Microsoft doesn't serialize the position property of a ListViewItem and it doesn't take the property into account when the .AddRange method got executed on a ListViewItem-List. It can be considered as a bug / limitation with fault at Microsoft (my personal opinion). I totally recoded the structure and made some overrides to the ListView to fix that stuff. Since the "fix code" is about several pages and not compatible to the code in my question it won't fit in here, but I tell what to do with the problem. For serializing I wrote an own type ListViewItem2 (this type I marked to be serializable) which stores all the properties which I want have to be saved included the position. Then I override the OnItemAdded event in such way that the position of an item will be kept when it has been added by the AddRange method. I hope this helps to those who encounter similar difficulties. The autoarrange-property of the ListView must be also off to set the positions.

OTHER TIPS

Well, what you're doing there is you're taking each item and getting the X/Y value from it (when it's already been put into the list) and assigning that same X/Y value back to it, resulting in no net change.

You need to load the point data from your file and then assign that to the items in the view. For example:

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

Where GetYourXForIndex(int) is a function you defined which returns the proper X value for a given index. Same for GetYourYForIndex(int).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top