Опубликован: 11.09.2006 | Доступ: свободный | Студентов: 7646 / 472 | Оценка: 4.26 / 3.45 | Длительность: 30:46:00
ISBN: 978-5-9556-0080-2
Лекция 2:

Работа с элементами управления

Сохранение файла при закрытии формы

Всякий раз, когда мы закрываем документ Microsoft Word, в который внесли изменения, появляется окно предупреждения, предлагающее сохранить документ. Добавим аналогичную функцию в наше приложение. В классе blank : System.Windows.Forms.Form формы blank создаем переменную, которая будет фиксировать сохранение документа:

public bool IsSaved = false;

В обработчик методов Save и Save As формы frmmain добавляем изменение значения этой переменной:

private void mnuSave_Click(object sender, System.EventArgs e)
    {
…
frm.IsSaved = true;
    } 

  private void mnuSaveAs_Click(object sender, System.EventArgs e)
    {
…
frm.IsSaved = true;
    }

Переходим в режим дизайна формы blank и в окне свойств переключаемся на события формы, щелкнув на значок с молнией. В поле события Closing дважды щелкаем и переходим в код:

private void blank_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  {
  //Если переменная IsSaved имеет значение true, т. е.  новый документ 
//был сохранен (Save As) или в открытом документе были сохранены изменения (Save), то //выполняется условие
 if(IsSaved ==true)
  //Появляется диалоговое окно, предлагающее сохранить документ.
  if(MessageBox.Show("Do you want save changes in " + this.DocName + "?", 
      "Message", MessageBoxButtons.YesNo, 
      MessageBoxIcon.Question) == DialogResult.Yes)
      //Если была нажата  кнопка Yes, вызываем метод Save
    {
      this.Save(this.DocName); 
    }    
     
    
  }
2.7.

Запускаем приложение. При закрытии формы blank или frmmain появляется окно предупреждения (рис. 2.17):

Окно предупреждения при закрытии формы

Рис. 2.17. Окно предупреждения при закрытии формы

OpenFileDialog и SaveFileDialog для SDI-приложений

При создании MDI-приложений приходится разделять код для открытия и сохранения файлов, как мы делали для приложения Notepad C#. В случае SDI-приложений весь код будет находиться в одном обработчике. Cоздаем новое приложение, называем его TextEditor. На форме размещаем элемент управления TextBox и устанавливаем следующие свойства:

TextBox, свойство Значение
Name txtBox
Dock Fill
Multiline true
Text Да

Добавляем на форму элемент MainMenu, в котором будет всего три пункта — File, Open и Save (свойства этих пунктов см. в таблице 2.1). Из окна ToolBox перетаскиваем элементы OpenFileDialog и SaveFileDialog — свойства этих элементов в точности такие же, как и у диалогов приложения Notepad C#. Переходим в код формы. Подключаем пространство имен для работы с файловыми потоками:

using System.IO;

Добавляем обработчик для пункта меню Open:

private void mnuOpen_Click(object sender, System.EventArgs e)
  {
    //Показываем диалог выбора файла
    openFileDialog1.ShowDialog();
    // Переменной fileName присваиваем имя открываемого файла
    string fileName = openFileDialog1.FileName;
    //Создаем поток fs и открываем файл для чтения.
    FileStream filestream= File.Open(fileName, FileMode.Open, FileAccess.Read);
    //Проверяем,  открыт ли поток,  и если открыт, выполняем условие
    if(filestream != null)
    {
      //Создаем объект streamreader и связываем его с потоком filestream
      StreamReader streamreader = new StreamReader(filestream);
      //Считываем весь файл и записываем его в TextBox
      txtBox.Text = streamreader.ReadToEnd();
      //Закрываем поток.
      filestream.Close();
    }
  }
2.8.

Добавляем обработчик для пункта меню Save:

private void mnuSave_Click(object sender, System.EventArgs e)
  {
    //Показываем диалог выбора файла
    saveFileDialog1.ShowDialog();
    // В качестве имени сохраняемого файла устанавливаем переменную fileName
    string fileName=saveFileDialog1.FileName;
    //Создаем поток fs и открываем файл для записи.
    FileStream filestream = File.Open(fileName, FileMode.Create, FileAccess.Write);
      //Проверяем,  открыт ли поток,  и если открыт, выполняем условие
    if(filestream != null)
    {
      //Создаем объект streamwriter и связываем его с потоком filestream
      StreamWriter streamwriter = new StreamWriter(filestream);
      //Записываем данные из TextBox в файл
      streamwriter.Write(txtBox.Text);
      //Переносим данные из потока в файл
      streamwriter.Flush();
      //Закрываем поток
      filestream.Close();
    }
  }
2.9.

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

На диске, прилагаемом к книге, вы найдете приложение TextEditor (Code\Glava2\TextEditor).

FontDialog

Продолжим работу над приложением Notepad C#. Добавим теперь возможность выбирать шрифт, его размер и начертание. В режиме дизайна перетащим на форму frmmain из окна ToolBox элемент управления FontDialog. Не изменяя ничего в свойствах этого элемента, переходим в обработчик пункта Font главного меню:

private void mnuFont_Click(object sender, System.EventArgs e)
  {
    //Переключаем фокус на данную форму.
    blank  frm = (blank)this.ActiveMdiChild;
    //Указываем, что родительской формой является форма frmmain  
    frm.MdiParent = this;
    //Вызываем диалог
    fontDialog1.ShowColor = true;
    //Связываем свойства SelectionFont и SelectionColor элемента RichTextBox 
    //с соответствующими свойствами диалога
    fontDialog1.Font = frm.richTextBox1.SelectionFont;
    fontDialog1.Color = frm.richTextBox1.SelectionColor; 
    //Если выбран диалог открытия файла, выполняем условие
    if (fontDialog1.ShowDialog() == DialogResult.OK)
    {
      frm.richTextBox1.SelectionFont = fontDialog1.Font;
      frm.richTextBox1.SelectionColor = fontDialog1.Color; 
    }
    //Показываем форму
    frm.Show();
  }
2.10.

Запускаем приложение, и в окне Output появляется список ошибок (рис. 2.18).

Список ошибок — NotepadCSharp.blank.richTextBox1 недоступен из-за своего уровня защиты

Рис. 2.18. Список ошибок — NotepadCSharp.blank.richTextBox1 недоступен из-за своего уровня защиты

В чем же дело? При расположении на форме blank элемента управления RichTextBox среда Visual Studio.NET сгенерировала экземпляр richTextBox1 класса System.Windows.Forms.RichTextBox с модификатором доступа private, из-за чего при обращении к нему и возникает исключение:

private System.Windows.Forms.RichTextBox richTextBox1;

Изменим модификатор на public и снова запустим приложение. При выборе пункта меню Font теперь можно менять параметры текущего текста.

ColorDialog

Диалоговое окно FontDialog содержит список цветов, которые могут быть применены к тексту, но предлагаемый список ограничен. Более интересной представляется возможность назначать пользовательский цвет, который может быть определен в большом диапазоне (рис. 2.19):

Диалоговое окно ColorDialog

Рис. 2.19. Диалоговое окно ColorDialog

Из окна ToolBox добавляем элемент управления ColorDialog и, вновь не изменяя его свойств, переходим к обработчику пункта Color главного меню формы frmmain:

private void mnuColor_Click(object sender, System.EventArgs e)
    {
      blank frm = (blank)this.ActiveMdiChild;
      frm.MdiParent = this;
      colorDialog1.Color = frm.richTextBox1.SelectionColor; 
      
      if (colorDialog1.ShowDialog() == DialogResult.OK)
      {
        frm.richTextBox1.SelectionColor = colorDialog1.Color; 
      }

      frm.Show();
    }

Обратите внимание на то, что код для ColorDialog в точности такой же, как и часть кода для свойства Color диалога FontDialog. Это и не удивительно: ведь мы связываем эти диалоги со свойствами одного и того же объекта — RichTextBox.

Елена Дьяконова
Елена Дьяконова

При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: 

Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll

Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан.

Затем:

Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll

Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз.

Александр Сороколет
Александр Сороколет

Свойство WindowState формы blank Maximized. Не открывается почемуто на всё окно, а вот если последующую форму бланк открыть уже на макс открывается :-/