Глава 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. Вывод текстовой информации в контрол TextBox2.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.
Рис.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.
Рис.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 содержит следующие методы:
Класс 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. Вывод текстовой информации в контрол RichTextBox4.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";
}
Результат вывода:
Рис.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);
}
Рис.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.
Рис.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. справа).
Рис.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.
Рис.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 сайты). |