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

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

Контекстное меню

Контекстное меню, дублирующее некоторые действия основного меню, — не самый быстрый способ работы с программой, но самый привычный для пользователя. Элемент управления TextBox содержит в себе простейшее контекстное меню, дублирующее действия подменю Edit. Для того чтобы убедиться в этом, достаточно нанести этот элемент управления на форму и запустить приложение (рис. 2.8):

Контекстное  меню элемента TextBox

Рис. 2.8. Контекстное меню элемента TextBox

В нашем приложении Notepad C# в качестве текстового элемента мы используем RichTextBox. Добавим элемент управления contextMenu из окна ToolBox на форму blank. Добавляем пункты контекстного меню точно так же, как мы это делали для главного меню (рис. 2.9):

Пункты контекстного меню

Рис. 2.9. Пункты контекстного меню

Свойство Text и Shortcut пунктов меню оставляем прежними. Если мы установим затем для свойства ShowShortcut значение false, то сочетания клавиш будут работать, но в самом меню отображаться не будут — как на рис. рис. 2.8. Свойство Name будет формироваться следующим образом: для пункта Cut — cmnuCut, для Сopy — cmnuCopy и т.д.

В обработчике пунктов просто вызываем соответствующие методы:

private void cmnuCut_Click(object sender, System.EventArgs e)
  {
    Cut();
  }

  private void cmnuCopy_Click(object sender, System.EventArgs e)
  {
    Copy();
  }

  private void cmnuPaste_Click(object sender, System.EventArgs e)
  {
    Paste();
  }

  private void cmnuDelete_Click(object sender, System.EventArgs e)
  {
  Delete();
  }

  private void cmnuSelectAll_Click(object sender, System.EventArgs e)
  {
  SelectAll();
}
Листинг 2.3.

Последнее, что нам осталось сделать, — это определить, где будет появляться контекстное меню. Элемент RichTextBox, так же как и формы frmmain и blank, имеет свойство ContextMenu, где мы и указываем contextMenu1, поскольку нам нужно отображать меню именно в текстовом поле. Запускаем приложение — теперь в любой точке текста доступно меню (рис. 2.10).

Контекстное меню

Рис. 2.10. Контекстное меню

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

Среда Visual Studio .NET содержит готовые диалоговые окна, предлагающие выбрать файл для открывания или путь на диске для сохранений текущего файла (рис. 2.11).

Диалоговое окно открытия файла

Рис. 2.11. Диалоговое окно открытия файла

Мы рассмотрим одну часть диалоговых окон в этой лекции, а другую, относящуюся к подготовке документа к печати, — в "Работа с печатью и изображениями" .

OpenFileDialog

Добавьте на форму frmmain элемент управления OpenFileDialog из окна панели инструментов ToolBox. Подобно элементу MainMenu, он будет располагаться на панели невидимых компонент (рис. 2.12):

Добавление OpenFileDialog на форму

увеличить изображение
Рис. 2.12. Добавление OpenFileDialog на форму

Свойство FileName задает название файла, которое будет находиться в поле "Имя файла:" при появлении диалога. На рис. рис. 2.12 название в этом поле — "Текстовые файлы", поскольку на рис. рис. 2.11 был введен именно этот текст. Свойство Filter задает ограничение файлов, которые могут быть выбраны для открытия — в окне будут показываться только файлы с заданным расширением. Через вертикальную разделительную линию можно задать смену типа расширения, отображаемого в выпадающем списке "Тип файлов". Здесь введено Text Files (*.txt)|*.txt|All Files(*.*)|*.* что означает обзор либо текстовых файлов, либо всех. Свойство InitialDirectory позволяет задать директорию, откуда будет начинаться обзор. Если это свойство не установлено, исходной директорией будет рабочий стол.

Для работы с файловыми потоками в коде формы blank подключаем пространство имен System.IO:

using System.IO;

В методе Open считываем содержимое файла в RichTextBox:

//Создаем метод Open, в качестве параметра объявляем строку адреса  файла.
  public void Open(string OpenFileName)
  {
    //Если файл не выбран, возвращаемся назад (появится встроенное предупреждение)
    if (OpenFileName == "") 
    {
      return;
    }
    else
    {
//Создаем новый объект StreamReader и передаем ему переменную //OpenFileName
      StreamReader sr = new StreamReader(OpenFileName);
      //Читаем весь файл и записываем его в richTextBox1
      richTextBox1.Text = sr.ReadToEnd();
      // Закрываем поток
      sr.Close();
      //Переменной DocName присваиваем адресную строку
      DocName = OpenFileName;
    }
  }
2.4.

Добавим обработчик пункта меню Open формы frmmain:

private void mnuOpen_Click(object sender, System.EventArgs e)
  {
    //Можно программно задавать доступные для обзора расширения файлов 
    //openFileDialog1.Filter = "Text Files (*.txt)|*.txt|All Files(*.*)|*.*";
    
      
    //Если выбран диалог открытия файла, выполняем условие
    if (openFileDialog1.ShowDialog() == DialogResult.OK) 
    {
      //Создаем новый документ
      blank frm = new blank();
      //Вызываем метод Open формы blank
      frm.Open(openFileDialog1.FileName);
      //Указываем, что родительской формой является форма frmmain
      frm.MdiParent = this;
      //Присваиваем переменной DocName имя открываемого файла
      frm.DocName = openFileDialog1.FileName;
      //Свойству Text формы присваиваем переменную DocName
      frm.Text = frm.DocName;
      //Вызываем форму frm
      frm.Show();  
    }
  }
2.5.

Запускаем приложение и открываем текстовый файл, сохраненный в формате блокнота (рис. 2.13).

Заголовок формы представляет собой адрес и имя открытого файла

Рис. 2.13. Заголовок формы представляет собой адрес и имя открытого файла

Для корректного чтения кириллицы текст в блокноте должен быть сохранен в кодировке Unicode. К сожалению, встроенные диалоговые окна OpenFileDialog Visual Studio .NET не содержат дополнительного поля, позволяющего выбирать кодировку файла при его открытии или сохранении, как это реализовано, например, в блокноте.

SaveFileDialog

Для сохранения файлов добавляем на форму frmmain элемент управления saveFileDialog1. Cвойства этого диалога в точности такие же, как у OpenFileDialog (рис. 2.12). Переходим в код формы blank:

//Создаем метод Save, в качестве параметра объявляем строку адреса  файла.
    public void Save(string SaveFileName)
    {
      //Если файл не выбран, возвращаемся назад (появится встроенное предупреждение)
      if (SaveFileName == "") 
      {
        return;
      }
      else
      {
//Создаем новый объект StreamWriter и передаем ему переменную //OpenFileName
        StreamWriter sw = new StreamWriter(SaveFileName);
        //Содержимое richTextBox1 записываем в файл
        sw.WriteLine(richTextBox1.Text);
        //Закрываем поток
        sw.Close();
//Устанавливаем в качестве имени документа название сохраненного файла
        DocName = SaveFileName;
      }
    }
2.6.

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

private void mnuSave_Click(object sender, System.EventArgs e)
  {
    //Можно программно задавать доступные для обзора расширения файлов 
    //openFileDialog1.Filter = "Text Files (*.txt)|*.txt|All Files(*.*)|*.*";

    //Если выбран диалог открытия файла, выполняем условие
    if (saveFileDialog1.ShowDialog() == DialogResult.OK) 
    {
      //Переключаем фокус на данную форму.
      blank frm = (blank)this.ActiveMdiChild;
      //Вызываем метод Save формы blank
      frm.Save(saveFileDialog1.FileName);
      //Указываем, что родительской формой является форма frmmain
      frm.MdiParent = this;
      //Присваиваем переменной FileName имя сохраняемого файла
      frm.DocName = saveFileDialog1.FileName;
      //Свойству Text формы присваиваем переменную DocName
      frm.Text = frm.DocName;      
  
    }
  }

Запускаем приложение. Теперь файлы можно открывать, редактировать и сохранять. Однако, при сохранении внесенных изменений в уже сохраненном файле вместо его перезаписи вновь появляется окно SaveFileDialog. Изменим нашу программу так, чтобы можно было сохранять и перезаписывать файл. В конструкторе формы frmmain после InitializeComponent отключим доступность пункта меню Save:

mnuSave.Enabled = false;

Переключаемся в режим дизайна формы frmmain и добавляем пункт меню Save As после пункта Save. Устанавливаем следующие свойства этого пункта: Name — mnuSaveAs, Shortcut — CtrlShiftS, Text Save &As. В обработчике Save As вставляем вырезанный обработчик пункта Save и добавляем включение доступности Save:

mnuSave.Enabled = true;

Сохранять изменения требуется как в только что сохраненных документах, так и в документах, созданных ранее и открытых для редактирования. Поэтому добавим в метод Open включение доступности пункта меню Save:

private void mnuOpen_Click(object sender, System.EventArgs e)
{
  mnuSave.Enabled = true;
}

В обработчике пункта Save добавим простую перезапись файла — вызов метода Save формы blank:

private void mnuSave_Click(object sender, System.EventArgs e)
  {
    //Переключаем фокус на данную форму.
    blank frm = (blank)this.ActiveMdiChild;
    //Вызываем метод Save формы blank
    frm.Save(frm.DocName);
    
      
  }

Запускаем приложение. Теперь, если мы работаем с несохраненным документом, пункт Save неактивен (рис. 2.14), после сохранения он становится активным (рис. 2.15) и, кроме того, работает сочетание клавиш Ctrl+S. Можно сохранить копию текущего документа, вновь воспользовавшись пунктом меню Save As (рис. 2.16).

Новый документ

Рис. 2.14. Новый документ
Сохраненный документ

Рис. 2.15. Сохраненный документ
Сохранение копии

Рис. 2.16. Сохранение копии

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

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

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

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

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

Затем:

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

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

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

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