Опубликован: 11.09.2006 | Уровень: специалист | Доступ: платный
Лекция 6:

Работа с печатью и изображениями

В методе UstanovkaRejima проверяется значение переменной prosmotrperemen и вызывается соответствующий метод:

private void UstanovkaRejima()
    {
      //если pictureBox1 не содержит изображения, возвращаемся назад
      if ( this.pictureBox1.Image == null )
        return;
      //Если значение переменной prosmotrperemen равно PodgonRazmera,
      //вызываем метод PodgonRazmera
      if ( this.prosmotrperemen == RejimProsmotra.PodgonRazmera )
        this.PodgonRazmera();
      //Иначе вызываем метод Prokrutka
      else
      {
        
        this.Prokrutka();  
        this.AutoScroll = true;
      
      }
    }

В методе PomeshenieIzobrajeniyavCenter определяется положение элемента pictureBox1 и, соответственно, положение изображения:

private void PomeshenieIzobrajeniyavCenter()
    {
      //Переменная top равна разнице между высотой элемента 
      //и высотой pictureBox1, деленной пополам
      int top = (int)((this.Height - this.pictureBox1.Height)/2.0);
      //Переменная left равна разнице между шириной  элемента 
      //и шириной pictureBox1, деленной пополам
      int left = (int)((this.Width - this.pictureBox1.Width)/2.0);
      if ( top < 0 )
        top = 0;
      if ( left > 0 )
        left = 0;
      this.pictureBox1.Top = top;
      this.pictureBox1.Left = left;    
    }

Переключаемся в режим дизайна, выделяем форму, в окне Properties переключаемся на события и дважды щелкаем в поле Resize и Load:

private void NamePictureElement_Resize(object sender, System.EventArgs e)
    {
    //При изменении размеров элемента вызывается метод для установки режима просмотра:
    this.UstanovkaRejima();
    }

private void NamePictureElement_Load(object sender, System.EventArgs e)
    {
      //при загрузке элемента устанавливаем нулевые ширину и высоту pictureBox1
      this.pictureBox1.Width = 0;
      this.pictureBox1.Height = 0;
      //Вызываем метод для установки режима просмотра
      this.UstanovkaRejima();
    }

Все! Компилируем проект, используя сочетания клавиш Ctrl+Shift+B, и закрываем его. Создаем новое Windows-приложение, которое называем AutoScroll_and_Constrain. В свойстве Text формы можно ввести надпись "Сохранение пропорций и прокрутка". Перетаскиваем на форму OpenFileDialog, а главное меню скопируем из приложения Picture Viewer, затем оставим следующие пункты:

mainMenu1, Name Text Shortcut
mnuFile &Файл
mnuOpen &Открыть CtrlO
mnuView &Вид
mnuResize &Подогнать размер
mnuActual &Истинный размер

Теперь нам нужно добавить созданный пользовательский элемент управления. В окне Toolbox щелкаем правой кнопкой на закладке Windows Forms и выбираем пункт Add/Remove Items… . В окне Customize Toolbox на вкладке .NET Framework Components нажимаем кнопку Browse и выбираем файл PictureElement.dll из папки bin/Debug проекта PictureElement. В результате в окне компонент появляется элемент NamePictureElement, принадлежащий пространству имен PictureElement (рис. 6.24).

Элемент NamePictureElement

Рис. 6.24. Элемент NamePictureElement

Закрываем окно Customize Toolbox и перетаскиваем на форму появившейся элемент управления NamePictureElement. Обратите внимание на название этого элемента — не случайно при работе с проектом PictureElement мы дали проекту, форме и объекту в Solution Explorer три разных названия. На вкладке Toolbox элемент управления будет называться так же, как и форма пользовательского элемента в режиме дизайна (рис. 6.25).

Свойство Name формы будет названием пользовательского элемента управления

Рис. 6.25. Свойство Name формы будет названием пользовательского элемента управления

В окне Properties элемента namePictureElement1 появились два новых свойства, которые мы создали сами (рис. 6.26)!

Слева приведены фрагменты кода пользовательского элемента управления, на основании которых и были созданы свойства в окне Properties

Рис. 6.26. Слева приведены фрагменты кода пользовательского элемента управления, на основании которых и были созданы свойства в окне Properties

Устанавливаем свойству Dock значение Fill, а свойству UserPropRejimProsmotra — значение PodgonRazmera. В обработчике пункта меню "Открыть" свойству Izobrajenie элемента загружаемое изображение:

private void mnuOpen_Click(object sender, System.EventArgs e)
{
  this.openFileDialog1.ShowDialog();
  string path = this.openFileDialog1.FileName;
  this.namePictureElement1.Izobrajenie = Image.FromFile(path);
}

В обработчиках пунктов меню изменения режима просмотра последовательно устанавливаем два значения свойства UserPropRejimProsmotra:

private void mnuResize_Click(object sender, System.EventArgs e)
  {
   this.namePictureElement1.UserPropRejimProsmotra = PictureElement.RejimProsmotra.PodgonRazmera;
  }

   private void mnuActual_Click(object sender, System.EventArgs e)
  {
   this.namePictureElement1.UserPropRejimProsmotra = PictureElement.RejimProsmotra.Prokrutka;
  }

Строка кода в обработчике mnuResize_Click скопирована из области Windows Form Designer generated code:

// 
// namePictureElement1
// 
this.namePictureElement1.Dock = System.Windows.Forms.DockStyle.Fill;
this.namePictureElement1.Izobrajenie = null;
…
this.namePictureElement1.UserPropRejimProsmotra = PictureElement.RejimProsmotra.PodgonRazmera;

Запускаем приложение. Два режима просмотра позволяют просматривать уменьшенное изображение с сохранением пропорций или его действительную часть с прокруткой (рис. 6.27).

Готовое приложение AutoScroll_and_Constrain

Рис. 6.27. Готовое приложение AutoScroll_and_Constrain

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

Полный листинг приложения TextEditor

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

namespace TextEditor
{
  
  public class Form1 : System.Windows.Forms.Form
  {
    private System.Windows.Forms.OpenFileDialog openFileDialog1;
    private System.Windows.Forms.SaveFileDialog saveFileDialog1;
    private System.Windows.Forms.RichTextBox rtbText;
    private System.Windows.Forms.MainMenu mainMenu1;
    private System.Windows.Forms.MenuItem mnuFile;
    private System.Windows.Forms.MenuItem mnuOpen;
    private System.Windows.Forms.MenuItem mnuSave;
    private System.Windows.Forms.MenuItem menuItem1;
    private System.Windows.Forms.MenuItem mnuPageSetup;
    private System.Windows.Forms.MenuItem mnuPrintPreview;
    private System.Windows.Forms.MenuItem mnuPrint;
    private System.Windows.Forms.PageSetupDialog pageSetupDialog1;
    private System.Drawing.Printing.PrintDocument printDocument1;
    private System.Windows.Forms.PrintDialog printDialog1;
    private System.Windows.Forms.PrintPreviewDialog printPreviewDialog1;
    //Переменная для хранения текста для печати.
    //В нее мы будем помещать текст из RichTextBox
    string stringPrintText;
    //Переменная, определяющая номер страницы, с которой нужно начать печать
    int StartPage;
    //Переменная, определяющая количество страниц для печати:
    int NumPages;
    //Переменная, определяющая номер текущей страницы:
    int PageNumber;

    //    PrintDocument printDocument1 = new PrintDocument();
    //    PageSetupDialog  pageSetupDialog1 = new PageSetupDialog();
    //    PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog();
    //    PrintDialog printDialog1 = new PrintDialog();

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null;

    public Form1()
    {
      
      InitializeComponent();
      //      pageSetupDialog1.Document = printDocument1;
      //      printPreviewDialog1.Document = printDocument1;
      //      printDialog1.Document = printDocument1;
      //      printDialog1.AllowSomePages = true;
      //      printDialog1.AllowSelection = true;
      //
      //Определяем номер страницы, с которой следует начать печать
      printDialog1.PrinterSettings.FromPage = 1;
      //Определяем максимальный номер печатаемой страницы.
      printDialog1.PrinterSettings.ToPage = printDialog1.PrinterSettings.MaximumPage;

    
    }

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

    #region Windows Form Designer generated code
    /// <summary>
    /// Required method for Designer support — do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
      this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
      this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
      this.rtbText = new System.Windows.Forms.RichTextBox();
      this.mainMenu1 = new System.Windows.Forms.MainMenu();
      this.mnuFile = new System.Windows.Forms.MenuItem();
      this.mnuOpen = new System.Windows.Forms.MenuItem();
      this.mnuSave = new System.Windows.Forms.MenuItem();
      this.menuItem1 = new System.Windows.Forms.MenuItem();
      this.mnuPageSetup = new System.Windows.Forms.MenuItem();
      this.mnuPrintPreview = new System.Windows.Forms.MenuItem();
      this.mnuPrint = new System.Windows.Forms.MenuItem();
      this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog();
      this.printDocument1 = new System.Drawing.Printing.PrintDocument();
      this.printDialog1 = new System.Windows.Forms.PrintDialog();
      this.printPreviewDialog1 = new System.Windows.Forms.PrintPreviewDialog();
      this.SuspendLayout();
      // 
      // openFileDialog1
      // 
      this.openFileDialog1.FileName = "Текстовые файлы";
      this.openFileDialog1.Filter = "Text Files (*.txt)|*.txt|All Files(*.*)|*.*  ";
      // 
      // saveFileDialog1
      // 
      this.saveFileDialog1.FileName = "Текстовые файлы";
      this.saveFileDialog1.Filter = "Text Files (*.txt)|*.txt|All Files(*.*)|*.*  ";
      // 
      // rtbText
      // 
      this.rtbText.Dock = System.Windows.Forms.DockStyle.Fill;
      this.rtbText.Location = new System.Drawing.Point(0, 0);
      this.rtbText.Name = "rtbText";
      this.rtbText.Size = new System.Drawing.Size(292, 266);
      this.rtbText.TabIndex = 1;
      this.rtbText.Text = "";
      // 
      // mainMenu1
      // 
      this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                            this.mnuFile});
      // 
      // mnuFile
      // 
      this.mnuFile.Index = 0;
      this.mnuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                          this.mnuOpen,
                                          this.mnuSave,
                                          this.menuItem1,
                                          this.mnuPageSetup,
                                          this.mnuPrintPreview,
                                          this.mnuPrint});
      this.mnuFile.Text = "&Файл";
      // 
      // mnuOpen
      // 
      this.mnuOpen.Index = 0;
      this.mnuOpen.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
      this.mnuOpen.Text = "&Открыть";
      this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
      // 
      // mnuSave
      // 
      this.mnuSave.Index = 1;
      this.mnuSave.Shortcut = System.Windows.Forms.Shortcut.CtrlS;
      this.mnuSave.Text = "&Сохранить";
      // 
      // menuItem1
      // 
      this.menuItem1.Index = 2;
      this.menuItem1.Text = "-";
      // 
      // mnuPageSetup
      // 
      this.mnuPageSetup.Index = 3;
      this.mnuPageSetup.Text = "Пара&метры страницы";
      this.mnuPageSetup.Click += new System.EventHandler(this.mnuPageSetup_Click);
      // 
      // mnuPrintPreview
      // 
      this.mnuPrintPreview.Index = 4;
      this.mnuPrintPreview.Text = "Пред&варительный просмотр";
      this.mnuPrintPreview.Click += new System.EventHandler(this.mnuPrintPreview_Click);
      // 
      // mnuPrint
      // 
      this.mnuPrint.Index = 5;
      this.mnuPrint.Shortcut = System.Windows.Forms.Shortcut.CtrlP;
      this.mnuPrint.Text = "&Печать";
      this.mnuPrint.Click += new System.EventHandler(this.mnuPrint_Click);
      // 
      // pageSetupDialog1
      // 
      this.pageSetupDialog1.Document = this.printDocument1;
      // 
      // printDocument1
      // 
      this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage);
      // 
      // printDialog1
      // 
      this.printDialog1.AllowSelection = true;
      this.printDialog1.AllowSomePages = true;
      this.printDialog1.Document = this.printDocument1;
      // 
      // printPreviewDialog1
      // 
      this.printPreviewDialog1.AutoScrollMargin = new System.Drawing.Size(0, 0);
      this.printPreviewDialog1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
      this.printPreviewDialog1.ClientSize = new System.Drawing.Size(400, 300);
      this.printPreviewDialog1.Document = this.printDocument1;
      this.printPreviewDialog1.Enabled = true;
      this.printPreviewDialog1.Icon = ((System.Drawing.Icon)(resources.GetObject("printPreviewDialog1.Icon")));
      this.printPreviewDialog1.Location = new System.Drawing.Point(17, 54);
      this.printPreviewDialog1.MinimumSize = new System.Drawing.Size(375, 250);
      this.printPreviewDialog1.Name = "printPreviewDialog1";
      this.printPreviewDialog1.TransparencyKey = System.Drawing.Color.Empty;
      this.printPreviewDialog1.Visible = false;
      // 
      // Form1
      // 
      this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
      this.ClientSize = new System.Drawing.Size(292, 266);
      this.Controls.Add(this.rtbText);
      this.Menu = this.mainMenu1;
      this.Name = "Form1";
      this.Text = "TextEditor";
      this.ResumeLayout(false);

    }
    #endregion

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

    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 /*System.Text.Encoding.Unicode*/);
        //Считываем весь файл и записываем его в TextBox
        rtbText.Text = streamreader.ReadToEnd();
        //Закрываем поток.
        filestream.Close();
      }
    }

    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(rtbText.Text);
        //Переносим данные из потока в файл
        streamwriter.Flush();
        //Закрываем поток
        filestream.Close();
      }
    }

    private void mnuPageSetup_Click(object sender, System.EventArgs e)
    {
      //Показываем диалог
      pageSetupDialog1.ShowDialog();
    }

    private void mnuPrintPreview_Click(object sender, System.EventArgs e)
    {
      //Инициализируем переменные
      printDocument1.DocumentName = Text;
      stringPrintText = rtbText.Text;
      StartPage = 1;
      NumPages = printDialog1.PrinterSettings.MaximumPage;
      PageNumber = 1;
      //Показываем диалог
      printPreviewDialog1.ShowDialog();
    }

    private void mnuPrint_Click(object sender, System.EventArgs e)
    {
      printDialog1.AllowSelection = rtbText.SelectionLength >0;

      if(printDialog1.ShowDialog()==DialogResult.OK)
      {
        printDocument1.DocumentName =Text;
        //Определяем диапазон страниц для печати
        switch(printDialog1.PrinterSettings.PrintRange)
        {
            //Выбраны все страницы
          case PrintRange.AllPages:
            stringPrintText = rtbText.Text;
            StartPage = 1;
            NumPages = printDialog1.PrinterSettings.MaximumPage;
            break;
            //Выбрана выделенная область
          case PrintRange.Selection:
            stringPrintText = rtbText.SelectedText;
            StartPage = 1;
            NumPages = printDialog1.PrinterSettings.MaximumPage;
            break;
            //Выбран ряд страниц
          case PrintRange.SomePages:
            stringPrintText = rtbText.Text;
            StartPage = printDialog1.PrinterSettings.FromPage;
            NumPages = printDialog1.PrinterSettings.ToPage - StartPage+1;
            break;
        }
        PageNumber = 1;
        //Вызываем встроенный метод для начала печати
        printDocument1.Print();
      }
      
    }
    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
      //Создаем экземпляр graph класса Graphics
      Graphics graph = e.Graphics;
      //Создаем объект font, которому устанавливаем 
      // шрифт элемента rtbText
      Font font = rtbText.Font;
      //Получаем значение межстрочного интервала — высоту шрифта Т1, 134
      float HeightFont = font.GetHeight(graph);
      //Создаем экземпляр stringformat класса StringFormat для определения 
      //дополнительных параметров форматирования текста.
      StringFormat  stringformat = new StringFormat();
      //Создаем экземляры  rectanglefFull и rectanglefText класса RectangleF для 
      //определния областей печати и текста. Т1, 104
      RectangleF rectanglefFull, rectanglefText;
      //Создаем переменные для подсчета числа символов и строк.
      int NumberSymbols, NumberLines;
      //В качестве области печати устанавливаем объект rectanglefFull
      if (graph.VisibleClipBounds.X<0) rectanglefFull = e.MarginBounds;
      else
        //Определяем   объект  rectanglefFull
        rectanglefFull = new RectangleF(
          //Устанавливаем координату  X  
          e.MarginBounds.Left - (e.PageBounds.Width - graph.VisibleClipBounds.Width)/2, 
          //Устанавливаем координату  Y
          e.MarginBounds.Top - (e.PageBounds.Height - graph.VisibleClipBounds.Height)/2, 
          //Устанавливаем ширину области
          e.MarginBounds.Width,
          //Устанавливаем высоту области
          e.MarginBounds.Height);
      rectanglefText = RectangleF.Inflate(rectanglefFull, 0, -2*HeightFont);
      //Определяем число строк
      int NumDisplayLines = (int)Math.Floor(rectanglefText.Height/HeightFont);
      //Устанавливаем высоту области
      rectanglefText.Height = NumDisplayLines*HeightFont;
    
      if (rtbText.WordWrap)
      {
        stringformat.Trimming = StringTrimming.Word;
      }
      else
      {
        stringformat.Trimming = StringTrimming.EllipsisCharacter;
        stringformat.FormatFlags |=StringFormatFlags.NoWrap;
      }
      //При печати выбранных страниц переходим к первой стартовой странице
      while ((PageNumber<StartPage)&&(stringPrintText.Length>0))
      {
        if(rtbText.WordWrap)
          //Измеряем текстовые переменные, 
          //формирующие печать,  и возвращаем число символов NumberSymbols
          //и число строк NumberLines
          graph.MeasureString(stringPrintText, font, rectanglefText.Size, stringformat, out NumberSymbols, out NumberLines);
        else
          NumberSymbols = SymbolsInLines(stringPrintText, NumDisplayLines);
        stringPrintText = stringPrintText.Substring(NumberSymbols);
        //Увеличиваем число страниц 
        PageNumber++;
      }
      //Если длина строки stringPrintText равняется нулю (нет текста для печати),
      // останавливаем печать
      if (stringPrintText.Length==0)
      {
        e.Cancel = true;
        return;
      }
      //Выводим (рисуем) текст для печати — stringPrintText, используем для этого шрифт font,
      //кисть черного цвета  — Brushes.Black, область печати — rectanglefText,
      //передаем строку  дополнительного форматирования stringformat
      graph.DrawString(stringPrintText, font, Brushes.Black, rectanglefText, stringformat);
      //Получаем текст для следующей страницы
      if (rtbText.WordWrap)
        graph.MeasureString(stringPrintText, font, rectanglefText.Size, stringformat, out NumberSymbols, out NumberLines);
      else
        NumberSymbols = SymbolsInLines(stringPrintText, NumDisplayLines);
      stringPrintText = stringPrintText.Substring(NumberSymbols);
      //Очищаем объект stringformat, использованный для формирования полей.
      stringformat = new StringFormat();
      //Добавляем  вывод на каждую страницу ее номера
      stringformat.Alignment = StringAlignment.Far;
      graph.DrawString("Страница " + PageNumber, font, Brushes.Black, rectanglefFull, stringformat);
      PageNumber++;
      //Cнова проверяем, имеется ли текст для печати и номер страницы, заданной для печати
      e.HasMorePages=(stringPrintText.Length>0)&&(PageNumber<StartPage+NumPages);
      //Для печати из окна предварительного просмотра  снова инициализируем переменные
      if(!e.HasMorePages)
      {
        stringPrintText = rtbText.Text;
        StartPage = 1;
        NumPages = printDialog1.PrinterSettings.MaximumPage;
        PageNumber = 1;
      }

      
    }
    

    int SymbolsInLines(string stringPrintText, int NumLines)
    {
      int index = 0;
      for (int i = 0; i< NumLines; i++)
      {
        index = 1+ stringPrintText.IndexOf('\n', index);
        if(index==0)
          return stringPrintText.Length;
      }
      return index;
    }

    

    }
  }
Листинг 6.13.

Полный листинг приложения PictureViewer

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

namespace PictureViewer
{
  /// <summary>
  /// Summary description for Form1.
  /// </summary>
  public class Form1 : System.Windows.Forms.Form
  {
    private System.Windows.Forms.MainMenu mainMenu1;
    private System.Windows.Forms.MenuItem mnuFile;
    private System.Windows.Forms.MenuItem mnuOpen;
    private System.Windows.Forms.MenuItem mnuSave;
    private System.Windows.Forms.MenuItem menuItem1;
    private System.Windows.Forms.MenuItem mnuPageSetup;
    private System.Windows.Forms.MenuItem mnuPreview;
    private System.Windows.Forms.MenuItem mnuPrint;
    private System.Windows.Forms.MenuItem menuItem5;
    private System.Windows.Forms.MenuItem mnuExit;
    private System.Windows.Forms.MenuItem mnuView;
    private System.Windows.Forms.MenuItem mnuResize;
    private System.Windows.Forms.OpenFileDialog openFileDialog1;
    private System.Windows.Forms.SaveFileDialog saveFileDialog1;
    private System.Windows.Forms.ContextMenu contextMenu1;
    private System.Windows.Forms.PictureBox pictureBox1;
    private System.Windows.Forms.MenuItem mnuActual;
    private System.Windows.Forms.MenuItem mnuCenterImage;
    private System.Windows.Forms.MenuItem mnuAutoSize;
    private System.Windows.Forms.MenuItem cmnuResize;
    private System.Windows.Forms.MenuItem cmnuActual;
    private System.Windows.Forms.MenuItem cmnuCenterImage;
    private System.Windows.Forms.MenuItem cmnuAutoSize;
    private System.Windows.Forms.StatusBar statusBar1;
    private System.Windows.Forms.StatusBarPanel sbFile;
    private System.Windows.Forms.StatusBarPanel sbSize;
    private System.Windows.Forms.PrintDialog printDialog1;
    private System.Windows.Forms.PrintPreviewDialog printPreviewDialog1;
    private System.Windows.Forms.PageSetupDialog pageSetupDialog1;
    private System.Drawing.Printing.PrintDocument printDocument1;
    
    private System.ComponentModel.Container components = null;

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

    #region Windows Form Designer generated code
    /// <summary>
    /// Required method for Designer support — do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
      this.mainMenu1 = new System.Windows.Forms.MainMenu();
      this.mnuFile = new System.Windows.Forms.MenuItem();
      this.mnuOpen = new System.Windows.Forms.MenuItem();
      this.mnuSave = new System.Windows.Forms.MenuItem();
      this.menuItem1 = new System.Windows.Forms.MenuItem();
      this.mnuPageSetup = new System.Windows.Forms.MenuItem();
      this.mnuPreview = new System.Windows.Forms.MenuItem();
      this.mnuPrint = new System.Windows.Forms.MenuItem();
      this.menuItem5 = new System.Windows.Forms.MenuItem();
      this.mnuExit = new System.Windows.Forms.MenuItem();
      this.mnuView = new System.Windows.Forms.MenuItem();
      this.mnuResize = new System.Windows.Forms.MenuItem();
      this.mnuActual = new System.Windows.Forms.MenuItem();
      this.mnuCenterImage = new System.Windows.Forms.MenuItem();
      this.mnuAutoSize = new System.Windows.Forms.MenuItem();
      this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
      this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
      this.contextMenu1 = new System.Windows.Forms.ContextMenu();
      this.cmnuResize = new System.Windows.Forms.MenuItem();
      this.cmnuActual = new System.Windows.Forms.MenuItem();
      this.cmnuCenterImage = new System.Windows.Forms.MenuItem();
      this.cmnuAutoSize = new System.Windows.Forms.MenuItem();
      this.pictureBox1 = new System.Windows.Forms.PictureBox();
      this.statusBar1 = new System.Windows.Forms.StatusBar();
      this.sbFile = new System.Windows.Forms.StatusBarPanel();
      this.sbSize = new System.Windows.Forms.StatusBarPanel();
      this.printDialog1 = new System.Windows.Forms.PrintDialog();
      this.printPreviewDialog1 = new System.Windows.Forms.PrintPreviewDialog();
      this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog();
      this.printDocument1 = new System.Drawing.Printing.PrintDocument();
      ((System.ComponentModel.ISupportInitialize)(this.sbFile)).BeginInit();
      ((System.ComponentModel.ISupportInitialize)(this.sbSize)).BeginInit();
      this.SuspendLayout();
      // 
      // mainMenu1
      // 
      this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                            this.mnuFile,
                                            this.mnuView});
      // 
      // mnuFile
      // 
      this.mnuFile.Index = 0;
      this.mnuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                          this.mnuOpen,
                                          this.mnuSave,
                                          this.menuItem1,
                                          this.mnuPageSetup,
                                          this.mnuPreview,
                                          this.mnuPrint,
                                          this.menuItem5,
                                          this.mnuExit});
      this.mnuFile.Text = "&Файл";
      // 
      // mnuOpen
      // 
      this.mnuOpen.Index = 0;
      this.mnuOpen.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
      this.mnuOpen.Text = "&Открыть";
      this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
      // 
      // mnuSave
      // 
      this.mnuSave.Index = 1;
      this.mnuSave.Shortcut = System.Windows.Forms.Shortcut.CtrlS;
      this.mnuSave.Text = "&Сохранить";
      this.mnuSave.Click += new System.EventHandler(this.mnuSave_Click);
      // 
      // menuItem1
      // 
      this.menuItem1.Index = 2;
      this.menuItem1.Text = "-";
      // 
      // mnuPageSetup
      // 
      this.mnuPageSetup.Index = 3;
      this.mnuPageSetup.Text = "Page Se&tup";
      this.mnuPageSetup.Click += new System.EventHandler(this.mnuPageSetup_Click);
      // 
      // mnuPreview
      // 
      this.mnuPreview.Index = 4;
      this.mnuPreview.Text = "Print Pre&view";
      this.mnuPreview.Click += new System.EventHandler(this.mnuPreview_Click);
      // 
      // mnuPrint
      // 
      this.mnuPrint.Index = 5;
      this.mnuPrint.Shortcut = System.Windows.Forms.Shortcut.CtrlP;
      this.mnuPrint.Text = "&Print";
      this.mnuPrint.Click += new System.EventHandler(this.mnuPrint_Click);
      // 
      // menuItem5
      // 
      this.menuItem5.Index = 6;
      this.menuItem5.Text = "-";
      // 
      // mnuExit
      // 
      this.mnuExit.Index = 7;
      this.mnuExit.Shortcut = System.Windows.Forms.Shortcut.AltF4;
      this.mnuExit.Text = "&Выход";
      this.mnuExit.Click += new System.EventHandler(this.mnuExit_Click);
      // 
      // mnuView
      // 
      this.mnuView.Index = 1;
      this.mnuView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                          this.mnuResize,
                                          this.mnuActual,
                                          this.mnuCenterImage,
                                          this.mnuAutoSize});
      this.mnuView.Text = "&Вид";
      this.mnuView.Popup += new System.EventHandler(this.mnuView_Popup);
      // 
      // mnuResize
      // 
      this.mnuResize.Index = 0;
      this.mnuResize.Text = "&Подогнать размер";
      this.mnuResize.Click += new System.EventHandler(this.mnuResize_Click);
      // 
      // mnuActual
      // 
      this.mnuActual.Index = 1;
      this.mnuActual.Text = "&Истинный размер";
      this.mnuActual.Click += new System.EventHandler(this.mnuActual_Click);
      // 
      // mnuCenterImage
      // 
      this.mnuCenterImage.Index = 2;
      this.mnuCenterImage.Text = "&По центру";
      this.mnuCenterImage.Click += new System.EventHandler(this.mnuCenterImage_Click);
      // 
      // mnuAutoSize
      // 
      this.mnuAutoSize.Index = 3;
      this.mnuAutoSize.Text = "&Автоматический размер";
      this.mnuAutoSize.Click += new System.EventHandler(this.mnuAutoSize_Click);
      // 
      // openFileDialog1
      // 
      this.openFileDialog1.Title = "Выбор изображения";
      // 
      // saveFileDialog1
      // 
      this.saveFileDialog1.Title = "Сохранение изображения";
      // 
      // contextMenu1
      // 
      this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                             this.cmnuResize,
                                             this.cmnuActual,
                                             this.cmnuCenterImage,
                                             this.cmnuAutoSize});
      // 
      // cmnuResize
      // 
      this.cmnuResize.Index = 0;
      this.cmnuResize.Text = "&Подогнать размер";
      this.cmnuResize.Click += new System.EventHandler(this.cmnuResize_Click);
      // 
      // cmnuActual
      // 
      this.cmnuActual.Index = 1;
      this.cmnuActual.Text = "&Истинный размер";
      this.cmnuActual.Click += new System.EventHandler(this.cmnuActual_Click);
      // 
      // cmnuCenterImage
      // 
      this.cmnuCenterImage.Index = 2;
      this.cmnuCenterImage.Text = "&По центру";
      this.cmnuCenterImage.Click += new System.EventHandler(this.cmnuCenterImage_Click);
      // 
      // cmnuAutoSize
      // 
      this.cmnuAutoSize.Index = 3;
      this.cmnuAutoSize.Text = "&Автоматический размер";
      this.cmnuAutoSize.Click += new System.EventHandler(this.cmnuAutoSize_Click);
      // 
      // pictureBox1
      // 
      this.pictureBox1.ContextMenu = this.contextMenu1;
      this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
      this.pictureBox1.Location = new System.Drawing.Point(0, 0);
      this.pictureBox1.Name = "pictureBox1";
      this.pictureBox1.Size = new System.Drawing.Size(616, 266);
      this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
      this.pictureBox1.TabIndex = 0;
      this.pictureBox1.TabStop = false;
      // 
      // statusBar1
      // 
      this.statusBar1.Location = new System.Drawing.Point(0, 244);
      this.statusBar1.Name = "statusBar1";
      this.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
                                              this.sbFile,
                                              this.sbSize});
      this.statusBar1.ShowPanels = true;
      this.statusBar1.Size = new System.Drawing.Size(616, 22);
      this.statusBar1.TabIndex = 3;
      // 
      // sbFile
      // 
      this.sbFile.Width = 500;
      // 
      // printPreviewDialog1
      // 
      this.printPreviewDialog1.AutoScrollMargin = new System.Drawing.Size(0, 0);
      this.printPreviewDialog1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
      this.printPreviewDialog1.ClientSize = new System.Drawing.Size(400, 300);
      this.printPreviewDialog1.Enabled = true;
      this.printPreviewDialog1.Icon = ((System.Drawing.Icon)(resources.GetObject("printPreviewDialog1.Icon")));
      this.printPreviewDialog1.Location = new System.Drawing.Point(151, 59);
      this.printPreviewDialog1.MinimumSize = new System.Drawing.Size(375, 250);
      this.printPreviewDialog1.Name = "printPreviewDialog1";
      this.printPreviewDialog1.TransparencyKey = System.Drawing.Color.Empty;
      this.printPreviewDialog1.Visible = false;
      // 
      // printDocument1
      // 
      this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage);
      // 
      // Form1
      // 
      this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
      this.ClientSize = new System.Drawing.Size(616, 266);
      this.ContextMenu = this.contextMenu1;
      this.Controls.Add(this.statusBar1);
      this.Controls.Add(this.pictureBox1);
      this.Menu = this.mainMenu1;
      this.Name = "Form1";
      this.Text = "Picture Viewer";
      ((System.ComponentModel.ISupportInitialize)(this.sbFile)).EndInit();
      ((System.ComponentModel.ISupportInitialize)(this.sbSize)).EndInit();
      this.ResumeLayout(false);

    }
    #endregion

    private PictureBoxSizeMode[] ArrayMenu =
    {
      PictureBoxSizeMode.StretchImage,
      PictureBoxSizeMode.Normal, 
      PictureBoxSizeMode.CenterImage,
      PictureBoxSizeMode.AutoSize
    };
    private int selectedMode = 0;
    [STAThread]
    static void Main() 
    {
      Application.Run(new Form1());
    }

    private void mnuOpen_Click(object sender, System.EventArgs e)
    {
      OpenFileDialog diag = new OpenFileDialog();
      diag.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ;
      if (diag.ShowDialog() == DialogResult.OK)
      {
        pictureBox1.Image = new Bitmap(diag.OpenFile());
      }
    
      //Строка для вывода   во время загрузки изображения
      sbFile.Text  = "Загрузка " + diag.FileName;
      //Строка для вывода после загрузки изображения
      sbFile.Text  = "Изображение " + diag.FileName;
      //Вывод ширины (Width) и высоты (Height) изображения
      sbSize.Text= String.Format("{0:#} x {1:#}",  pictureBox1.Image.Width, pictureBox1.Image.Height);
    }

    private void mnuSave_Click(object sender, System.EventArgs e)
    {
      SaveFileDialog diag = new SaveFileDialog();
      diag.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ;
      if(diag.ShowDialog() != DialogResult.OK)
        return;
      // Получаем адрес файла.
      string filename = diag.FileName;
      FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite);
      pictureBox1.Image.Save(fs,  System.Drawing.Imaging.ImageFormat.Jpeg);
      fs.Close();
    }

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

    private void mnuResize_Click(object sender, System.EventArgs e)
    {
      if (sender is MenuItem)
      {
        MenuItem menuitem = (MenuItem)sender;
        selectedMode = menuitem.Index;
        pictureBox1.SizeMode = ArrayMenu[0];
        pictureBox1.Invalidate();
        
      }
    
    }

    private void mnuActual_Click(object sender, System.EventArgs e)
    {
      if (sender is MenuItem)
      {
        MenuItem menuitem = (MenuItem)sender;
        selectedMode = menuitem.Index;
      
        pictureBox1.SizeMode = ArrayMenu[1];
        pictureBox1.Invalidate();
        
      }
    }

    private void mnuView_Popup(object sender, System.EventArgs e)
    {
      if (sender is MenuItem) 
      {
        bool ImLoad  = (pictureBox1.Image != null);
        foreach (MenuItem menuitem in ((MenuItem)sender).MenuItems)
              {
                    menuitem.Enabled = ImLoad;
                    menuitem.Checked = (this.selectedMode == menuitem.Index);
              }
      }
      
    }

    private void mnuCenterImage_Click(object sender, System.EventArgs e)
    {
      if (sender is MenuItem)
      {
        MenuItem menuitem = (MenuItem)sender;
        selectedMode = menuitem.Index;
      
        pictureBox1.SizeMode = ArrayMenu[2];
        pictureBox1.Invalidate();
        
      }
    }

    private void mnuAutoSize_Click(object sender, System.EventArgs e)
    {
      if (sender is MenuItem)
      {
        MenuItem menuitem = (MenuItem)sender;
        selectedMode = menuitem.Index;
      
        pictureBox1.SizeMode = ArrayMenu[3];
        pictureBox1.Invalidate();
        
      }
    
    }

    private void cmnuResize_Click(object sender, System.EventArgs e)
    {
      if (sender is MenuItem)
      {
        MenuItem menuitem = (MenuItem)sender;
        selectedMode = menuitem.Index;
        pictureBox1.SizeMode = ArrayMenu[0];
        pictureBox1.Invalidate();
        
      }
      
      
    }

    private void cmnuActual_Click(object sender, System.EventArgs e)
    {
      if (sender is MenuItem)
      {
        MenuItem menuitem = (MenuItem)sender;
        selectedMode = menuitem.Index;
        pictureBox1.SizeMode = ArrayMenu[1];
        pictureBox1.Invalidate();
        
      }
    
    }

    private void cmnuCenterImage_Click(object sender, System.EventArgs e)
    {
      if (sender is MenuItem)
      {
        MenuItem menuitem = (MenuItem)sender;
        selectedMode = menuitem.Index;
        pictureBox1.SizeMode = ArrayMenu[2];
        pictureBox1.Invalidate();
        
      }
      
    }

    private void cmnuAutoSize_Click(object sender, System.EventArgs e)
    {
      if (sender is MenuItem)
      {
        MenuItem menuitem = (MenuItem)sender;
        selectedMode = menuitem.Index;
        pictureBox1.SizeMode = ArrayMenu[3];
        pictureBox1.Invalidate();
        
      }
      
    }

    private void mnuPageSetup_Click(object sender, System.EventArgs e)
    {
      PageSetupDialog diag
        = new PageSetupDialog();
      diag.Document = printDocument1;
      diag.ShowDialog();
    }

    private void mnuPreview_Click(object sender, System.EventArgs e)
    {
      PrintPreviewDialog diag
        = new PrintPreviewDialog();
      diag.Document = printDocument1;
      diag.ShowDialog();
    }

    private void mnuPrint_Click(object sender, System.EventArgs e)
    {
      PrintDialog diag = new PrintDialog();
      diag.Document = printDocument1;
      if (diag.ShowDialog() == DialogResult.OK)
      {
        printDocument1.Print();
      }
      
    }

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
      //Если в pictureBox1 не загружено изображение, возвращаемся назад
      if (pictureBox1.Image == null)
      {
        e.Cancel = true;
        return;
      }
      //Определяем печатную область страницы
      float leftMargin = e.MarginBounds.Left;
      float rightMargin = e.MarginBounds.Right;
      float topMargin = e.MarginBounds.Top;
      float bottomMargin= e.MarginBounds.Bottom;
      float printableWidth = e.MarginBounds.Width;
      float printableHeight = e.MarginBounds.Height;
      //Cоздаем экземпляр graph класса Graphics
      Graphics graph = e.Graphics;
      //Создаем экземпляр font  класса Font
      Font font= new Font("Comic Sans MS", 16);
      //Определяем высоту шрифта
      float fontHeight = font.GetHeight(graph);
      //Определяем размер пробелов 
      float spaceWidth = graph.MeasureString(" ", font).Width;
      //Определяем область, в которую будет вписываться изображение, 
      //размер наибольшей стороны изображения составляет 90% 
      //от кратчайшей стороны листа
      float imageLength;
      float Xposition = leftMargin;
      float Yposition = topMargin + fontHeight;
      if (printableWidth < printableHeight)
      {
        imageLength = printableWidth * 90/100;
        Yposition += imageLength;
      }
      else
      {
        imageLength = printableHeight * 90/100;
        Xposition += imageLength + spaceWidth;
      }
      // Выводим изображение в области rectImage
      Rectangle rectImage  = new Rectangle((int)leftMargin + 1,  (int)topMargin + 1,(int)imageLength,  (int)imageLength);
      graph.DrawImage(pictureBox1.Image,(int)leftMargin + 1,  (int)topMargin + 1, (int)imageLength,(int)imageLength);
      // Определяем область rectText и выводим в нее строку с размером файла
      RectangleF rectText  = new RectangleF(Xposition, Yposition, rightMargin - Xposition,  bottomMargin - Yposition);
      PrintText(graph, font,"Размер изображения: ", Convert.ToString(pictureBox1.Image.Size),   ref rectText);
    }
    protected void PrintText( Graphics graph,   Font font,  string name, string text,  ref RectangleF rectText)
    {
      // Определяем размеры печатной области для текста:
      float leftMargin = rectText.Left;
      float rightMargin = rectText.Right;
      float topMargin = rectText.Top;
      float bottomMargin = rectText.Bottom;
      //Определяем высоту текста и координаты, где он будет выводиться:
      float fontHeight = font.GetHeight(graph);
      float Xposition = rectText.Left;
      float Yposition = topMargin + fontHeight;
      //Определяем ширину текста и размер пробелов
      float spaceWidth = graph.MeasureString(" ",   font).Width;
      float nameWidth  = graph.MeasureString(name, font).Width;
      graph.DrawString(name, font,
      Brushes.Black, new PointF(Xposition, Yposition));
      leftMargin += nameWidth + spaceWidth;
      Xposition = leftMargin;
      // Формируем несколько строк для текста  в случае,
      // если он не будет умещаться на одной строке
      string[] words
        = text.Split(" \r\t\n\0".ToCharArray());
      foreach (string word in words)
      {
        float wordWidth = graph.MeasureString(
          word, font).Width;
        if (wordWidth == 0.0)
          continue;
        if (Xposition + wordWidth > rightMargin)
        {
          // Начало с новой строки
          Xposition = leftMargin;
          Yposition += fontHeight;
          if (Yposition > bottomMargin)
          {            
            break;
          }
        }
        graph.DrawString(word, font,Brushes.Black,  new PointF(Xposition, Yposition));
        Xposition += wordWidth;
      }
      // Исключаем область, на которую был выведен текст, из области печати 
      //для избежания наложения текста и рисунка
      rectText.Y = Yposition;
      rectText.Height = bottomMargin - Yposition;
  
    }
  }
}
Листинг 6.14.
Елена Дьяконова
Елена Дьяконова

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

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

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

Затем:

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

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

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

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

Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000