C # Код отмены / повтора ничего не делает

#c# #winforms #stack #undo-redo

#c# #winforms #стек #отменить-повторить

Вопрос:

для моего редактора плиток у меня есть 2 стека TileMaps, undo и redo. Каждый раз, когда пользователь вносит изменение, состояние карты добавляется в стек, после чего производится изменение. Вот мой код отмены:

 private void undoToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (undo.Count != 0)
        {
            redo.Push(tileMap);
            tileMap = undo.Peek();
            undo.Pop();
        }
    }
  

Однако карта не меняется. Почему?

Комментарии:

1. Что такое tileMap ? Что именно вы ожидаете, что произойдет?

2. tileMap — это просто объект типа TileMap, который содержит все отрисовываемые слои. Я ожидаю, что это отменит последнее внесенное изменение.

3. невозможно отладить код, который мы не видим

Ответ №1:

Если отмена и повтор — это просто объекты стека, то ничего не должно произойти. Вместо этого вам нужно добавить код для фактического обновления пользовательского интерфейса при выполнении отмены. В этом случае, я полагаю, вы бы перерисовали карту, используя текущую tileMap, извлеченную из стека.

Комментарии:

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

2. Вы уверены, что пользовательский интерфейс действительно выполняет свою работу? Убедитесь, что он обновляется с соответствующей tileMap. Также убедитесь, что ваш код отмены вызывается правильно. Проверьте эти вещи с помощью инструкций print или отладчика, затем вернитесь.

3. Так что, если они, то у вас на самом деле нет проблемы. Если код отмены вызван, и tileMap действительно обновлена, и в конечном итоге вызывается код обновления пользовательского интерфейса, и он использует правильную tileMap, то единственное, что остается, это то, что ваш код обновления пользовательского интерфейса не работает. Возможно, все еще есть ссылки, указывающие на tileMap, которая была заменена, когда новая была извлечена из стека отмены?

Ответ №2:

Я знаю, что это старая тема, но я только что столкнулся с этой самой проблемой. Оказалось, что элемент, который я передавал в CurrentItem, был тем же элементом, который я редактировал в памяти, поэтому он просто передавал один и тот же объект назад и вперед.

Я обошел это, создав функцию Clone для объекта, чтобы возвращать новую версию самого себя, и я делал это каждый раз, когда выполнялись функции отмены, повтора или добавления в обоих направлениях. Таким образом, это всегда устраняло зависимость от редактируемого объекта. Теперь все работает 🙂

Ответ №3:

Если это не проблема с обновлением пользовательского интерфейса…

Ваши ссылки на повтор и отмену относятся к разным объектам стека? Если они оба ссылаются на один и тот же объект стека, то ваш код просто нажимал бы на текущее состояние.

Или аналогично, вы вводите другую ссылку на тот же объект tileMap или его копию? (т. Е. Вы, вероятно, хотите Push(tileMap.DeepCopy()) )

Кроме того, почему вы просматриваете, а затем открываете? Вы можете просто перейти непосредственно к tileMap.