С# для Windows

К началу раздела

Глава 5. Вывод текстовой информации


В начало

Параграф 1. Вывод текстовой информации в контрол Label


В начало

Для вывода текстовой информации наиболее часто применяются контролы Label и TextBox, которые мы уже использовали в параграфе "Простейший Windows Application проект". Контрол TLabel предназначен для вывода однострочной текстовой информаци и имеет стандартный набор свойств и методов, большинство из которых прозрачны или описаны в предыдущих параграфах.

Отметим, что в контрол можно помещать не только текст, но, чего нет в Delphi и Borland C++ Builder, и рисунки, аналогично, как это мы делалали для кнопок - он имеет такойже набор свойств(Image, ImageAlign, ImageList).

Интересным является свойство UseMnemonic, позволяющее определить, как будет интерпретироваться символ амперсанда (&), размещенный в свойстве Text. Если установлено значение True, то амперсанд из текста удаляется, а символ, перед которым он расположен, подчеркивается. Эта возможность применяется для определения клавиш быстрого доступа для выбора именно контрола Label - пользователь может комбинацией клавиш <А1t>+<подчеркнутая клавиша в метке> устанавливать фокус на контрол, а затем, используя клавишу Tab, на контрол, следующий по таб номеру за контролом Label. Например, если в форме расположено несколько контролов, среди которых имеется текстовое поле, в которое необходимо перейти нажатием клавиши быстрого доступа, то достаточно установить свойства Tabindex метки и текстового поля так, чтобы для метки это значение было на единицу меньшее, чем у текстового поля. Теперь, в программе, Вы можете выбрать клавишами быстрого доступа метку и, далее, нажать клавишу Tab - будет выбрано текстовое поле для ввода информации.

Вывод текста в контрол не вызывает трудностей, для этого контрол имеет свойство Text:

label1.Text="My Text";

Параграф 2. Вывод текстовой информации в контрол TextBox


В начало

2.1. Основные свойства TextBox

Контрол TextBox мы пока использовали для ввода и вывода однострочного текста, однако он болле предназначен именно для ввода и вывода многострочного текста. Для этого у него есть свойство Multiline, которое должно быть установлено в True.

Cвойства AcceptsTab и AcceptsReturn определяют действие при нажатии клавиш Tab и Enter, при False (по умолчанию) и при нажатии Tab или Enter осуществляется переход фокуса к следующему по TabIndex контролу, при True - клавиши выполняют основное свое назначение - вставка разрыва табуляции и перевод строки соответственно.

Cвойство AutoSize определяет, нужно ли автоматически изменять размеры конрола, чтобы в нем можно было разместить его содержимое.

Свойство CharacterCasing определяет регистр в котором будут отображаться техт в контроле.

Свойство HideSelection целесообразно установить в False - в противном случае выделенный программно текст не будет отображаться.

Свойство Locked определяет может ли пользователь изменять свойства TextBox программно.

Свойство ScrollBars показывает положение полос прокрутки - при Both полоса прокрутки появляется при выходе текста за соответствующую границу.

Свойство PasswordChar (работает только при Multiline=false) не дает возможности просматривать вводимые символы, заменяя их на привычные для ввода пароля звездочки или другой символ, указанный в этом поле.

Свойство WordWrap при True разрешает перенос текста на новую строку при ширене строки текста более ширины окна.


В начало

2.2. Программный вывод текста в TextBox

Создадим проект решения для вывода текстовой информации с контролом TrxtBox, показанный на Рис.1.

fieldsoutput001.gif

Рис.1. Проект решения для вывода текстовой информации

Создание кнопочной панели, меню и панели статуса уже рассмотрены в предыдущих параграфах раздела, поэтому здесь приводятся лиш коды обработчиков событий для кнопок. У кнопок установлено свойство Tag соответственно в 1, 2 и 3 и события MouseHover и MouseLeave для всех кнопок замкнуты на toolStripButton1_MouseHover и toolStripButton1_MouseLeave. Для вывода подсказок использован контрол toolStrip, а для вывода подсказок в панель статуса StatusStrip и соответствующий код (все тонкости описаны в предыдущих параграфах).

private void toolStripButton1_MouseHover(object sender, EventArgs e)
{
 int i = Convert.ToInt32((sender as ToolStripButton).Tag);
 switch (i)
 {
  case 1:
    toolStripStatusLabel1.Text = "Output Text";
  break;
  case 2:
    toolStripStatusLabel1.Text = "Delete String";
  break;
  case 3:
    toolStripStatusLabel1.Text = "Close Form";
  break;            
 }
}
private void toolStripButton1_MouseLeave(object sender, EventArgs e)
{
 toolStripStatusLabel1.Text = "";
}

Прежде чем выводить текст программно, нажмем кнопочку с тремя точками в свойстве Lines (вызов String Coleection Editor) и выведем несколько строк текста с клавиатуры. После нажатия кнопочки OK видим, что текст появился в окне контрола и в свойстве Text. Это говорит о том, что текст можно выводить как в свойство Text, так и использовать свойство Lines (String[] Array). Обратим внимание, что в свойстве Text присутствуют два нечитаемых символа - это \r и \n - перевод строки и возврат каретки. К сожалению, из за этого, придется при редактировани текста учитывать наличие этих символов. У свойства Lines нет методов Add и Delete для строк, что также создает дополнительные трудности при редактировании текста.

Перед началом манипулирования с текстом определим статическую переменную viNom в декларационной части кода:

public partial class Form1 : Form
{
 private static int viNom=0;
 .....

Следующие коды обработчиков событий нажатия для кнопок показывают возможности редактирования многострочного текста. Раскоментируйте интересующий Вас способ.

toolStripButton1_Click(object sender, EventArgs e)
{
 ////Вывод текста в одну строку
 //textBox1.Text+=" Text "+(Convert.ToInt32(viNom)).ToString();
 viNom++;			
 ////Первый способ вывода многострочного текста
 //textBox1.Text+="Строка  "+(Convert.ToInt32(viNom)).ToString()+"\r\n";
 //viNom++;
 //textBox1.Text += "Строка  " + (Convert.ToInt32(viNom)).ToString() + "\r\n";
 ////Второй способ вывода многострочного текста
 //textBox1.AppendText("Строка "Convert.ToString(viNom)+"\r\n");
 //viNom++;
 //textBox1.AppendText("Строка " + Convert.ToString(viNom) + "\r\n");
 ////Третий способ вывода многострочного текста
 //textBox1.Text = "Строка  1" + System.Environment.NewLine + "Строка 2";
 ////Четвертый способ вывода многострочного текста 
 //(требует подключения using System.IO)
 //System.IO.StringWriter writer = new System.IO.StringWriter();
 //writer.WriteLine("Строка 1");
 //writer.WriteLine("Строка 2");
 //textBox1.Text += writer.ToString();
 ////Пятый способ вывода многострочного текста 
 //textBox1.Lines = new string[]{"Строка 1", "Строка 2"};
 //Добавляем строку к любому методу
 //textBox1.AppendText(Environment.NewLine+"Строка 3"); 
}
private void toolStripButton2_Click(object sender, EventArgs e)
{		
 string sLine;
 String sSearchString;
 try
 {
  sSearchString=textBox1.Lines[0].ToString();					
 }
 catch
 {
  //Удалять нечего
  return;
 }
 //Отобразим в заголовке окна удаляемый текст
 this.Text=sSearchString;
 //Можно удалить все		    
 //textBox1.SelectAll();
 //textBox1.Cut();
 //Если знаем, что удалять будем именно первую строку
 textBox1.SelectionStart = 0;
 //Длина +2 - запас на \r\n
 textBox1.SelectionLength=sSearchString.Length+2;
 if(textBox1.SelectionLength > 0) 
 {
  MessageBox.Show(this,
    "Есть выделенный текст он = "+textBox1.SelectedText);	
  //И далее просто удалить
  textBox1.Cut();
 }
 //Если удалить надо по содержимому 
 sSearchString="Строка 2";			
 int index=-1;
 for(int i=0;i < textBox1.Text.Length-sSearchString.Length;i++)
 {
  index = textBox1.Text.IndexOf(sSearchString,i,sSearchString.Length);
  if(index != -1) break;
 }			  
 if(index != -1)
 {
  //Можно выделить и так
  textBox1.Select(index,index+sSearchString.Length+2);
  textBox1.Cut();
 }
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
  Application.Exit();
}

Нажимаем F5 и можем добавлять и удалять строки в TextBox.

fieldsoutput002.gif

Рис.2. Демонстрация добавления и удаления строк

Удалять строки можно и так (ровно как добавлять и вставлять):

if(textBox1.Lines.Length > 0)
{
 string[] vsS = textBox1.Lines;
 string[] vsS1 =new string[vsS.Length-1];
 textBox1.Text = "";
 //Удаляем нулевую строку
 for(int i=0; i < vsS.Length-1; i++)
 {
     vsS1[i]=vsS[i+1];
 }
 textBox1.Lines = vsS1;
}
else
{
 //Удалять нечего
 return;
}


В начало

Параграф 3. Ввод/Вывод текстовой информации в контрол TextBox из/в файл(а)


В начало

3.1. Классы для работы с текстовыми файлами

Для работы с текстовыми файлами удобно использовать потоки и класс потоков, наследника класса Stream - Класс FileStream.

Класс FileStream используется для чтения и записи файлов. Его можно использовать для чтения и записи байтов, символов, строк и других типов данных. Класс FileStream поддерживает синхронное и асинхронное открытие файлов, синхронные операции чтения и записи (методы Read и Write), а также асинхронные операции чтения и записи (методы BeginRead и BeginWrite). Асинхронные операции завершаются вызовом методов EndRead и EndWrite соответственно. Режим по умолчанию - синхронный. Для проверки режима используемтсясвойство класса IsAsync. Для асинхронных операций необходим объект WaitHandle. Метод Seek используется для произвольного доступа к файлам. Свойство Position позволяет нам узнать или установить текущую позицию в потоке. Методы Lock и Unlock служат для предотвращения доступа ко всему файлу или к его части, а также для отмены ранее установленного запрета доступа. Свойство Length возвращает длину потока в байтах, а метод SetLength служит для задания длины потока. Методы ReadByte и WriteByte используются для чтения и записи одного байта. Для других примитивных типов необходимы классы BinaryReader и BinaryWriter соответственно.

Удобно использовать для работы с текстовыми файлами в дополнение к классу FileStream классы TextReader, TextWriter StreamReader, StreamWriter, StringReader и StringWriter.

Класс TextReader используется для чтения последовательности символов из ассоциированного потока. Этот класс служит основой для двух других классов: StreamReader и StringReader.

Класс TextReader содержит следующие методы:

  • Peek() - возвращает следующий символ из потока, но не перемещает указатель текущей позиции;

  • Read() или Read(Char(), Integer, Integer) - метод применяется для чтения указанного числа символов из потока;

  • ReadBlock(Char(), Integer, Integer) - метод считывает указанное число символов в буфер;

  • ReadLine() - считывает строку символов из потока;

  • ReadToEnd() - считывает все символы с текущей позиции до конца потока как одну строку.

Класс TextWriter служит для записи последовательности символов в поток.

Класс StreamReader применяется для чтения последовательности символов из файла или другого потока. Его можно использовать для чтения текстового файла построчно и как одну строку.

Класс StringReader позволяет выполнить чтение символов из строк. StreamReader и StringReader для чтения строки из текстового файла и чтения символов из этой строки как из потока:

Класс StreamWriter применяется для вывода последовательности символов в той или иной кодировке. По умолчанию используется экземпляр класса UTF8Encoding для записи символов в кодировке Unicode UTF-8. Существует несколько перегруженных конструкторов, позволяющих указать поток, кодировку по умолчанию, задать кодировку, размер буфера и тип операции: требуется перезаписать существующий файл или информация должна быть к нему добавлена. Свойство Flush служит для указания, следует ли записывать содержимое буфера в поток после каждого вызова методов Write и WriteLine.

Класс StringWriter используется для записи строки, которая хранится в классе StringBuilder, реализованном в пространстве имен System.Text.


В начало

3.2. Ввод/Вывод текстовой информации

Покажем возможные способы использования перечисленных классов для ввода и вывода информации в TextBox.

Используем для реализации проект решения из предыдущего параграфа. Для чего уберем имеющийся код из обработчиков toolStripButton1_Click и toolStripButton2_Click. При желании можем изменить тексты подсказок и картинки для button1 и button2 и заглавие проекта.

В обработчики нажатия кнопок toolStripButton2_Click и toolStripButton2_Click запишем следующий код:

// ЗАПИСЬ В ФАЙЛ СОДЕРЖИМОГО textBox1
private void toolStripButton1_Click(object sender, EventArgs e)
{
 //Создаем поток для записи в файл и загружаем в него файл
 //при отсутствии файла он будет создан
 FileStream filestream = 
   new FileStream("a.txt",FileMode.OpenOrCreate,FileAccess.Write);
 //Очищаем поток
 filestream.SetLength(0);
 //StreamWriter создаем для потока filestream
 StreamWriter streamwriter = new StreamWriter(filestream);         
 //Записываем текст, введенный в textBox1 в файл
 streamwriter.Write(textBox1.Text);
 //Освобождаем ресурсы
 streamwriter.Flush();
 streamwriter.Close();
 filestream.Close();  
}
//ЧТЕНИЕ СОДЕРЖИМОГО ФАЙЛА И ВЫВОД В  textBox1
private void button2_Click(object sender, EventArgs e)
{		
 string sFileText;
 FileStream filestream = new FileStream("a.txt",
          FileMode.OpenOrCreate,FileAccess.Read);
 //StreamReader создаем для потока filestream
 StreamReader streamreader = new StreamReader(filestream);
 //Буфер для прочитанной информации
 char[] chBuf = new char[filestream.Length];
 //Чтения файла в буфер начиная с позиции 0
 streamreader.ReadBlock(chBuf,0,(int)filestream.Length);
 sFileText = new string(chBuf); 
 textBox1.Text+=sFileText;
 //Освобождаем ресурсы
 filestream.Close();
 streamreader.Close();
}

Проверим в заголовке наличие кода using System.IO; :

После выполнения программы введенный в контрол TextBox текст будет записан в файл по нажатию toolStripButton1_Click и добавлен к введенному из файла по нажатию toolStripButton2_Click.

Следующий код (изменим обработчик для кнопки 2) позволяет вывести текст по линиям. На этом принципе может быть также основан вывод конкретной строки текста.

private void toolStripButton2_Click(object sender, EventArgs e)
{		
 string sStringText;
 string sFileName="a.txt";			
 TextReader textreader = new StreamReader(sFileName);
 bool fF=false;
 textBox1.Text="";
 while(textreader.Peek() > -1)
 {
  sStringText=textreader.ReadLine();			
  if(fF)
   textBox1.Text+="\r\n"+sStringText;
  else
   textBox1.Text+=sStringText;
  fF=true;
 }
textreader.Close();
}

Когда необходимо чтение всего текста, то код можно упростить.

private void toolStripButton2_Click(object sender, EventArgs e)
{		
 string sStringText;
 string sFileName="a.txt";			
 TextReader textreader = new StreamReader(sFileName);
 textBox1.Text="";
 sStringText=textreader.ReadToEnd();	
 textBox1.Text+=sStringText;
 textreader.Close();
}

Изменим теперь обработчик для кнопки 1

private void toolStripButton1_Click(object sender, EventArgs e)
{
 string sFileName="a.txt";			
 StreamWriter streamwriter = new StreamWriter(sFileName);
 //Первая строка
 streamwriter.WriteLine("My Strings!!");
 //Вторая строка
 streamwriter.WriteLine(textBox1.Text);
 streamwriter.Close();
}

Теперь при запуске прграммы мы можем ввести какой либо текст в TextBox и, далее, после нажатия последовательно кнопок 1 и 2 его вывести c заголовком ("My Strings!!"). Этот код показывает как можно добавлять строки в текстовый файл.

Добавим в заголовок решения строку:

//Эта уже добавлена
using System.IO;
using System.Text;

Изменим текст обработчика кнопки 1 для вывода чисел в текстовый файл:

private void toolStripButton1_Click(object sender, EventArgs e)
{
 Int64 viI;
 try 
 {
  //Открываем файл при true - добавление при false - поток очищается
  StreamWriter streamwriter = new StreamWriter
                ("a.txt", false, Encoding.ASCII);				
  for(viI=0; viI < 10; viI++)
  {
   //Вывод на одной линии
   streamwriter.Write(viI);
   //Вывод каждой цифра на новой линии
   streamwriter.WriteLine(viI);
  } 
  streamwriter.Close();
 }
 catch
 {
 }

Результат после последовательного нажатия кнопок 1 и 2:

00
11
22
33
44
55
66
77
88
99


В начало

Параграф 4. Вывод текстовой информации в контрол RichTextBox


В начало

4.1. Основные свойства RichTextBox

Вначале изменим предыдущее решение удалив коды обработчиков событий нажатия Button1 и Button2, удалим контрол TextBox и на его место поместим контрол RichTextBox. Рассмотрим его свойство на страничке Properties. Большинство свойст аналогичны описанным ранее для уже рассмотренных контролов. Рассмотрим те свойства, которых не было у уже использованных нами контролов.

Свойство AcceptButton позволяет закрепить кнопку, клик которой будет выполняться при нажатии Enter когда RichTextBox в фокусе (например после ввода).

WordSelection если свойство true, пользователь может, двойным щелчком на любой части слова в контроле сделать его выделенным.

BulletIndent и SelectionBullet - BulletIndent определяет отступ в пикселях текста перечислений (пунктов списка) от иконки соответствующей пункту списка при значении свойства SelectionBullet=true.

Пример из Help С#:

private void toolStripButton1_Click(object sender, EventArgs e)
{
 // Очистить все
 richTextBox1.Clear();
 richTextBox1.SelectionBullet = true;
 // Устанавливаем отступ в пикселях для пунктов списков
 richTextBox1.BulletIndent = 50;			
 richTextBox1.SelectionFont = new Font("Arial", 16);
 //Выводим текст на который не влияет установленный 
 //отступ (SelectionBullet=false)
 richTextBox1.SelectedText = "Ниже список\n";			
 richTextBox1.SelectionFont = new Font("Arial", 12);	
 //Далее список
 richTextBox1.SelectionBullet = true;
 richTextBox1.SelectionColor = Color.Red;
 richTextBox1.SelectedText = "Яблоко" + "\n";			
 richTextBox1.SelectionFont = new Font("Arial", 12);
 richTextBox1.SelectionColor = Color.Orange;
 richTextBox1.SelectedText = "Апельсин" + "\n";
 richTextBox1.SelectionFont = new Font("Arial", 12);
 richTextBox1.SelectionColor = Color.Purple;
 richTextBox1.SelectedText = "Виноград" + "\n";			
 richTextBox1.SelectionBullet = false;
 richTextBox1.SelectionFont = new Font("Verdana", 10);
 richTextBox1.SelectedText = "Список закончился\n";
}

Результат вывода:

fieldsoutput003.gif

Рис.3. Свойства SelectionBullet и BulletIndent.

Свойство DetectUrls позволяет распозновать и выделять интернетовские ссылки и запускать браузер по этой ссылке при наличии в решении кода обработчика события LinkClicked следующего вида (Рис.4.):

private void toolStripButton3_Click(object sender, EventArgs e)
{
 richTextBox1.Text = "Мой сайт http:\\wladm.narod.ru";            
}
private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
{
 System.Diagnostics.Process.Start(e.LinkText);
}

fieldsoutput004.gif

Рис.4. Использование свойства DetectUrls

Свойство ZoomFactor позволяет одновременно изменять масштаб вывода текста в RichTextBox в пределах значений 0.64 - 64.0.

Свойство Ime Mode задает или возвращает состояние IME (Input Method Editor - IME - редактор способа ввода). Вместе со свойством RightToLeft определяют направление текста и способ его редактирования (свойства не актуальны для европейских языков, в том числе и для русского) - более необходимы при вводах иероглифических текстов на китайском, арабском, корейском и японском языках (при соответствующих Windows).

Значение по умолчанию NoControl.

Все остальные свойства richTextBox повторяют свойства TextBox.


В начало

4.2. Программный вывод текста в RichTextBox

В начале параграфа мы поместили контрол RichTextBox на форму.

Все свойства контрола пока оставим принятые по умолчанию. Свойства остальных контролов оставим без изменения - проект решения выглядит аналогично показанному на Рис.1. При удалении контрола требуется только удалить коды обработчиков нажатия кнопок 1 и 2.

Так как свойство Lines у RichTextBox и TextBox, то следует предположить, что ввод и вывод информации в контрол ничем не отличимы в обоих контролах - достаточно заменить имена, как показано далее в обработчиках toolStripButton1_Click и toolStripButton2_Click.

private void toolStripButton1_Click(object sender, EventArgs e)
{
 //int viNom = 0;
 //Вывод текста в одну строку
 //richTextBox1.Text += " Text " + (Convert.ToInt32(viNom)).ToString();
 //viNom++;
 ////Первый способ вывода многострочного текста
 //richTextBox1.Text+="Строка  "+(Convert.ToInt32(viNom)).ToString()+"\r\n";
 //viNom++;
 //richTextBox1.Text += "Строка  " + (Convert.ToInt32(viNom)).ToString() + "\r\n";
 ////Второй способ вывода многострочного текста
 //richTextBox1.AppendText("Строка "Convert.ToString(viNom)+"\r\n");
 //viNom++;
 //richTextBox1.AppendText("Строка " + Convert.ToString(viNom) + "\r\n");
 ////Третий способ вывода многострочного текста
 //richTextBox1.Text = "Строка  1" + System.Environment.NewLine + "Строка 2";
 ////Четвертый способ вывода многострочного текста 
 //(требует подключения using System.IO)
 //System.IO.StringWriter writer = new System.IO.StringWriter();
 //writer.WriteLine("Строка 1");
 //writer.WriteLine("Строка 2");
 //richTextBox1.Text += writer.ToString();
 ////Пятый способ вывода многострочного текста 
 //richTextBox1.Lines = new string[]{"Строка 1", "Строка 2"};
 //Добавляем строку к любому методу
 //richTextBox1.AppendText(Environment.NewLine+"Строка 3"); 
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
 string sLine;
 String sSearchString;
 try
 {
  sSearchString=richTextBox1.Lines[0].ToString();					
 }
 catch
 {
  //Удалять нечего
  return;
 }
 //Отобразим в заголовке окна удаляемый текст
 this.Text=sSearchString;
 //Можно удалить все		    
 //richTextBox1.SelectAll();
 //richTextBox1.Cut();
 //Если знаем, что удалять будем именно первую строку
 richTextBox1.SelectionStart = 0;
 //Длина +2 - запас на \r\n
 richTextBox1.SelectionLength=sSearchString.Length+2;
 if(richTextBox1.SelectionLength > 0) 
 {
  MessageBox.Show(this,
   "Есть выделенный текст он = "+richTextBox1.SelectedText);	
  //И далее просто удалить
  richTextBox1.Cut();
  }
  //Если удалить надо по содержимому 
  sSearchString="Строка 5";			
  int index=-1;
  for(int i=0;i < richTextBox1.Text.Length-sSearchString.Length;i++)
  {
   index = richTextBox1.Text.IndexOf(sSearchString,i,sSearchString.Length);
   if(index != -1) break;
  }			  
  if(index != -1)
  {
   //Можно выделить и так
   richTextBox1.Select(index,index+sSearchString.Length+2);
   richTextBox1.Cut();
 }
}

Коды обсолютно одинаковы и работают аналогично (Рис.2.). Все отличие контролов в формате текста .rtf и .txt. RichTextBox, как мы это видели при описании свойств контрола, позволяет менять шрифты, и характеристики шрифтов, отступы, использовать интернет ссылки и т.п.

Но прежде чем перейти к рассмотрению всех этих возможностей приведем еще один код (подходит и для работы с TextBox), который позволяет удалять строки несколько иначе и показывает, что с RichTextBox это, в отношении хранения информации - такойже массив как и string[]:

private void toolStripButton2_Click(object sender, EventArgs e)
{
 string sText;
 try
 {
  sText = richTextBox1.Lines[0];
 }
 catch
 {
  //Удалять нечего
  return;
 }
 //sText.Length+1 - для учета перехода на новую строку
 richTextBox1.Select(richTextBox1.Find(sText),sText.Length+1);
 //Если HideSelection=true то позволяет увидеть выделенное программно
 richTextBox1.Focus();
 //Удаляем строку
 richTextBox1.Cut();
 string[] sTextLines = richTextBox1.Lines;
 //Сохраняем строки в массиве
 for(int i = 0; i < sTextLines.Length; i++) 
 {
  string sTextLine = sTextLines[i];
  sTextLines[i] = sTextLine;
 }
 //убираем все строки
 richTextBox1.Clear();
 //Внови помещаем сохраненные в sTextLines строки в RichTextBox
 richTextBox1.Lines = sTextLines;
}


В начало

4.3. Использование шрифтов в RichTextBox

Изменим обработчик для кнопки 1 так, чтобы выводимые строки меняли свой шрифт при выводе очередной строки.

private void toolStripButton1_Click(object sender, EventArgs e)
{
 richTextBox1.Clear();
 string sText1,sText2,sText3,sText4,sText5;
 for(int i=1; i <= 5; i++)
 {
  richTextBox1.Text+="Cтрока "+(Convert.ToInt32(i)).ToString()+
   System.Environment.NewLine ;
 }
 //Копии введенных строк
 sText1="Cтрока "+(Convert.ToInt32(1)).ToString();
 sText2="Cтрока "+(Convert.ToInt32(2)).ToString();
 sText3="Cтрока "+(Convert.ToInt32(3)).ToString();
 sText4="Cтрока "+(Convert.ToInt32(4)).ToString();
 sText5="Cтрока "+(Convert.ToInt32(5)).ToString();
 richTextBox1.Select(richTextBox1.Find(sText1),sText1.Length);
 richTextBox1.SelectionFont = new Font("Arial", 
         10,System.Drawing.FontStyle.Regular);
 richTextBox1.SelectionColor = Color.Red;
 richTextBox1.Select(richTextBox1.Find(sText2),sText2.Length);			
 richTextBox1.SelectionFont = new Font("Arial", 
         12,System.Drawing.FontStyle.Underline);
 richTextBox1.SelectionColor = Color.Blue;
 richTextBox1.Select(richTextBox1.Find(sText3),sText3.Length);
 richTextBox1.SelectionFont = new Font("Arial", 
         14,System.Drawing.FontStyle.Bold);
 richTextBox1.SelectionColor = Color.Aqua;
 richTextBox1.Select(richTextBox1.Find(sText4),sText4.Length);
 richTextBox1.SelectionFont = new Font("Arial", 
	      16,System.Drawing.FontStyle.Bold | 
                   System.Drawing.FontStyle.Italic);
 richTextBox1.SelectionColor = Color.Cyan;
 richTextBox1.Select(richTextBox1.Find(sText5),sText5.Length);
 richTextBox1.SelectionFont = new Font("Arial", 18,
	System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic
	 | System.Drawing.FontStyle.Strikeout);
 richTextBox1.SelectionColor = Color.Brown;
 //Убираем выделение
 richTextBox1.SelectionStart=0;
 richTextBox1.SelectionLength=0;
}

Результат выполнения кода представлен на Рис.4.

fieldsoutput005.gif

Рис.5. Задание параметров шрифтов для строк

Обратм внимание, что любая попытка добавить текcт обычным образом приведет у тому, что весь текст отобразится шрифтом, установленным в свойстве Font RichTextEdit.

В приведенном выше коде показно как добавить составляющую в стиль шрифта. Но соствляющие можно также и убирать. Добавим в конец предыдущего кода фрагмент:

 FontStyle fs;
 //Вновь выделяем строку
 richTextBox1.Select(richTextBox1.Find(sText5),sText5.Length);
 //Запоминаем стиль шрифта
 fs=richTextBox1.SelectionFont.Style;
 //Убираем зачеркивание
 fs = fs & ~System.Drawing.FontStyle.Strikeout; 
 richTextBox1.SelectionFont = new Font("Arial", 18,fs);
 richTextBox1.SelectionStart=0;
 richTextBox1.SelectionLength=0;

Результат - перечеркивания в пятой строке исчезло.


В начало

4.4. Работа со строками в RichTextBox

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

Отметим сразу, что привычных для программистов методов, напрямую добавляющих, удаляющих или вставляющех строки в C# для RichEditBox, ровно как и для TextBox, нет. Как результат приходится работать через Clipboard. (Наличие метода Insert у свойства Text пусть никого не обольщает, его малая результативность будет показана чуть ниже).

Изменим код в обработчике toolStripButton1_Click:

private void toolStripButton3_Click(object sender, EventArgs e)
{
 int viNom = 0;
 richTextBox1.Lines = new string[] { "Строка 1", 
   "Строка 2","Строка 3","Строка 4","Строка 5"};

 //Выделяем строку 5
 richTextBox1.Select(richTextBox1.Find("Строка 5"), richTextBox1.Lines[4].Length);
 //Копируем выделенное в буфер
 richTextBox1.Copy();
 //Ищем начало строки
 viNom = richTextBox1.Find("Строка 2");
 //Создаем DataObject тождественный объекту в буфере
 DataObject dataobject = (DataObject)Clipboard.GetDataObject();
 //Выделяем строку
 richTextBox1.SelectionStart = viNom;
 richTextBox1.SelectionLength = 0;
 //Вставляем перед ней строку из буфера
 richTextBox1.SelectedRtf = (String)dataobject.GetData(DataFormats.Rtf);
}

Результат видим на Рис.6.(слева).

Если вместо строчки кода

richTextBox1.SelectionLength=0;

вставить

richTextBox1.SelectionLength=richTextBox1.Lines[1].Length;

Или вообще ее убрать, то строка 5 заместит строку 2 (Рис.6. справа).

fieldsoutput006.gif

Рис.6. Манипулирование строками в RichTextBox

Теперь о методе Insert. Рассмотрим фрагмент кода, который добавим в конец фрагмента кода, где мы экспирементировали со шрифтами:

string[] srgText = new string[richTextBox1.Lines.Length];
srgText = richTextBox1.Lines;
richTextBox1.Clear();
for (int i = 0; i < srgText.Length; i++)
{
 richTextBox1.Text =
  richTextBox1.Text.Insert(0, srgText[i] + "\r\n");
}

Все хорошо (Рис.7.) - строки поменяльсь местами и вставлена строка в нулевую позицию, но все форматирование исчезло. Причина - Text и отформатированный текст не одно и тоже. Текст хранится в свойстве Lines по строчно и в свойстве текст одной строкой, а отформатированный и отображаемый текст в формате Rtf в свойстве SelectedRtf.

fieldsoutput007.gif

Рис.7. Манипулирование строками в RichTextBox

Нетрудно посмотреть причину этого - достаточно добавить перед последнем вставленным фрагментом и в конце его код:

System.Diagnostics.Debug.WriteLine(richTextBox1.Rtf);

и посмотреть результат в окне отладчика и сравнить коды (меню View/Output).

Зная формат нетрудно найти все, что было введено при форматировании и потерялось при присвоении.

Можно попробовать осуществить манипуляцию строками через посредника, например richTextBox2.

System.Windows.Forms.RichTextBox richTextBox2;
richTextBox2 = new System.Windows.Forms.RichTextBox();
richTextBox2.Clear();
string sText1=richTextBox1.Lines[1];		
richTextBox1.Select(richTextBox1.Find(sText1),sText1.Length);
richTextBox2.Font=richTextBox1.SelectionFont;
richTextBox2.Text=sText1;
richTextBox1.Text=
richTextBox1.Text.Insert(0,richTextBox2.Text);

Однако и это ничего хорошего не дает - при присвоении теряются форматы всех строк кроме первой, который становится форматом всего текста.


В начало

4.5. Файловый ввод/вывод RichTextBox

Рассмотрим фрагмент кода, который, как и прежде, поместим в конец кода обработчика toolStripButton3_Click:

richTextBox1.SaveFile("a.rtf",RichTextBoxStreamType.RichText);
richTextBox1.Clear();
richTextBox1.LoadFile("a.rtf",RichTextBoxStreamType.RichText);

При запуске текст пишется из контрола в файл и читается из него в контрол благодаря наличию методов SaveFile и LoadFile. Причем формат тексты сохраняется.

Как и большинства функций C# функции SaveFile и LoadFile перегружаемые и можно напрямую указать формат текста, например:

richTextBox1.SaveFile("a.rtf",RichTextBoxStreamType.RichText);
richTextBox1.LoadFile("a.rtf",RichTextBoxStreamType.RichText); 

Молчанов Владислав 15.07.2004г.

Адаптировано к VS 2005 11.11.2006г.

Еcли Вы пришли с поискового сервера - посетите мою главную страничку

На главной странице Вы найдете программы комплекса Veles - программы для автолюбителей, программы из раздела графика - программы для работы с фото, сделанными цифровым фотоаппаратом, программу Bricks - игрушку для детей и взрослых, программу записную книжку, программу TellMe - говорящий Русско-Английский разговорник - программу для тех, кто собирается погостить за бугром или повысить свои знания в английском, теоретический материал по программированию в среде Borland C++ Builder, C# (Windows приложения и ASP.Net Web сайты).

На главную страницу

В начало страницы

К началу раздела

К началу книги


Сайт управляется системой uCoz