Уроки моддинга
Основной раздел
Search
K
Links

000151. Запуск другой формы из основной, ListBox, MenuStrip

Запуск другой формы из основной, ListBox, MenuStrip||wmysterio|wmysterio|[email protected]|/||Всем осветительный привет! Мы продолжаем изучать формы Windows и сегодня мы будем учится запускать новую форму из окна основной, а также рассмотрим такие элементы, как ListBox и MenuStrip. Начнём с того, что будем создавать обычное меню, которое можно наблюдать в стандартных окнах. Для этого найдите компонент MenuStrip и переместите его в макет программы:
По-умолчанию меню выводится сверху, как видно на рисунке выше. Это визуальный редактор меню. В поле "Вводить здесь" нам предлагают ввести имя ячейки каждого пункта нашей навигации. При нажатии на элемент в нас выскакивают дополнительные места для будущих команд:
Соответственно всё, что будет написано справа будет горизонтальной навигацией, а что внизу - подпункты выделенной категории. Для начала создадим 3 пункта меню: "Файл", "Команды" и "Справка". В меню файл создадим 2 пункта: "Сохранить HTML" и "Выход":
В меню "Команды" добавим только 1 пункт - "История", а в Справку закинем "Об авторе" и "О программе". Наше меню готово, осталось только написать логику этих пунктов. Но прежде всего предлагаю сместить объект кнопка, браузер и ТекстБокс на небольшое расстояние от панели меню. Если это сделать, то получится эффект, когда меню частично закрывает кнопку и поле ввода, что намекает на криворукость программиста
smile
Думаю при компиляции без изменений сразу будет видим этот эффект. Ваша задача - подкорректировать элементы макета под более удобный вид. В этом уроке мы рассмотрим выполнение 2-х функций - "Выход" и "История". Знаю, что выйти с программы можно и нажав красный крестик, но я предлагаю сделать это программно, вдруг кому-то пригодится
smile
Мы должны сделать обработчик события "Клик" по пункту меню. Два раза нажимаем ЛКМ по нужной ячейке меню, чтобы компилятор автоматически создал подписку и обработчик события:
и в обработчике пишем всего одну команду:
Кодprivate void выходToolStripMenuItem_Click( object sender, EventArgs e ) { Application.Exit(); }С историей посещённый сайтов немного сложнее. Здесь есть куда разный вариантов. Я предлагаю немного усовершенствовать библиотеку, которую мы создали в предыдущем уроке. Заходим в проект BrowserLib и нажимаем комбинацию CTRL+SHIFT+A, и добавляем новую форму, назвав её, например, History:
Теперь мы можем визуализировать нашу новую форму. Предлагаю эту форму сделать фиксированной, размером 400х350, режим авто-размера: GrowAndShrink. Добавим туда новый компонент - ListBox и разместим его на форме. Добавим ещё 2 кнопки: "удалить запись", "очистить". Если пользователь нажмёт 2 раза ЛКМ по элементу списка, то браузер перейдёт по сохранённой ссылке. Кроме этого создадим лейбл, который будет иметь имя "Нет". Этот компонент будет отображать дату записи, которую мы указали в момент добавления записи лога. В итоге мы должны получить такое окно:
ListBox сам-по-себе не очень сложный в освоении, и очень поход на обычные списки, только в визуальном оформлении. Прежде всего нужно заполнить список информацией. По-задумке, в форму будет передан некий массив строк с которых будет формироваться список. Перейдём в режим редактирования(клавиша F7). В конструктор впишем аргумент - string[] LINKS. Чтобы мы могли выводить дату, мы должны хранить её где-нить, по-этому предлагаю добавить private поле со списком: Кодprivate List<string> DATE = new List<string>();Так, как одна из функций данного окна является переход по ссылке, мы должны вернуть эту ссылку в виде строки. Пишем: Кодpublic string retLink = "";Дальше уже идёт процесс заполнения. После процедуры InitializeComponent() добавим следующий код: Кодpublic History( string[] LINKS ) { InitializeComponent(); if ( LINKS == null ) { button1.Enabled = false; button2.Enabled = false; return; } foreach ( string Temp in LINKS ) { string[] s = Temp.Split( '|' ); DATE.Add(s[0]); listBox1.Items.Add(s[1]); } }Рассмотрим первый блок. По логике, если нам передали пустой или несуществующий массив, то значит никаких ссылок в логе у нас нет. По этому все действия будут бесполезны, по этому зададим активность наших кнопок в режим "спячки" и сражу же выходим с конструктора с помощи return. Если массив всё-таки существует и имеет записи, то условие не выполняется и идёт второй блок. Мы в цикле обходим все строки в массиве. Каждую строчку мы разделяем сепаратором Split( '|' ). Суть этого метода в том, что он берёт каждую подстроку и записывает в массив, каждая строка является новым элементом. То есть если у нас есть строка "111|222|333|444|555", то на выходе мы получим массив с элементами: КодArrey [0]111 [1]222 [2]333 [3]444 [4]555Символ '|' является сепаратором и в массив не входит. Так как наша строка имеет всего один символ сепаратора, то на выходе мы получим массив с 2-х элементов: даты и ссылки. Нулевой элемент мы запишем в список DATE, а первый в ListBox. Процесс заполнения окончен.Дальше уже идёт реализация. Создадим обработчик события для кнопки "Удалить запись". Прежде всего нам необходимо узнать текущий выбранный элемент: КодlistBox1.SelectedIndexА потом его удалить командой: КодlistBox1.Items.RemoveAt( INDEX );Так, как мы должны удалить и в списке дат элемент, то более оптимально будет вынести индекс в переменную, чтобы не делать лишних запросов: Кодint Index = listBox1.SelectedIndex; listBox1.Items.RemoveAt( Index ); DATE.RemoveAt( Index ); listBox1.SelectedIndex = 0;Однако есть исключение - нельзя отнимать несуществующие элементы, по этому мы должны поставить условия, что если к-во элементов списка больше нуля, то удалять, иначе отключим кнопки: Кодprivate void button2_Click( object sender, EventArgs e ) { if ( listBox1.Items.Count > 0 ) { int Index = listBox1.SelectedIndex; listBox1.Items.RemoveAt( Index ); DATE.RemoveAt(Index); if ( 1 > listBox1.Items.Count ) { button1.Enabled = false; button2.Enabled = false; } } else { button1.Enabled = false; button2.Enabled = false; } }Процесс очистки всех элементов ещё проще. Можно конечно было бы делать циклы и тому подобное, но Майкрософт уже сделали это за нас, создав отличный метод очистки: Кодprivate void button1_Click( object sender, EventArgs e ) { listBox1.Items.Clear(); DATE.Clear(); button1.Enabled = false; button2.Enabled = false; }Итак, мы научили список удалятся 2-мя способами: по одному и всё вместе. Он умеет получать данные из вне. Теперь разберёмся с датами. Здесь проще простого. Выбираем наш список в макете программы и ищем событие SelectedIndexChanged, жмём 2 раза на поле и получаем обработчик события:
Этот блок рекомендую брать в блок try, так как индекс после удаления очищается. Кодprivate void listBox1_SelectedIndexChanged( object sender, EventArgs e ) { try { label1.Text = DATE[ listBox1.SelectedIndex ].ToString(); } catch { label1.Text = "НЕТ"; } }Итак, у нас теперь теперь осталась одна задача - переход на ссылке по двойному клику в списке. Здесь тоже нет ничего сложного - наша форма этого делать не будет, это осуществит dll-библиотека, а мы должны только передадим нужное значение. Опять переходим в события ЛистБокса и выбираем событие "DoubleClick". В обработчике пишем следующий текст: Кодprivate void listBox1_DoubleClick( object sender, EventArgs e ) { retLink = listBox1.Items[ listBox1.SelectedIndex ].ToString(); Close(); }Суть в том, что мы передаём через публичную переменную ссылку а затем просто закрываем форму, используя процедуру Close(). Казалось весь функционал формы уже сделан, но есть один интересный факт: удаляли мы только со списка, но не с файла. Нам нужно осуществить перезапись файла. Это делается не очень сложно. Для начала зайдём в события самой формы и выбираем "FormClosing". Это событие возникает перед самим закрытием формы, а не после, дающий возможности воспользоваться данными формы: Кодprivate void History_FormClosing( object sender, FormClosingEventArgs e ) { string text = ""; int j = DATE.Count; if ( j > 0 ) { for ( int i = 0; i < j; i++ ) { text += DATE[ i ].ToString() + "|" + listBox1.Items[ i ].ToString() + "\r\n"; } } File.WriteAllText( "log.txt", text ); }Если к-во элементов списка больше нуля, то идёт цикл, который прибавляет строку с нужным форматом к переменной text. Дальше идёт переход к записи файла. Если есть записи, то запишутся все. Если нет, то файл будет только пустым. На этом мы завершаем проектировать форму и переходим к dll-ке. Добавим новый статический метод: Кодpublic static string DysplayHistory() { // Здесь будет код }Чтобы открыть новую форму, нам понадобится подключить библиотеку: Кодusing System.Windows.Forms;Дальше нужно объявить переменную - нашу форму. Делается это так: КодНАЗВАНИЕ_ФОРМЫ переменная = new НАЗВАНИЕ_ФОРМЫ(атрибуты);Так как форму я завал History, то конструктор будет следующим: КодHistory frm = new History( GetMessages() );В качестве параметра я передаю массив строк, который получаю ранее записанным методом GetMessages. Дальше нам нужно вызвать форму на экран. Есть 2 способа: 1) Вызов модального окна - форма будет поверх всех окон, а остальные будут недоступны(напоминает MessageBox). 2) Обычный вызов окна - будет создано окно, но мы может осуществлять и другие действия в проекте, вне создаваемой формы. Я предпочитаю модальный способ: Кодfrm.ShowDialog();Для обычного: Кодfrm.Show();Итак, окно открылось, пользователь сделал какие-то действия и закрыл его. Наша процедура возвращает строку, но какую? Так как в окне истории мы предполагали, что пользователь может нажать дабл-клик по списку, то будет переход на тот сайт. Так вот эту стоку метод будет возвращать. Весь метод будет выглядеть так: Кодpublic static string DysplayHistory() { History frm = new History( GetMessages() ); frm.ShowDialog(); return frm.retLink; }Мы крутые! Форма и библиотека полностью функциональна! Теперь нам остался последний штрих! вызвать эту процедуру с главного окна программы. Для этого дважды кликнем на шаблон ячейки меню "История" и добавим следующий код: Кодprivate void историяToolStripMenuItem_Click( object sender, EventArgs e ) { string a = BrowserLog.DysplayHistory(); }Делаем тест:
Наша задача выполнена. наш браузер научился хранить историю! :) Теперь сделаем одну махинацию, чтобы легче и экономнее было использовать наш браузер, а именно создать процедуру, которая будет принимать 1 строковый параметр а сама выполнять переход в браузер: Кодpublic void FollowLink( string URL ) { try { webBrowser1.Url = new Uri( URL ); BrowserLog.AddMessage( URL ); label1.Text = ""; } catch { label1.Text = "Неверное имя ссылки!"; } }И использовать эту функцию в обработчике кнопки: Кодprivate void button1_Click( object sender, EventArgs e ) { FollowLink( textBox1.Text ); }Теперь мы можем воспользоваться этой процедурой и в обработчике кнопки меню "История": Кодprivate void историяToolStripMenuItem_Click( object sender, EventArgs e ) { string a = BrowserLog.DysplayHistory(); if ( a.Length > 0 ) { FollowLink( a ); } }Таким образом мы осуществили такое действие: пользователь дважды нажал на ссылку в списке и осуществился переход на эту ссылку. Ну и чтобы Вас окончательно утомить, давайте осуществим просьбу одного пользователя - чтобы префикс "http://" автоматически приклеивался, а то постоянно вводить адрес как-то непривычно и не функционально. Реализовать такое просто.Достаточно написать условие: Кодif ( str.ToLower().IndexOf( "http://" ) == -1 ) { str = "http://" + str; }а метод FollowLink будет иметь вид: Кодpublic void FollowLink( string URL ) { try { if ( URL.ToLower().IndexOf( "http://" ) == -1 ) { URL = "http://" + URL; } webBrowser1.Url = new Uri( URL ); BrowserLog.AddMessage( URL ); label1.Text = ""; } catch { label1.Text = "Неверное имя ссылки!"; } }Суть условия проста. Ищем в строке подстроку "http://". Если такая не нашлась(результат вернул -1), то просто дописываем эту приставку к строке. Чтобы поиск был корректным, нужно перевести строку в нижний регистр, чем мы воспользовались: ToLower(). Итак, из этого урока вы извлекли: - Вызов формы из другой формы; - Применили основные команды ListBox и также List; - Научились передавать данные между формой и библиотекой(этот вариант катит и при обмене с другими формами, классами и.т.п.); - Узнали некоторые методы работы со строками Split, ToLower, IndexOf; - Узнали о понятии меню и как писать команды при нажатия кнопки; На этом, окончательно, урок окончен. Спасибо за внимание ;) |3469|1|0|81769077png581160400110\|74422300png23596|96864589png18093\|53095560png320168|75561017png587189400128\|29877193png416367400352|10715290png561356400253\|42902911png600450400300||zapusk_drugoj_formy_iz_osnovnoj_listbox_menustrip|1399455340