Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
.NET 4.x

Организация многократной отмены действий для своей таблицы

03.12.2018, 18:27. Показов 1126. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Есть файл:
Code
1
2
3
4
5
6
7
palette_region:
 dc.w     0, $8CE, $6AC, $48A, $268, $46, $224, 2
 dc.w     0, $C, $A, 8, 6, 4, 2, 0  ; harkonnen
 dc.w     0, $E40, $C40, $A40, $840, $620, $420, $200
 dc.w     0, $C0, $A0, $80, $60, $40, $20, 0    ; ordos
 dc.w     0, $E0E, $C0C, $A0A, $808, $606, $404, $202
 dc.w     0, $EEE, $CCC, $AAA, $888, $666, $444, $222
Данные у меня хранятся в массиве:
C#
1
private string[,] Palette_regions { get; set; }
Ему задаются размер и туда помещаются данные при помощи парсинга файла.
В принципе чтобы сделать однократную кнопку назад тоесть отменить только последние действие то можно использовать дополнительную переменную скажем
C#
1
private string[,] prevPalette_regions { get; set; }
Но для многократьной отмены тоесть всех действий это не подходит. Как это организовать в моем случае:
Вроде у List<> тоже нет поддержки многократной отмены действий

Добавлено через 13 минут
Вообще хоть массив и двумерный но по факту многократное отмена нужна для 2 значения элементов например матрица в программе будет такой:
Code
1
2
3
4
5
6
0, $8CE, $6AC, $48A, $268, $46, $224, 2 - ID1
0, $C, $A, 8, 6, 4, 2, 0  - ID2
0, $E40, $C40, $A40, $840, $620, $420, $200  - ID3
0, $C0, $A0, $80, $60, $40, $20, 0  - ID4
0, $E0E, $C0C, $A0A, $808, $606, $404, $202  - ID5
0, $EEE, $CCC, $AAA, $888, $666, $444, $222  - ID6
Обращение:
C#
1
Palette_regions[ID, I]
А отображение на форме идет только списком I
ID выбирается через радиокнопки!
Так что и многократное отмена нужна только для I а не для все матрицы так как пользователь не может редактировать сразу всю матрицу он может менять только ID1 или ID2 или ID3... и так далее.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.12.2018, 18:27
Ответы с готовыми решениями:

Дописать код для кнопки отмены действий пользователя
Запоминать каждое действие, которое делает пользователь, если после действия не произошла отмена, записываем действие в оригинал....

как написать кнопку для очистки или отмены действий
Не могу написать правильно код для кнопки &quot; очистка&quot;. Мне нужно чтобы я вводила оценки, он мне подсчитывал средний бал, после чего я...

Кнопка отмены действий другой кнопки
как создать button1, который бы прекращал работу button2? private void button2_Click(object sender, EventArgs e) { ...

15
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18242 / 14156 / 5366
Регистрация: 17.03.2014
Сообщений: 28,846
Записей в блоге: 1
03.12.2018, 21:24
Alexandr_7, заведи Stack<T> с элементом где хранятся индексы массива и старое значение. Перед изменением значения заносим на стек старое значение. При отмене забираем из стека значение и меняем массив.

Цитата Сообщение от Alexandr_7 Посмотреть сообщение
В принципе чтобы сделать однократную кнопку назад тоесть отменить только последние действие то можно использовать дополнительную переменную скажем
C#
1
private string[,] prevPalette_regions { get; set; }
Но для многократьной отмены тоесть всех действий это не подходит. Как это организовать в моем случае:
Только одним объявлением не обойтись. Нужно еще клонировать массив перед записью в эту переменную. Иначе даже для однократной отмены это работать не будет.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
03.12.2018, 22:06  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Alexandr_7, заведи Stack<T> с элементом где хранятся индексы массива и старое значение. Перед изменением значения заносим на стек старое значение. При отмене забираем из стека значение и меняем массив.
Можно поподробнее.
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18242 / 14156 / 5366
Регистрация: 17.03.2014
Сообщений: 28,846
Записей в блоге: 1
03.12.2018, 22:23
Alexandr_7, пишем вспомогательный класс
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class ArrayWithUndo<T>
    where T : IEquatable<T>
{
    T[,] _array;
    Stack<UndoData<T>> _undo = new Stack<UndoData<T>>();
    
    public ArrayWithUndo(T[,] array)
    {
        _array = array;
    }
    
    public T this[int row, int col]
    {
        get { return _array[row,col]; }
       set
        {
            if (!_array[row, col].Equals(value))
            {
                _undo.Push(new UndoData<T> { Row = row, Col = col, Value = _array[row,col] });
                _array[row, col] = value;
            }
        }
    }
    
    public bool Undo()
    {
        if (_undo.Count == 0) return false;
        
        var data = _undo.Pop();
        _array[data.Row, data.Col] = data.Value;
        return true;
    }
    
    struct UndoData<T>
    {
        public T Value;
        public int Row, Col;
    }
}
Далее в коде вся работа с массивом должна идти через класс ArrayWithUndo
C#
1
2
3
4
5
6
7
8
string[,] array = {{"a", "b", "c"},{"d", "e", "f"}};
var arrayHelper = new ArrayWithUndo<string>(array);
arrayHelper[0,1] = "B";
arrayHelper[0,0] = "A";
arrayHelper[1,2] = "F";
 
arrayHelper.Undo();
arrayHelper.Undo();
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
03.12.2018, 23:51  [ТС]
Получается array нужен только для начального присваение значений?

Добавлено через 20 минут
Подождите а как undo отменяет действия? Последние действие что ли отменяет. Я же говорю что отмену нужно делать для каждого элемента своя отмена?
Я видать сглупил когда написал что отмену нужно делать для 1 вхождения.
Короче вот как изменяю я данные массива:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
private void tb_EditPalette_n_TextChanged(object sender, EventArgs e)
        {
            #region Парсинг строки
 
            char[] symbols = { '0', '2', '4', '6', '8', 'A', 'C', 'E' };
 
            TextBox tb = (TextBox)sender;
 
            var text = tb.Text.ToUpper();
 
            text = new string(text.Where(x => symbols.Contains(x)).ToArray());
 
            if ((text.Length >= 2 || text.IndexOf('A') >= 0 || text.IndexOf('C') >= 0 || text.IndexOf('E') >= 0) && text.IndexOf("$") < 0)
                text = text.Insert(0, "$");
 
            tb.Text = text;
 
            tb.SelectionStart = tb.Text.Length;
 
            #endregion
 
            #region Редактирование палитр
 
            if (tb.Text.Length <= 0) return;
 
            pb_EditPalette[(int)tb.Tag].BackColor = Additional_DHE.FromSEGAColor(tb.Text);
 
            if (PE.Settings.SelectPagePaletteEditor == 0)
            {
                Palette_regions[PE.Settings.SelectHousePalette, (int)tb.Tag] = tb.Text;
            }
            else if (PE.Settings.SelectPagePaletteEditor == 1)
            {
                Palette_ending[PE.Settings.SelectHousePalette, (int)tb.Tag] = tb.Text;
            }
            else if (PE.Settings.SelectPagePaletteEditor == 2)
            {
                Palette_gamepal_unit[PE.Settings.SelectHousePalette, (int)tb.Tag] = tb.Text;
            }
            else return;
 
            #endregion
 
            if (NoExamplePic == true) return;
 
            SetPaletteExample();
        }
Тоесть 1 вхождение это SelectHousePalette - выбраная радиокнопка
2 Вхождение это (int)tb.Tag - текстовое поле в котором я меняю значение.
То есть количество текстовых полей равно количестеву y в двухмерном массиве
Ну короче их 8 штук для файла что я привел в примере.
Когда создавал тему расчитывал на отмену для каждого отдельно. Хотя щас думаю а удобно ли это. Может общую использовать? В примере я так понял общая для всех. Но даже если и делать общую то у меня в 1 вхождении PE.Settings.SelectHousePalette
То есть общую надо делать только для (int)tb.Tag а 1 вхождение нужно указывать. Вызов отмены должна быть приблизительно такой:
C#
1
arrayHelper[PE.Settings.SelectHousePalette].Undo();
Ну или такой
C#
1
arrayHelper[].Undo(PE.Settings.SelectHousePalette);
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18242 / 14156 / 5366
Регистрация: 17.03.2014
Сообщений: 28,846
Записей в блоге: 1
03.12.2018, 23:55
Alexandr_7, идею я продменстрировал. Если не подходит, то перепиши как требуется.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
04.12.2018, 13:40  [ТС]
Ну как устроена работа слегка понял но чет не получается переделать под сохранение предыдущих действий только для 1 вхождения. Я даже не могу понять как в таком случае должно быть устроена сохранение и возвращение чтобы действовало только для y точнее чтобы указывать x для назад

Добавлено через 10 минут
Вроде стек не подойдет. Он подходит если делать общую отмену в моем же случае нужно восстанавливать объект указанный из ячеек но x тоесть общий общию историю но тольбко для y значений или проще говоря для 2го вхождения

Добавлено через 35 секунд
И кстати. Ошибка:
Code
1
Имя типа параметра "T" совпадает с именем типа параметра внешнего типа "ArrayWithUndo<T>".
Добавлено через 3 часа 27 минут
И так. Извиняюсь за создание пустой темы. Ибо допер только щас. Я же изменения дело через textBox
А У textBox есть метод undo который к слову должен работать многократно.
Ну так в принципе можно и через textBox и делать отмену.
Единственный вопрос при срабатывании undo будет срабатывать событие TextChanged
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
08.12.2018, 21:32  [ТС]
И так не хочу создовать новой темы. Вот код
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
        private void tb_EditPalette_n_TextChanged(object sender, EventArgs e)
        {
            TextBox tb = (TextBox)sender;
 
            if (tb.Text.Length <= 0) return;
 
            #region Парсинг строки
 
            char[] symbols = { '0', '2', '4', '6', '8', 'A', 'C', 'E' };
 
            var text = tb.Text.ToUpper();
 
            text = new string(text.Where(x => symbols.Contains(x)).ToArray());
 
            if ((text.Length >= 2 || text.IndexOf('A') >= 0 || text.IndexOf('C') >= 0 || text.IndexOf('E') >= 0) && text.IndexOf("$") < 0)
                text = text.Insert(0, "$");
 
            tb.Text = text;
 
            tb.SelectionStart = tb.Text.Length;
 
            btn_UndoPalette[(int)tb.Tag].Enabled = true;
 
            #endregion
 
            #region Редактирование палитр
 
            pb_EditPalette[(int)tb.Tag].BackColor = PE.Additional_DHE.FromSEGAColor(tb.Text);
 
            if (PE.Settings.SelectPagePaletteEditor == 0)
            {
                PE.Palette_regions[PE.Settings.SelectHousePalette, (int)tb.Tag] = tb.Text;
            }
            else if (PE.Settings.SelectPagePaletteEditor == 1)
            {
                PE.Palette_ending[PE.Settings.SelectHousePalette, (int)tb.Tag] = tb.Text;
            }
            else if (PE.Settings.SelectPagePaletteEditor == 2)
            {
                PE.Palette_gamepal_unit[PE.Settings.SelectHousePalette, (int)tb.Tag] = tb.Text;
            }
            else return;
 
            #endregion
 
            if (NoExamplePic == true) return;
 
            SetPaletteExample();
        }
private void btn_UndoPalette_n_Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
 
            TextBox tb = tb_EditPalette[(int)btn.Tag];
 
            tb.Undo();
        }
Но отмена не работает должным образом.
1. Она отменяет только последние действие
2. Иногда она вовсе не срабатывает.

Добавлено через 5 часов 6 минут
Может кто помочь как сделать возможность под textbox многократной отмены. Ну также как это в c# например при нажатие Ctrl Z
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18242 / 14156 / 5366
Регистрация: 17.03.2014
Сообщений: 28,846
Записей в блоге: 1
08.12.2018, 21:38
Alexandr_7, мне непонятно что и как тебе нужно отменять. Если ты объяснишь это на пальцах, то постараюсь помочь.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
08.12.2018, 22:06  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Alexandr_7, мне непонятно что и как тебе нужно отменять. Если ты объяснишь это на пальцах, то постараюсь помочь.
В textBox отменять изменения текста. Надо привязать стек к элементу TextBox
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18242 / 14156 / 5366
Регистрация: 17.03.2014
Сообщений: 28,846
Записей в блоге: 1
08.12.2018, 22:11
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Может кто помочь как сделать возможность под textbox многократной отмены. Ну также как это в c# например при нажатие Ctrl Z
Если вопрос только в этом, то возможно поможет статья Undo/Redo Framework

Добавлено через 55 секунд
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Надо привязать стек к элементу TextBox
Как они связаны между собой?
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
08.12.2018, 22:38  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Если вопрос только в этом, то возможно поможет статья Undo/Redo Framework
Там же под VB а его я не учил чтобы собразить как переделать под c#

Добавлено через 2 минуты
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Если вопрос только в этом, то возможно поможет статья Undo/Redo Framework
Да в принципе то что нужно но нужно ограничится только компонентом TextBox
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18242 / 14156 / 5366
Регистрация: 17.03.2014
Сообщений: 28,846
Записей в блоге: 1
08.12.2018, 23:00
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Там же под VB а его я не учил чтобы собразить как переделать под c#
Знание VB тут не обязательно. Можно откомпидировать проект на VB, а потом путем декомпиляции получить код на C#.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
08.12.2018, 23:01  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
Знание VB тут не обязательно. Можно откомпидировать проект на VB, а потом путем декомпиляции получить код на C#.
Ну тогда нужно знать асемблер да и там для всей формы код а мне только под TextBox именно чтобы отмену через сам TextBox делать
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18242 / 14156 / 5366
Регистрация: 17.03.2014
Сообщений: 28,846
Записей в блоге: 1
08.12.2018, 23:31
Alexandr_7, знания ассемлера тоже не требуются

Добавлено через 27 минут
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
C#
9
10
11
12
13
14
15
16
17
18
            char[] symbols = { '0', '2', '4', '6', '8', 'A', 'C', 'E' };
 
            var text = tb.Text.ToUpper();
 
            text = new string(text.Where(x => symbols.Contains(x)).ToArray());
 
            if ((text.Length >= 2 || text.IndexOf('A') >= 0 || text.IndexOf('C') >= 0 || text.IndexOf('E') >= 0) && text.IndexOf("$") < 0)
                text = text.Insert(0, "$");
 
            tb.Text = text;
Лучше настроить TextBox так чтобы можно было вводить только перечисленные символы. Например через событие KeyPress.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,891
08.12.2018, 23:39  [ТС]
Да отмена нужна чтобы можно было востановить удаленные данные! Например ввел он не тот цвет который нужно. И вот с помощью кнопки востановить тот что был.
То что нельзя вводить запрещенные символы это то чтобы не ввели символы которые не относятся к цветовой палитре.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.12.2018, 23:39
Помогаю со студенческими работами здесь

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

Организация в БД таблицы характеристик для товаров
Давно занимаюсь разработкой сайтов и интернет-магазинов. Наработал уже довольно своих кодов и библиотек. Сайты делаю на основе своей...

C# WPF Организация Пошаговых ДЕйствий
Здравствуйте Товарищи программисты! Может кто знает как организовать пошаговые выполнение чего либо через диалоговые окна В какую...

Организация своей VPN сети с обходом
Помогите создать схему обхода Squid... wifi сети (см.схему). Что можно использовать, и что почитать , чтобы поставить такую сеть?:) ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru