Search This Blog

2011-11-10

C#: Text Highlighting in RichTextBox

RichTextBox -той харьцаж байхдаа хайлт хийх эсвэл онцгой шаардлагатай үгсийг бусдаас ялган тодотгох шаардлагатай үе гардаг. Энэ үед яаж зохицуулах вэ? Үүнийг яаж зохицуулах талаар олж мэдсэнээ та бүхэнтэй хуваалцъя.

Гол санаа нь идэвхтэй мөр болгоны эхлэл болон төгсгөлыг олж, уг мөрөнд тодруулах шаардлагатай үг орсон эсэхийг хайна. Хэрэв тийм үг олдвол тухайн үгийг бусдаас ялган будсанаар бидний зорилго биелэх юм.
int currentLineStart = 0; 
int currentLineLength = 0;
int currentLineEnd = 0;
Regex regKeyWords = new Regex("int|foreach|while|hello", RegexOptions.IgnoreCase);
        
[DllImport("user32.dll")]
public extern static bool LockWindowUpdate(IntPtr WndLock);
regKeyWords нь бидэнд шаардлагатай түлхүүр үгсийг хадгалж байх бөгөөд харьцуулалт хийхэд хэрэглэгдэх юм. Regex класс нь хайлт хийх, текстыг харьцуулахад нэн тохиромжтой.
Regex классыг ашиглахын тулд доорх мөр кодыг програмдаа оруулж өгсөн байх шаардлагатай.
using System.Text.RegularExpressions;
Энэ жишээнд авснаар "int, foreach, while, hello" эдгээр нь бидний тодруулах ёстой үгнүүд болно.
Илүү дэлгэрэнгүйг мэдээллийг  Regex.

[DllImport("user32.dll")]
public extern static bool LockWindowUpdate(IntPtr WndLock);
Мөр болгоныг эхнээс нь шалгах учраас өмнө нь тодруулсан эсэхээс үл хамааран шаардлагатай үгийг ахин буддаг. Энэ нь текстэнд өөрчлөлт орох болгонд өнгө нь ахин дахин солигддог ба ингэж гялалзах нь нүдийг амархан ядрааж болно. Үүнийг арилгах үүднээс дээрх 2 мөр кодыг ашиглана.
         LockWindowUpdate функц нь өгөдсөн програмын хэсгийг түгжиж өмнөх зүйлд өөрчлөлт орохоос хамгаалдаг. Үүнийг ашиглаад шаардлагатай үгээ будхын өмнө richtextbox -оо түгжвэл өмнө будагдсан үгийг ахин будахаас зайлсхийх юм.
user32.dll файлыг дээрх үзүүлсэн байдлаар хэрэглэх нь програм ажиллаж байх үед дуудагдах учраас үүнийг дэмжих namespace -г мөн програмдаа оруулж өгөх хэрэгтэй. Доорх мөр код энэ үйл ажиллагааг дэмжинэ.
 using System.Runtime.InteropServices;

Одоо яаж идэвхтэй мөрийн эхлэл болон төгсгөлийг олохыг үзье. Ингэхдээ TextChanged төлвийг ашиглаад хийе.
Доорх кодыг RichTextBox -нхоо text changed төлөв дээр бичиж өгөх хэрэгтэй. Ингэснээр үг, үсэг нэмэгдэх болгонд шалгалт хийгдэх ба шаардлагатай бол тодруулна.
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
   int currentSelectionStart = richTextBox1.SelectionStart;
   string currentLine;

   //Идэвхтэй байгаа мөрийн эхлэлийг олох
   currentLineStart = currentSelectionStart;
   while (currentLineStart > 0 && richTextBox1.Text[currentLineStart - 1] != '\n')
      currentLineStart--;

   //Идэвхтэй байгаа мөрийн төгсгөлийг олох
   currentLineEnd = currentSelectionStart;
   while (currentLineEnd < richTextBox1.Text.Length &&   richTextBox1.Text[currentLineEnd] != '\n')
       currentLineEnd++;

   //Мөрийн уртыг тодорхойлох
   currentLineLength = currentLineEnd - currentLineStart;
            
   //Идэвхтэй байгаа мөрийг авах
   currentLine = richTextBox1.Text.Substring(currentLineStart, currentLineLength);

   //Одоо уг мөрөнд байх бүх хэрэгцээт үгээ тодруулах
   LockWindowUpdate(richTextBox1.Handle);
   highLightCLine(currentLine);
   LockWindowUpdate(IntPtr.Zero);
}
LockWindowUpdate функцын талаар дээр дурьдсан билээ. Харин одоо highLightCLine() функцын талаар авч үзье. Энэ функц текстыг тодруулж буй гол этгээд юм.

Идэвхтэй байгаа мөрийн үг бүрийг тодруулах ёстой үгтэй харьцуулж үзээд хэрэв тохирч байвал өгөгдсөн өнгөөр будаж харуулах юм. Манай жишээнд идэвхтэй үгийг хөх өнгөөр будаж байна.
void highLightCLine(string str)
{
   int selectionStart = richTextBox1.SelectionStart;
   richTextBox1.SelectionStart = currentLineStart;
   richTextBox1.SelectionLength = currentLineLength;
   richTextBox1.SelectionColor = Color.Black;
            
   foreach (Match matchKeyWords in regKeyWords.Matches(str))
   {
      int start = matchKeyWords.Index + currentLineStart;
      int length = matchKeyWords.Length;

      richTextBox1.SelectionStart = start;
      richTextBox1.SelectionLength = length;
      richTextBox1.SelectionColor = Color.Blue;
   }

   richTextBox1.SelectionStart = selectionStart;
   richTextBox1.SelectionLength = 0;
   richTextBox1.SelectionColor = Color.Black;
}
Шаардлагатай үгээ тодруулсны дараа бусад үг нь хэвийн харагдах ёстой. Иймээс өнгийг буцаан хар болгоно. Үр дүн нь :

За ингээд та бүгдэд амжилт хүсэе.
Хэрэв ойлгохгүй зүйл байвал сэтгэгдэл үлдээгээрэй.

2 comments:

Anonymous said...

well done :)

Anonymous said...

@Anon well, thank you :)

Зурхай