Удаление дубликатов в списке <T>на основе выбора из DataGridView - PullRequest
2 голосов
/ 17 января 2012

(Обязательное предупреждение для новичка! Я не могу обещать, что пойму все, что вы мне скажете.)

У меня есть программа, которая использует List<T> пользовательского класса CheckOrderLine для заполнения *От 1005 * до BindingSource.Из элемента управления dataGrid я предоставляю возможность «разбивать» записи на несколько строк для наложения.У меня возникают проблемы при разработке обратного процесса.

Мне нужно иметь возможность сделать выбор в dataGrid, получить первую выбранную строку, с которой нужно начинать, а затем перебрать все CheckOrderLine ввыделения и сравните их с первой строкой.

Если все они совпадают, мне нужно изменить количество в первой записи, чтобы оно равнялось сумме всех выбранных строк, а затем удалить лишние строки.

Вот фрагмент того, что я до сих пор работал самостоятельно:

        int index = 1;
        while (index < rowToJoin)
        {
            _bs.RaiseListChangedEvents = false;

            int first = _bs.Position;
            int second = first++;
            CheckOrderLine current = (CheckOrderLine)_bs[first];
            CheckOrderLine next = (CheckOrderLine)_bs[second];

            if (current.OrderNumber == next.OrderNumber)
            {
                _bs.RemoveAt(second);
            }
            else
            {
                MessageBox.Show("You must select at least two matching rows to join.");
                return;
            }

            _bs.RaiseListChangedEvents = true;
            _bs.ResetBindings(false);
            index++;
        }

Это работает, только если я выбираю снизу вверх и только на основе OrderNumber.Чтобы предотвратить несчастные случаи, мне действительно нужно проверить все поля между двумя строками.Возможность выбора в любом направлении была бы бонусом на этом этапе.

РЕДАКТИРОВАТЬ: я думаю, что я не был достаточно ясен изначально.

  1. У меня есть метод, который может разделитьстрока в 2-5 новых строк.
  2. Мой исходный код может объединять любое количество строк, но только если выбран снизу вверх и основан на OrderNumber.
  3. Есть ли более эффективныйспособ сравнить две строки, кроме current.OrderNumber == next.OrderNumber?Я знаю, что могу добавить все свои поля в оператор if, но я бы предпочел, чтобы его можно было многократно использовать.
  4. Выбор в любом направлении - это отдаленная секунда сравнения всех полей.

1 Ответ

1 голос
/ 18 января 2012

Причина, по которой это работает только при выборе снизу вверх, состоит в том, что BindingSource.Current указывает на последний выбранный элемент, поэтому, если вы выбираете сверху вниз, вы сравниваете с невыбранными элементами.

Кажется, у вас также есть ошибка, из-за которой ваши first и second меняются местами.Вы используете операцию увеличения постфикса, когда, вероятно, не хотели этого делать.

Допустим, _bs.Position равно 5;

int first = _bs.Position;  // first is now 5
int second = first++;  // postfix increment: second is now 5, first is now 6

Как сказано в документации ,

результатом операции является значение операнда до его увеличения

Итак, вы действительно сделали это:

second = first;
first = first + 1;

Похоже, вы просто хотели сделать это:

second = first + 1;

В этом случае, вероятно, не было никакой разницы, но это делает для довольно запутанного кода.


Существует множество подходов к тому, что вы пытаетесь сделать.Вот, пожалуй, более прямой и понятный способ:

int count = dgv.SelectedRows.Count;

// DataGridView.SelectedRows is reverse order, so the first selected item is the last item in the list
var firstSelected = dgv.SelectedRows[count - 1].DataBoundItem as CheckOrderLine;
int firstOrderNumber = firstSelected.OrderNumber;

// starting at second-last item (second selected row)
for (int i = count - 2; i >= 0; i--)
{
    var row = dgv.SelectedRows[i];
    var item = row.DataBoundItem as CheckOrderLine;
    if (item.OrderNumber == firstOrderNumber)
        dgv.Rows.Remove(row);
}

Для простоты я упустил обновление оставшейся строки и проверку ошибок.

Обратите внимание, что это будет работать дажеесли совпадающие строки не являются последовательными.Вам решать, разрешить это или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...