Установить положение ListViewItem в C# из текстового файла в LargeIconView (обновление 1)
У меня есть системный Windows Forms ListView в C# (VS 2008) с AutoArrange=false и LargeIconView. Я позволяю пользователю изменять положение элемента в моем ListView и сохраняю все изменения положения в текстовом файле. Затем я загружаю его обратно из txt-файла и проверяю, что с моей информацией все в порядке, но в любом случае, если я попытаюсь установить позицию обратно в ListViewItems, это ничего не изменит. Если я обращаюсь непосредственно к одному пункту с жестко закодированными значениями, это, кажется, работает. Я понятия не имею, что происходит. Как я могу установить сохраненные позиции обратно в ListViewItems?
Я переместил загрузочную часть из Form_Load в событие Form_Shown только для случая, чтобы убедиться, что ListView будет обязательно загружен, пока я пытаюсь назначить позиции, но это не помогло в этом вопросе. Позиции listViewItem не изменятся на сохраненные, но имеют выравнивание по умолчанию. Я проверил, что для autoarrange установлено значение false, и больше ничего не нашел, что я мог сделать здесь. Может ты знаешь? Может быть, другой параметр играет роль?
Если я делаю это только для одного элемента, он меняется без проблем, но загруженные значения не применяются.
listView1.Items[0].Position = new Point(300, 400);
Здесь я загружаю свои значения в.Tag моего ListViewItem и получаю 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);
}
}
Обновление после дальнейшего тестирования: так как я добавляю около 25000 элементов в свой ListView, я использую метод AddRange. Метод AddRange, кажется, отбрасывает мою Позицию, ранее установленную для всех ListViewItems в Списке ListViewItems. С AddRange эти элементы добавляются менее чем за 1-2 минуты, при этом позиция.Add-Method сохраняется, но я не могу использовать просто .Add. Похоже, ошибка Microsoft на месте здесь. Что я могу сделать вместо этого?.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
2 ответа
Один ответ, который я получил по этой теме, не соответствует моей проблеме / не имеет ничего общего с моей проблемой, поэтому я не могу выбрать его. Я нашел решение сам. Microsoft не сериализует свойство position объекта ListViewItem и не учитывает это свойство, когда метод.AddRange выполняется в ListViewItem-List. Это можно рассматривать как ошибку / ограничение по вине Microsoft (мое личное мнение). Я полностью перекодировал структуру и сделал некоторые изменения в ListView, чтобы исправить это. Так как "код исправления" состоит из нескольких страниц и не совместим с кодом в моем вопросе, он здесь не подходит, но я расскажу, что делать с проблемой. Для сериализации я написал собственный тип ListViewItem2 (этот тип я пометил как сериализуемый), в котором хранятся все свойства, которые я хочу сохранить, включая позицию. Затем я переопределяю событие OnItemAdded таким образом, чтобы позиция элемента сохранялась, когда он был добавлен методом AddRange. Надеюсь, это поможет тем, кто сталкивается с подобными трудностями. Свойство autoarrange объекта ListView также должно быть отключено для установки позиций.
Что вы делаете, вы берете каждый элемент и получаете из него значение 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)
,