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

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

Работа с файловой системой Windows

В рассмотренном выше примере мы проверяли наличие файла в папке Bin/Debug, где находится само приложение. В практических случаях подобная директория не может нас устраивать — требуется просматривать заданные каталоги и папки. В C# можно работать с файлами и каталогами, используя классы DirectoryInfo и FileInfo, предоставляющие всю информацию о файлах и папках.

Класс DirectoryInfo обычно применяется для таких операций, как копирование, перемещение, переименование, создание и удаление папок. Этот класс содержит метод GetFiles(), который возвращает список файлов из текущего каталога.

Класс FileInfo предоставляет методы для создания, копирования, удаления, перемещения и открытия файлов, а также является вспомогательным классом при создании объекта FileStream.

Cоздайте новое консольное приложение и назовите его DirectoryInfo. Следующий простой код выводит список всех файлов, содержащихся на диске С:

using System;
using System.IO;

namespace DirectoryInformation
{
  
  class Class1
  {
  
    [STAThread]
    static void Main(string[] args)
    {
      //Создаем экземпляр di класса DirectoryInfo и указываем диск С в качестве директории
      DirectoryInfo directoriya = new DirectoryInfo("C:\\");
      // Получаем список всех папок, содержащихся на диске С:\
      DirectoryInfo[]  poddirectoriya = directoriya.GetDirectories();
      
      foreach (DirectoryInfo dd in poddirectoriya)
      {
        //Проверяем наличие доступа к каталогу
        if(dd.Attributes == FileAttributes.Directory)
        {
          // Получаем список всех файлов из каталога
          FileInfo[] spisokfile= dd.GetFiles();
          foreach (FileInfo fi in spisokfile)
          {
            //Выводим список файлов
            Console.WriteLine(fi.ToString());
          }
        }
      }
    }
    }
  }
Листинг 2.16.

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

Чтение и запись двоичных файлов

Для более общего способа чтения и записи файлов используются классы BinaryReader и BinaryWriter, предназначенные для чтения двоичных данных. Любой файл в конечном итоге представляет собой набор двоичных данных, следовательно, эти данные можно считывать и записывать во внутреннем, двоичном формате. Класс BinaryWriter представляет собой оболочку для байтового потока, управляющей записью двоичных данных. Класс BinaryReader является оболочкой, содержащей байтовый поток, и выполняет чтение двоичных данных.

Рассмотрим приложение, позволяющее считывать файл формата MP3 и записывать фрагмент этого файла. Создайте новое консольное приложение и назовите его BinaryReadWrite. В папку bin/Debug поместите любой музыкальный файл формата MP3, имеющийся на вашем компьютере.

Подключаем пространство имен:

using System.IO;

Добавляем код:

[STAThread]
    static void Main(string[] args)
    {
      //Добавляем блок обработки исключений 
      try
      {
        //Создаем новый поток Chtenie  и указываем  файл для чтения — music.mp3
        FileStream Chtenie = new FileStream("music.mp3", FileMode.Open);

        //Создаем экземпляр  br класса BinaryReader и 
//связываем  его с потоком Chtenie
        BinaryReader br = new BinaryReader(Chtenie);

        // Создаем массив типа байтов и 
        //передаем ему размер в байтах – (например, 1000000) записываемого файла
        byte[] n = br.ReadBytes(1000000);
        //Закрываем поток
        br.Close();
        //Создаем новый поток Zapis  и указываем  название 
//файла для записи sozdanajamuzika.mp3
        FileStream Zapis = new FileStream("newmusic.mp3", FileMode.CreateNew, FileAccess.Write);
        //Создаем экземпляр  wr класса BinaryWriter и 
//связываем  его с потоком Zapis
        BinaryWriter wr = new BinaryWriter(Zapis);
        // Можно связывать объект wr с потоком создавая его без названия:
//BinaryWriter wr = new BinaryWriter(new FileStream("sozdanajamuzika.mp3", //FileMode.CreateNew, FileAccess.Write));
        //Передаем в поток массив байтов n
        wr.Write(n);
        //Закрываем поток
        br.Close();
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
      
    }
Листинг 2.17.

Запускаем приложение. Если все сработает без ошибок — на экране появится станадртное сообщение Press any key to continue, в противном случае — поскольку мы включили блок исключений — выйдет диагностическое сообщение. Перейдем в папку bin/Debug. В ней появился файл newmusic.mp3, прослушать который мы можем с помощью любого музыкального проигрывателя.

Рассмотрим перечисления в конструкторах FileStream. Параметр FileMode определяет, каким образом открывается файл (рис. 2.36):

Перечисления FileMode

Рис. 2.36. Перечисления FileMode

Значения перечисления FileMode указаны в таблице 2.4.

Таблица 2.4. Значение перечисления FileMode
Значение Описание
Append Если файл существует, он открывается, если нет — создается новый. Данные добавляются в конец файла
Create Создается новый выходной файл; если файл с таким названием существует, он перезаписывается
CreateNew Создается новый выходной файл; если файл с таким названием уже существует, генерируется исключение IOException
Open Открывается существующий файл; если файла с таким названием не существует, генерируется исключение FileNotFoundException
OpenOrCreate Открывается существующий файл; если файл не существует, он создается
Truncate Открывается существующий файл, но его длина усекается до нуля

Параметр FileAccess определяет для пользователя разрешение на доступ к файлу (рис. 2.37):

Перечисления FileAccess

увеличить изображение
Рис. 2.37. Перечисления FileAccess

Значения перечисления FileAccess указаны в таблице 2.5.

Таблица 2.5. Значение перечисления FileAccess
Значение Описание
Read Доступ на чтение из файла
ReadWrite Разрешается чтение из файла и запись данных в файл
Write Доступ для записи в файл

Дополнительно для управления режимом доступа при одновременной работе с файлами нескольких потоков используется перечисление FileShare (рис. 2.38). Например, при создании потока для чтения файла мы могли полностью определить все параметры следующим образом:

FileStream Chtenie = new FileStream("music.mp3", FileMode.Open, 
FileAccess.Read, FileShare.Read);
Перечисления FileShare

увеличить изображение
Рис. 2.38. Перечисления FileShare

Значения перечисления FileShare указаны в таблице 2.6.

Таблица 2.6. Значение перечисления FileShare
Значение Описание
Inheritable Дает доступ к файлам, образованных текущим потоком
None Запрещает совместное использование текущего файла. Пока файл открыт, доступ к нему будет блокирован
Read Позволяет открывать текущей файл для чтения
ReadWrite Позволяет открывать текущий файл для чтения или записи
Write Позволяет открывать текущий файл для записи

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

Запуск программ из приложения

Иногда в приложениях требуется запускать программы, входящие в состав операционной системы или установленные на данном компьютере. Создайте новое Windows-приложение и назовите его RunProgramm. На появившейся форме расположите три кнопки:

button1, Свойства Значения свойств
Name btnSystemInfo
Size 168;23
Text Информация о системе
button2, Свойства Значения свойств
Name btnRegEdit
Size 168;23
Text Редактор реестра
button3, Свойства Значения свойств
Name btnExplorer
Size 168;23
Text Проводник

Располагаем кнопки в центре формы и выравниваем их, используя пункт меню Format. В коде формы подключаем пространство имен Diagnostics, позволяющее запускать приложения:

using System.Diagnostics;

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

private void btnSystemInfo_Click(object sender, System.EventArgs e)
    {
      //Добавляем блок обработки исключений — по разным причинам (например, 
      //система установлена на другом диске) приложение может быть недоступным.
      try
      {
        //Создаем новый экземпляр SysInfo класса Process
        Process SysInfo = new Process();
        // Если приложение не будет работать корректно — вызываем диалоговое окно ошибок.
        SysInfo.StartInfo.ErrorDialog = true;
        //Указываем путь к  запускаемому приложению "Сведения о системе"
        SysInfo.StartInfo.FileName = "C:\\Program Files\\Common Files\\Microsoft Shared\\MSInfo\\msinfo32.exe";
        //Запускаем SysInfo
        SysInfo.Start();
      }
      catch (Exception ex)
      {
        MessageBox.Show (ex.Message);
      }
    }

    private void btnRegEdit_Click(object sender, System.EventArgs e)
    {
      try
      {
        Process RegEdit = new Process();
        RegEdit.StartInfo.ErrorDialog = true;
        //Указываем путь к  запускаемому приложению "Редактор реестра"
        RegEdit.StartInfo.FileName = "C:\\Windows\\regedit.exe";
        RegEdit.Start();
      }
      catch (Exception ex)
      {
        MessageBox.Show (ex.Message);
      }
    
    }

    private void btnExplorer_Click(object sender, System.EventArgs e)
    {
      try
      {
        Process Explorer = new Process();
        Explorer.StartInfo.ErrorDialog = true;
        //Указываем путь к  запускаемому приложению "Проводник"
        Explorer.StartInfo.FileName = "C:\\Windows\\explorer.exe";
        Explorer.Start();
      }
      catch (Exception ex)
      {
        MessageBox.Show (ex.Message);
      }
    
    }
Листинг 2.18.

Запускаем приложение. При нажатии на кнопки запускаются соответствующие приложения (рис. 2.39).

Запуск программ из приложения RunProgramm

увеличить изображение
Рис. 2.39. Запуск программ из приложения RunProgramm

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

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

Листинг форм frmmain и blank проекта NotepadCSharp

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace NotepadCSharp
{
  
  public class frmmain : System.Windows.Forms.Form
  {
    private System.Windows.Forms.MainMenu mainMenu1;
    private System.Windows.Forms.MenuItem menuItem5;
    private System.Windows.Forms.MenuItem menuItem12;
    private System.Windows.Forms.MenuItem mnuFile;
    private System.Windows.Forms.MenuItem mnuNew;
    private System.Windows.Forms.MenuItem mnuOpen;
    private System.Windows.Forms.MenuItem mnuSave;
    private System.Windows.Forms.MenuItem mnuExit;
    private System.Windows.Forms.MenuItem mnuEdit;
    private System.Windows.Forms.OpenFileDialog openFileDialog1;
    private System.Windows.Forms.MenuItem mnuCut;
    private System.Windows.Forms.MenuItem mnuCopy;
    private System.Windows.Forms.MenuItem mnuPaste;
    private System.Windows.Forms.MenuItem mnuDelete;
    private System.Windows.Forms.MenuItem mnuSelectAll;
    private System.Windows.Forms.MenuItem mnuHelp;
    private System.Windows.Forms.MenuItem mnuAbout;
  

    private System.Windows.Forms.MenuItem mnuArrangeIcons;
    private System.Windows.Forms.MenuItem mnuCascade;
    private System.Windows.Forms.MenuItem mnuTileHorizontal;
    private System.Windows.Forms.MenuItem mnuTileVertical;
    private System.Windows.Forms.MenuItem mnuWindow;
    private int openDocuments = 0;
    private System.Windows.Forms.MenuItem mnuFormat;
    private System.Windows.Forms.SaveFileDialog saveFileDialog1;
    private System.Windows.Forms.MenuItem mnuSaveAs;
    private System.Windows.Forms.FontDialog fontDialog1;
    private System.Windows.Forms.MenuItem mnuFont;
    private System.Windows.Forms.MenuItem mnuColor;
    private System.Windows.Forms.ColorDialog colorDialog1;
    private System.Windows.Forms.MenuItem menuItem1;
    private System.Windows.Forms.MenuItem mnuFind;
    private System.Windows.Forms.ToolBarButton tbNew;
    private System.Windows.Forms.ToolBarButton tbOpen;
    private System.Windows.Forms.ToolBarButton tbSave;
    private System.Windows.Forms.ToolBarButton tbCut;
    private System.Windows.Forms.ToolBarButton tbCopy;
    private System.Windows.Forms.ToolBarButton tbPaste;
    private System.Windows.Forms.ImageList imageList1;
    private System.Windows.Forms.ToolBar toolBarMain;
    private System.ComponentModel.IContainer components;
  

    public frmmain()
    {
      //
      // Required for Windows Form Designer support
      //
      InitializeComponent();
      mnuSave.Enabled = false;

      //
      // TODO: Add any constructor code after InitializeComponent call
      //
    }

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    protected override void Dispose( bool disposing )
    {
      if( disposing )
      {
        if (components != null) 
        {
          components.Dispose();
        }
      }
      base.Dispose( disposing );
    }

    region Windows Form Designer generated code
    

    [STAThread]
    static void Main() 
    {
      Application.Run(new frmmain());
    }

    
    private void mnuNew_Click(object sender, System.EventArgs e)
    {
      //Создаем новый экземпляр формы  frm
      blank  frm = new blank();

      frm.DocName = "Untitled " + ++openDocuments;
      //Указываем, что родительским контейнером 
      //нового экземпляра будет эта, главная форма.
      frm.MdiParent = this;
      frm.Text = frm.DocName;
      //Вызываем форму
      frm.Show();
    }

    private void mnuArrangeIcons_Click(object sender, System.EventArgs e)
    {
      this.LayoutMdi(MdiLayout.ArrangeIcons);
    }

  

    private void mnuCascade_Click(object sender, System.EventArgs e)
    {
      this.LayoutMdi(MdiLayout.Cascade);
    }

    private void mnuTileHorizontal_Click(object sender, System.EventArgs e)
    {
      this.LayoutMdi(MdiLayout.TileHorizontal);
    }

    private void mnuTileVertical_Click(object sender, System.EventArgs e)
    {
      this.LayoutMdi(MdiLayout.TileVertical);
    }

    private void mnuCut_Click(object sender, System.EventArgs e)
    {
      blank frm = (blank)this.ActiveMdiChild;
      frm.Cut();
    }

    private void mnuCopy_Click(object sender, System.EventArgs e)
    {
      blank frm = (blank)this.ActiveMdiChild;
      frm.Copy();
    }

    private void mnuPaste_Click(object sender, System.EventArgs e)
    {
      blank frm = (blank)this.ActiveMdiChild;
      frm.Paste();
    }

    private void mnuDelete_Click(object sender, System.EventArgs e)
    {
      blank frm = (blank)this.ActiveMdiChild;
      frm.Delete();
    }

    private void mnuSelectAll_Click(object sender, System.EventArgs e)
    {
      blank frm = (blank)this.ActiveMdiChild;
      frm.SelectAll();
    }

    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();  
        mnuSave.Enabled = true;
      }
    

    }

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

    private void mnuSaveAs_Click(object sender, System.EventArgs e)
    {
      mnuSave.Enabled = true;
      //Можно программно задавать доступные для обзора расширения файлов 
      //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;    
        frm.IsSaved = true;
        
    
      }

    }

    private void mnuExit_Click(object sender, System.EventArgs e)
    {
      this.Close();
    }

    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();
    }

    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();
    }

    
    private void mnuFind_Click(object sender, System.EventArgs e)
    {
      //Создаем новый экземпляр формы FindForm
      FindForm frm = new FindForm();
      //Если выбран результат DialogResult.Cancel, закрываем форму (до этого 
      //мы использовали DialogResult.OK
      if(frm.ShowDialog(this) == DialogResult.Cancel) return;
      ////Переключаем фокус на данную форму.
      blank form = (blank)this.ActiveMdiChild;
      ////Указываем, что родительской формой является форма frmmain  
      form.MdiParent = this;
      //Вводим переменную для поиска в определенной части текста —
      //поиск слова будет осуществляться от текущей позиции курсора
      int start = form.richTextBox1.SelectionStart;
      //Вызываем предопределенный метод Find элемента richTextBox1.
      form.richTextBox1.Find(frm.FindText, start, frm.FindCondition);
    }

    private void mnuAbout_Click(object sender, System.EventArgs e)
    {
      //Создаем новый экземпляр формы  About
      About  frm = new About();
      frm.Show();
    }

    private void toolBarMain_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
    {
      //New
      if (e.Button.Equals(tbNew)) 
      {
        mnuNew_Click(this, new EventArgs());
      }
      //Open
      if (e.Button.Equals(tbOpen))
      {
        mnuOpen_Click(this, new EventArgs());
      }
      //Save
      if (e.Button.Equals(tbSave))
      {
        mnuSave_Click(this, new EventArgs());
      }
      //Cut
      if (e.Button.Equals(tbCut))
      {
        mnuCut_Click(this, new EventArgs());
      }
      //Copy
      if (e.Button.Equals(tbCopy))
      {
        mnuCopy_Click(this, new EventArgs());
      }
      //Paste
      if (e.Button.Equals(tbPaste))
      {
        mnuPaste_Click(this, new EventArgs());
      }
    }
  }
}
Листинг 2.19. Форма frmmain
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;

namespace NotepadCSharp
{
  /// <summary>
  /// Summary description for blank.
  /// </summary>
  public class blank : System.Windows.Forms.Form
  {
    public System.Windows.Forms.RichTextBox richTextBox1;
    public string DocName = "";
    private string BufferText = "";
    private System.Windows.Forms.ContextMenu contextMenu1;
    private System.Windows.Forms.MenuItem cmnuCut;
    private System.Windows.Forms.MenuItem cmnuCopy;
    private System.Windows.Forms.MenuItem cmnuPaste;
    private System.Windows.Forms.MenuItem cmnuDelete;
    private System.Windows.Forms.MenuItem menuItem6;
    private System.Windows.Forms.MenuItem cmnuSelectAll;
    public bool IsSaved = false;
    private System.Windows.Forms.StatusBar statusBar1;
    private System.Windows.Forms.StatusBarPanel sbAmount;
    private System.Windows.Forms.StatusBarPanel sbTime;
    
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null;



    public blank()
    {
      
      InitializeComponent();
      //Свойству Text панели sbTime устанавливаем системное время, 
      // конвертировав его в тип String
      sbTime.Text = Convert.ToString(System.DateTime.Now.ToLongTimeString());
      //В тексте всплывающей подсказки  выводим текущую дату
      sbTime.ToolTipText = Convert.ToString(System.DateTime.Today.ToLongDateString());
    }

    
    protected override void Dispose( bool disposing )
    {
      if( disposing )
      {
        if(components != null)
        {
          components.Dispose();
        }
      }
      base.Dispose( disposing );
    }

    region Windows Form Designer generated code
    

    // Вырезание текста
    public void Cut()
    {
      this.BufferText = richTextBox1.SelectedText;
      richTextBox1.SelectedText = "";
    }

    // Копирование текста
    public void Copy()
    {
      this.BufferText = richTextBox1.SelectedText;
    }

    // Вставка
    public void Paste()
    {
      richTextBox1.SelectedText = this.BufferText;
    }

    // Выделение всего текста — используем свойство SelectAll элемента управления RichTextBox 
    public void SelectAll()
    {
      richTextBox1.SelectAll(); 
    }

    // Удаление.
    public void Delete()
    {
      richTextBox1.SelectedText = "";  
      this.BufferText = "";
    }
    //Создаем метод 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;
      }      
    }

    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();
    }
    //Создаем метод 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;
      }
    }

    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); 
        }    
     
    
    }

    private void richTextBox1_TextChanged(object sender, System.EventArgs e)
    {
      //Свойству Text панели sbAmount устанавливаем надпись "Аmount of symbols " 
      //и длину  текста в RichTextBox.
      sbAmount.Text = "Аmount of symbols " + richTextBox1.Text.Length.ToString(); 
    }      
    }
  }
Листинг 2.20. Форма blank
Елена Дьяконова
Елена Дьяконова

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

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

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

Затем:

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

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

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

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