Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 19.12.2017
Сообщений: 4

Ошибка при повторном нажатии мышью по PictureBox! Игра Мемо

19.12.2017, 22:50. Показов 1774. Ответов 4

Студворк — интернет-сервис помощи студентам
Составляю программу-игру типа "Мемо" (открываются 2 картинки, если они не одинаковы, закрываются назад).
Проблема:
1 круг: нажали 1 картинку, потом 2-ю картинку, сравнили = false, они закрылись.
2 круг: нажимаем 2-ю картинку из 1го круга: выскакивает ошибка System.ArgumentException: "Parameter is not valid." (указывает на 17 строчку красного шрифта, см. картинку прикрепленную)
В чем может быть дело? Событие прикреплено к каждой картинке.
Я начинающий пользователь c#. Это моя первая программа.

Код процедуры

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
[LIST=1]
private PictureBox[] P1 = new PictureBox[20]; // Массив картинок-обложек
private PictureBox[] P2 = new PictureBox[20]; // Массив картинок перешанных
private int Check = 0; //Флаг счета нажатия мышкой на картинку
private int Pic1, Pic2 = 0; //Переменные для сохранения индексов выбранных мышкой картинок
 
[1]private void pictureBox1_Click(object sender, EventArgs e) //Событие щелчка мыши по картинке
[2]        {
[3]            PictureBox pictureB = sender as PictureBox; //Определение картинки, по которой произошел клик мыши и ее сохранение в переменную PictureB
[4]            //Если картинка, по которой щелкнули, имеет путь Application...
[5]            if (pictureB.ImageLocation == Convert.ToString(Application.StartupPath + "\\abstrakcia-1366x768-38.JPG"))
[6]            {
[7]                int i = 0; //Переменная-счетчик
[8]                Boolean pictV = false; //переменная-флаг: указатель, что картинка установлена
[9]                do
[10]                {
[11]                    if (P2[i].Name.Equals(pictureB.Name)) //Сравнение имен картинки массива P2 из ранее сохраненной и выбранной картинкой 
[12]                    {
[13]                        pictV = P1[i]; //установка флага, настройка картинки, загрузка кратинки-рисунка из ранее сохраненного массива картинок P1[].
[14]                        P2[i].Image.Dispose(); 
[15]                        P2[i].SizeMode = PictureBoxSizeMode.Zoom;
[16]                        P2[i].ImageLocation = P1[i].ImageLocation;
[17]                        P2[i].Image = P1[i].Image;
[18]                        TLP3.Update();
[19]                    }
[20]                    i++; //изменение счетчика
[21]                } while (i < (razm * 2) && pictV == false); //пока счетчик меньше количества картинок в игре ИИ флаг не изменен
 
[22]                Check++; //Изначально при запуске = 0; флаг для определения какая по счету картинка кликнута
[23]                if (Check == 1)
[24]                    Pic1 = i-1; //Индекс 1 выбранной картинки
[25]                if (Check == 2)
[26]                {
[27]                    Pic2 = i-1; //Индекс 2 выбранной картинки
[28]                    Thread.Sleep(1000);
[29]                    if (P2[Pic1].ImageLocation != P2[Pic2].ImageLocation) //Если пути 1 и 2 выбранных картинок НЕ равны
[30]                    {
                              //Настройка картинки, установка обложки вместо картинки-рисунка
[31]                        P2[Pic1].Image.Dispose();
[32]                        P2[Pic1].SizeMode = PictureBoxSizeMode.Normal;
[33]                        P2[Pic1].ImageLocation = Application.StartupPath + "\\abstrakcia-1366x768-38.JPG";
[34]                        P2[Pic1].Image = Image.FromFile(Application.StartupPath + "\\abstrakcia-1366x768-38.JPG");
[35]                                              
[36]                        P2[Pic2].Image.Dispose();
[37]                        P2[Pic2].SizeMode = PictureBoxSizeMode.Normal;
[38]                        P2[Pic2].ImageLocation = Application.StartupPath + "\\abstrakcia-1366x768-38.JPG";
[39]                        P2[Pic2].Image = Image.FromFile(Application.StartupPath + "\\abstrakcia-1366x768-38.JPG");
[40]                        TLP3.Update();
[41]                    }
[42]                    Check = 0; //флаг обнуляется
[43]                }
[44]            }
[45]        }[/LIST]
Миниатюры
Ошибка при повторном нажатии мышью по PictureBox! Игра Мемо  
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.12.2017, 22:50
Ответы с готовыми решениями:

При нажатии на Button1 в Edit1 или Label1 записывается цифра 50, при повторном нажатии к этой 50 прибавляется еще 50. Как сделать?
Помогите сделать следующее. При нажатии на Button1 в Edit1 или Label1 записывается цифра 50, при повторном нажатии к этой 50 прибавляется...

При нажатии на ссылке установить, а при повторном нажатии - снять галочку
Всем привет!:) имеется input checkbox и Ссылка &lt;a&gt;, как при нажатии на ссылку установить галочку и потом при повторном нажатии на ссылку...

Вылетает непонятная ошибка при первом нажатии мышью в любом месте дочерней формы. Я в отчаянии!
Сделал форму в которой можно добавлять накладную. Из-за очевидного удобства, решил сразу же в форму добавить подчинённую форму в которой...

4
0 / 0 / 0
Регистрация: 19.12.2017
Сообщений: 4
19.12.2017, 23:07  [ТС]
На картинке - то, что выдает ошибка,если нажать посмотреть сведения

Добавлено через 10 минут
C#
1
private PictureBox[] P1 = new PictureBox[20]; // Массив картинок-обложек
Заполняется при инициализации формы
C#
1
2
for (int i = 0; i < 20; i++)
                P1[i] = new PictureBox();
Затем в цикле отдельной процедуры присваиваются случайно выбранные картинки (В ListBox1 прописаны пути к картинкам):
C#
1
2
3
 P1[q].Image = Image.FromFile (Convert.ToString(listBox1.Items[n[0]]));
                    P1[q].ImageLocation = Convert.ToString(listBox1.Items[n[0]]);
private PictureBox[] P2 = new PictureBox[20]; // Массив картинок перешанных
Заполняется обращением к процедуре MassP2:
C#
1
2
3
4
5
6
7
8
9
10
11
    MassP2(pictureBox1, 0); MassP2(pictureBox2, 1);
                        MassP2(pictureBox3, 2); MassP2(pictureBox4, 3); MassP2(pictureBox5, 4);
                        MassP2(pictureBox6, 5);
 
           private void MassP2 (PictureBox P2s, int i)
             {
                 P2[i] = P2s;
                 P2[i].Image = Image.FromFile(Application.StartupPath + "\\abstrakcia-1366x768-38.JPG");
                 P2[i].ImageLocation = Application.StartupPath + "\\abstrakcia-1366x768-38.JPG";
                 i++;
              }
0
 Аватар для Aferuga
645 / 529 / 324
Регистрация: 20.05.2015
Сообщений: 1,471
20.12.2017, 09:43
Лучший ответ Сообщение было отмечено Tanya23Kir как решение

Решение

Проще самому написать:
Кликните здесь для просмотра всего текста
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
        private Image[] img = new Image[11]; // массив используемых картинок включая картинку-обложку(если она одна)
        private List<int> mass = new List<int>(); // массив индексов картинок
        private int last_id = -1;
        private List<int> pool = new List<int>(); //выбранные на данный момент картинки
 
        public MemoGame()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            if (listBox1.Items.Count >= 11)
            {
                for (int i = 0; i < img.Length; i++)
                {
                    img[i] = Image.FromFile(listBox1.Items[i].ToString());
                    if (i != 0)//первый элемент в listbox это обложка
                    {
                        mass.Add(i);
                        mass.Add(i);
                    }
                }
                mass = orderNew(mass);
                int Y = 10;
                int X = 10;
                for (int i = 0; i < 20; i++)
                {
                    PictureBox pb = new PictureBox();
                    pb.Size = new Size(30, 30);
                    pb.Location = new Point(X, Y);
                    pb.Click += pictureBox1_Click;
                    pb.Image = img[0];
                    pb.Name = String.Format("pictureBox1_{0}", i);
                    if ((i + 1) % 5 == 0)
                    {
                        X = 10;
                        Y += 40;
                    }
                    else
                    {
                        X += 40;
                    }
                    this.Controls.Add(pb);
                }
            }
            else
            {
                MessageBox.Show("Картинок должно быть больше десяти");
            }
        }
 
        public List<int> orderNew(List<int> li_old)
        {
            Random rand = new Random();
            List<int> li_new = new List<int>();
 
            for (int i = li_old.Count; i > 0; i--)
            {
                int ind = rand.Next(0, li_old.Count);
                li_new.Add(li_old[ind]);
                li_old.RemoveAt(ind);
            }
            return li_new;
        }
 
        private void pictureBox1_Click(object sender, EventArgs e)
        {
            int id = int.Parse((sender as PictureBox).Name.Substring(12));
            if ((mass[id]!=0)&&(!pool.Contains(id))){
            if (last_id == -1)
            {
                last_id = id;
                (sender as PictureBox).Image = img[mass[id]];
                pool.Add(last_id);
            }
            else
            {
                if (last_id != id)
                {
                    
                    (sender as PictureBox).Image = img[mass[id]];
                    if (mass[id] == mass[last_id])
                    {
                        mass[id] = 0;
                        mass[last_id] = 0;
                        pool.RemoveAll(p=>p==last_id);
                        last_id = -1;
                        if (mass.Sum() == 0) MessageBox.Show("Игра окончена");
                    }
                    else
                    {
                        pool.Add(id);
                        last_id = -1;
                        BackgroundWorker bw = new BackgroundWorker();
                        bw.DoWork += bw_DoWork;
                        bw.RunWorkerAsync();
                    }
                }
            }
            }
        }
 
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            int id1 = pool[pool.Count()-2];
            int id2 = pool[pool.Count() - 1];
            Thread.Sleep(1000);
            Action act = () =>
            {
                (this.Controls[String.Format("pictureBox1_{0}", id1)] as PictureBox).Image = img[0];
                (this.Controls[String.Format("pictureBox1_{0}", id2)] as PictureBox).Image = img[0];
            };
            this.Invoke(act);
            pool.RemoveAll(p=>p==id1);
            pool.RemoveAll(p => p == id2);
        }
1
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
20.12.2017, 10:44
Цитата Сообщение от Tanya23Kir Посмотреть сообщение
private PictureBox[] P1 = new PictureBox[20];
Цитата Сообщение от Tanya23Kir Посмотреть сообщение
Boolean pictV = false;
Цитата Сообщение от Tanya23Kir Посмотреть сообщение
pictV = P1[i];
У меня вопрос -- как оно вообще компилится?!

Вообще, если я правильно понял игру, то подход крайне непрактичен. Идея такая:
- каждая картинка-кнопка содержит в себе мета-информацию об изображении-источнике. Например в поле Tag
- есть переменная хранящая открытую (openButton) на данный момент картинку. Если она null, то считаем что открытой для проверки нет.
- по клику смотрим в openButton, если она null, то просто записываем текущую кликнутую и делаем еще "открытой". В противном случае сравниваем Tag по ссылкам. Совпали -- переводим обе в статус "открыты", нет -- обе закрываем. Не забываем скинуть openButton в null.
- дальше уже делаем подсчеты и прочее.

к слову:
- Держать отдельно массив картинок обложек не обязательно, можно просто менять Image на один общий.
- для того чтобы не кликать в дальнейшем уже по открытой картинке, просто делаем ее Enable = false;

ну и прикрепил пример (правда там куча сахара)
Вложения
Тип файла: zip Nyan.TestMemo.zip (306.5 Кб, 7 просмотров)
1
0 / 0 / 0
Регистрация: 19.12.2017
Сообщений: 4
20.12.2017, 17:42  [ТС]
Aferuga, Спасибо за ответ! Простите, что еще раз Вас беспокою. Подскажите, пожалуйста, можно ли в последнюю часть кода добавить что-то, чтобы больше 2-х картинок ОДНОВРЕМЕННО не открывалось, если они разные? Когда выполняется Thread.Sleep(1000); можно успеть открыть еще пару картинок, а этого происходить не должно.
Ваш вариант:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
                        BackgroundWorker bw = new BackgroundWorker();
                        bw.DoWork += bw_DoWork;
                        bw.RunWorkerAsync();
                    }
                }
            }
            }
        }
 
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            int id1 = pool[pool.Count()-2];
            int id2 = pool[pool.Count() - 1];
            Thread.Sleep(1000);
            Action act = () =>
            {
                (this.Controls[String.Format("pictureBox1_{0}", id1)] as PictureBox).Image = img[0];
                (this.Controls[String.Format("pictureBox1_{0}", id2)] as PictureBox).Image = img[0];
            };
            this.Invoke(act);
            pool.RemoveAll(p=>p==id1);
            pool.RemoveAll(p => p == id2);
        }

Мой вариант чуть исправлен под мои нужды.
Кликните здесь для просмотра всего текста
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
                            BackgroundWorker bw = new BackgroundWorker();
                            bw.DoWork += bw_DoWork;
                            bw.RunWorkerAsync();
                        }
                    }
                }
            }
        }
 
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
 
            int id1 = Vwbr[Vwbr.Count() - 2];
            int id2 = Vwbr[Vwbr.Count() - 1];
            Thread.Sleep(1000);
            Action act = () =>
              {
                  (TLP3.Controls[String.Format("pictureBox1_{0}", id1)] as PictureBox).SizeMode = PictureBoxSizeMode.Normal;
                  (TLP3.Controls[String.Format("pictureBox1_{0}", id1)] as PictureBox).Image = Picture[0];
                  (TLP3.Controls[String.Format("pictureBox1_{0}", id2)] as PictureBox).SizeMode = PictureBoxSizeMode.Normal;
                  (TLP3.Controls[String.Format("pictureBox1_{0}", id2)] as PictureBox).Image = Picture[0];
              };
            TLP3.Invoke(act);
            Vwbr.RemoveAll(p => p == id1);
            Vwbr.RemoveAll(p => p == id2);
        }


Добавлено через 2 часа 32 минуты
Aferuga, Разобралась самостоятельно! Огромное спасибо за помощь!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
20.12.2017, 17:42
Помогаю со студенческими работами здесь

Как сделать при нажатии на context menu script, выполняется код timer.Start(); и при повторном нажатии выполняет код?
как сделать при нажатии на context menu script , выполняется код timer.Start(); и при повторном нажатии выполняет код timer.Stop();

Memo в delphi / как сделать так чтобы при нажатии на кнопку memo появляется, при повторном нажатии исчезает
как сделать так чтобы при нажатии на кнопку текст с memo появляется, при повторном нажатии исчезает - как сделать так чтобы при нажатии...

При нажатии на кнопку должна отображатся другая картинка ,при повторном нажатии снова первая картинка
На html языке отобразить картинку и кнопку.При нажатии на кнопку должна отображатся другая картинка ,при повторном нажатии снова первая...

Рисование на PictureBox. При повторном рисовании предыдущее изображение стирается
Здравствуйте, никак не могу разобраться в чем дело. Необходимо вывести &quot;звездное небо&quot;, раскидав на черном фоне разноцветные точки...

При первом нажатии кнопки - выполнялся один код,при повторном другой и тд
Имеется код : document.onkeydown = function(z) { if (z.keyCode==&quot;120&quot;) { var h = document.getElementsByTagName('a'); ...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru