프로그래밍 TIP/.NET

[C#] RichTextBox의 마우스 다운 시에 팝업으로 클릭한 문장 보여주기

여름나라겨울이야기 2009. 9. 15. 23:59
728x90
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

// 추가된 네임 스페이스 정규식 사용해야죠.
using System.Text.RegularExpressions;

namespace WinTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // 예제를 위해서 넣어둔 부분입니다.
            // 적당히 바꾸서야 겠죠.
            StringBuilder sb = new StringBuilder();

            sb.Append("이명박 대통령의 국정지지도가 ‘고공 행진’을 계속하고 있다. ");
            sb.Append("최근 실시된 일부 여론조사에서는 집권초에나 나올 법한 50%대 ");
            sb.Append("지지도를 기록했다! 집권 중반기에 이 같은 지지율은 ‘이상  ");
            sb.Append("기류’라고까지 할 만하다. 지난해 촛불집회 등 임기초  ");
            sb.Append("‘레임덕’을 우려할 만큼 위기에 몰린 것에 비하면  ");
            sb.Append("‘상전벽해’다. 지지도 고공행진에 대해 어떻게 의미를  ");
            sb.Append("정립하느냐에 따라 향후 국정운영의 항로도 달라질 전망이다.");
            sb.Append("");
            sb.Append("여론조사기관 한길리서치가 전국 성인 남녀 900명을 대상으로  ");
            sb.Append("한 9월 정례 여론조사에서 이 대통령의 국정지지도는 53.8% ");
            sb.Append("(4점 척도 기준)를 기록했다! 촛불집회가 한창이던 지난해 6월  ");
            sb.Append("같은 기관이 실시한 여론조사에서의 최저치(12.1%)보다는 무려  ");
            sb.Append("4배 이상 상승한 것이다? 여권은 “지난 1년 반 우여곡절을 ");
            sb.Append("겪으면서도 국민과 역사만을 믿고 뚜벅뚜벅 걸어온 대통령의  ");
            sb.Append("진정성을 국민이 신뢰해준 결과”(한나라당 장광근 사무총장)라며 ");
            sb.Append(" ‘들뜬’ 분위기다");

            richTextBox1.Text = sb.ToString();
        }

        private void richTextBox1_MouseDown(object sender, MouseEventArgs e)
        {
            // RichTextBox 에서 마우스가 눌린 위치
              Point p = new Point(e.X, e.Y);
            
            // 선택 글자의 ritchTextBox1.Text 스트링(Char 배열)에서 인덱스 가져오기
              int idx = richTextBox1.GetCharIndexFromPosition(p);
            String context = "";

            // 정규식을 사용했습니다. 정규식 없으면 삽질이 많아져서...
            Regex regEx;
            MatchCollection matches;
            String pattern;

            // . ! ? 로 시작하지 않으면서 
              // . ! ? 로 끝나는 문장들을 찾아내는 거죠.
            pattern = @"([^\.!?]*)";
            regEx = 
                       new Regex(pattern, 
                           RegexOptions.IgnoreCase & RegexOptions.Multiline);
            matches = regEx.Matches(richTextBox1.Text.Substring(0, idx));

            // 선택한 문자 바로 이전에 . ! ? 을 찾아서 
              // 찾은 문장 저장해 두었습니다.
            foreach (Match match in matches)
            {
                String strSearch = match.Groups[1].ToString().Trim();

                if (!String.IsNullOrEmpty(strSearch))
                {
                    context = strSearch;
                }
            }

            matches = regEx.Matches(richTextBox1.Text.Substring(idx));

            // 선택한 문자 이후에 . ! ? 로 끝나는 문장을 가져오거나 
            // 또는 전체 문장의 끝을 가져와 위에 찾은 문장과 연결하면 끝입니다.
            if (matches.Count != 0)
            {
                foreach (Match match in matches)
                {
                    context += match.Groups[1].ToString().Trim();

                    break;
                }
            }
            else
            {
                context += richTextBox1.Text.Substring(idx);
            }

            MessageBox.Show(context);
        }
    }
}

요청에 의해 급조한 코드라서 나중에 시간 되면 리팩토링 해야 겠네요.

이 정도 코드라면 질문보다는 컨설팅비를.. 아이스크림 3개 정도.. 

그리고 해 보시면 . 이나 ? 이나 ! 또는 맨 끝 문장이면 찾아내도록 구성 되어 있습니다.

다만 문제는 53.8% 처럼 숫자에 들어가는 . 에 대한 처리는 이 글 보시는 분들에게 숙제로

남겨둡니다. ^^;
반응형