[C#] 텍스트 에디터(윈도우 메모장) 만들기 5
2024. 2. 5. 22:24ㆍ[C#]/[C# 윈폼] 혼자해보는 윈도우 메모장 만들기
오늘은 1. 찾기 폼 제작 2. 모두 선택 기능을 구현했다.
1. FindDialog 만들기
우선 찾기 기능을 구현하기 위해서 Custom으로 Dialog를 만드려고 했다.
방법을 찾아보니 윈도우에서 지원하지 않고 따로 만들어줘야하는 것 같다.
- 위는 내가 만든 것, 아래는 윈도우 메모장이다.
- 찾으면서 하다보니 시간이 좀 걸렸는데, 내일부터는 빠르게 진행할 수 있을 것 같다.
- 내일 기능 구현하면서 더 수정할 예정이다.
public class FindDialog : Form
{
private Label findLabel;
private RichTextBox textBoxToSearch;
private Button findNextButton;
private Button cancleButton;
private CheckBox caseSensitiveCheckBox;
private CheckBox roundCheckBox;
private RadioButton forwardRadioButton;
private RadioButton backwardRadioButton;
public event EventHandler FindNextEvent;
public string SearchText => textBoxToSearch.Text;
public bool CaseSensitive => caseSensitiveCheckBox.Checked;
public bool SearchForward => forwardRadioButton.Checked;
public FindDialog(RichTextBox richtextBox)
{
textBoxToSearch = richtextBox;
InitializeUI();
this.Text = "찾기";
this.Width = 430;
this.Height = 180;
}
private void InitializeUI()
{
findLabel = new Label();
textBoxToSearch = new RichTextBox();
findNextButton = new Button();
cancleButton = new Button();
caseSensitiveCheckBox = new CheckBox();
forwardRadioButton = new RadioButton();
backwardRadioButton = new RadioButton();
roundCheckBox = new CheckBox();
//라벨
findLabel.Text = "찾을 내용(N) :";
findLabel.Location = new Point(10, 25);
findLabel.AutoSize = true;
//찾을 내용 TextBox
textBoxToSearch.Height = 25;
textBoxToSearch.Width = 200;
textBoxToSearch.Location = new Point(100, 20);
//다음 찾기 버튼 UI
findNextButton.Text = "다음 찾기(F)";
findNextButton.Height = 25;
findNextButton.Width = 80;
findNextButton.Location = new Point(310, 20);
findNextButton.Click += FindNextButton_Click;
//취소 버튼 UI
cancleButton.Text = "취소";
cancleButton.Height = 25;
cancleButton.Width = 80;
cancleButton.Location = new Point(310, 60);
cancleButton.Click += CancelButton_Click;
//대/소문자 구분 UI
caseSensitiveCheckBox.Text = "대/소문자 구분(C)";
caseSensitiveCheckBox.Location = new Point(10, 60);
caseSensitiveCheckBox.AutoSize = true;
// 찾기 방향 라디오 버튼
forwardRadioButton.Text = "위로(U)";
forwardRadioButton.Location = new Point(150, 60);
forwardRadioButton.Checked = false;
forwardRadioButton.AutoSize = true;
backwardRadioButton.Text = "아래로(D)";
backwardRadioButton.Location = new Point(220, 60);
backwardRadioButton.Checked = true;
backwardRadioButton.AutoSize = true;
//주위에 배치(R)
roundCheckBox.Text = "주위에 배치(R)";
roundCheckBox.Location = new Point(10, 90);
roundCheckBox.AutoSize = true;
// Add controls to the form
Controls.Add(findLabel);
Controls.Add(textBoxToSearch);
Controls.Add(findNextButton);
Controls.Add(cancleButton);
Controls.Add(caseSensitiveCheckBox);
Controls.Add(forwardRadioButton);
Controls.Add(backwardRadioButton);
Controls.Add(roundCheckBox);
}
private void FindNextButton_Click(object sender, EventArgs e)
{
FindNextEvent?.Invoke(this, EventArgs.Empty);
}
private void CancelButton_Click(object sender, EventArgs e)
{
// 취소 버튼 클릭 시 폼 닫기
this.Close();
}
}
2. 모두 선택
//모두 선택(Ctrl+A)
private void AllSelectTextToolTip_Click(object sender, EventArgs e)
{
MyTextArea.SelectAll();
}
- 그냥 텍스트 전체 선택을 지정해주면 된다.
전체 코드
using Microsoft.VisualBasic;
using System.Drawing.Printing;
namespace MyTextEditor
{
public partial class 메모장 : Form
{
private FindDialog findDialog;
private string currentFilePath = string.Empty;
private bool isTextChanged = false;
public 메모장()
{
InitializeComponent();
}
#region 파일 메뉴
// 새 파일(Ctrl+N)
private void NewFileToolTip_Click(object sender, EventArgs e)
{
if (isTextChanged)
{
// 파일이 변경되었을 경우 저장 여부 확인
DialogResult result = MessageBox.Show("변경된 내용을 저장하시겠습니까?", "저장 확인", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
// 저장
SaveFile();
}
else if (result == DialogResult.Cancel)
{
// 취소
return;
}
}
// 새 파일 초기화
MyTextArea.Text = string.Empty;
currentFilePath = string.Empty;
isTextChanged = false;
}
//새창(Ctrl+Shift+N)
private void NewMemoToolTip_Click(object sender, EventArgs e)
{
// 새 창을 만들기 위해 메모장의 복사본을 생성
메모장 newMemo = new 메모장();
// 새 창을 보여줌
newMemo.Show();
}
//열기(Ctrl+O)
private void OpenToolTip_Click(object sender, EventArgs e)
{
//현재 메모장에 수정이 있으면 저장 여부 후 열기 작업 진행
if (isTextChanged)
{
DialogResult result = MessageBox.Show("변경된 내용을 저장하시겠습니까?", "저장 확인", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
SaveFile();
}
else if (result == DialogResult.Cancel)
{
return;
}
}
//OpenFileDialog 호출(.txt text 파일만 열기)
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "텍스트 파일 (*.txt)|*.txt|모든 파일 (*.*)|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
currentFilePath = openFileDialog.FileName;
MyTextArea.Text = File.ReadAllText(currentFilePath);
isTextChanged = false;
UpdateFormTitle();
ControlFocusBack();
}
}
// 저장(Ctrl+S)
private void SaveToolTip_Click(object sender, EventArgs e)
{
SaveFile();
}
//다른 이름으로 저장(Ctrl+Shift+S)
private void DnameSaveToolTip_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "텍스트 파일 (*.txt)|*.txt|모든 파일 (*.*)|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
currentFilePath = saveFileDialog.FileName;
SaveFile();
}
}
//페이지 설정
private void PageSettingToolTip_Click(object sender, EventArgs e)
{
}
//인쇄(Ctrl+P)
private void PrintToolTip_Click(object sender, EventArgs e)
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = new PrintDocument();
if (printDialog.ShowDialog() == DialogResult.OK)
{
printDialog.Document.PrintPage += new PrintPageEventHandler(PrintDocument_PrintPage);
printDialog.Document.Print();
}
}
//끝내기
private void ExitToolTip_Click(object sender, EventArgs e)
{
if (isTextChanged)
{
DialogResult result = MessageBox.Show("변경된 내용을 저장하시겠습니까?", "저장 확인", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
// 저장
SaveFile();
}
else if (result == DialogResult.Cancel)
{
// 취소
return;
}
}
//폼 닫기
Close();
}
#endregion
#region 편집
//복사(Ctrl+C)
private void CopyTextToolTip_Click(object sender, EventArgs e)
{
if (MyTextArea.SelectionLength > 0)
{
MyTextArea.Copy();
}
}
//붙여넣기(Ctrl+V)
private void PasteTextToolTip_Click(object sender, EventArgs e)
{
MyTextArea.Paste();
}
//자르기(Ctrl+X)
private void CutTextToolTip_Click(object sender, EventArgs e)
{
if (MyTextArea.SelectionLength > 0)
{
MyTextArea.Cut();
}
}
//실행 취소(Ctrl+Z)
private void DoCancleToolTip_Click(object sender, EventArgs e)
{
if (MyTextArea.CanUndo)
{
MyTextArea.Undo();
}
}
//실행 복구(Ctrl+Y)
private void RedoToolTip_Click(object sender, EventArgs e)
{
if (MyTextArea.CanRedo)
{
MyTextArea.Redo();
}
}
//삭제(Delete)
private void DeleteTextToolTip_Click(object sender, EventArgs e)
{
if (MyTextArea.SelectionLength > 0)
{
MyTextArea.SelectedText = string.Empty;
}
}
//찾기(Ctrl+F)
private void FindTextToolTip_Click(object sender, EventArgs e)
{
ShowFindDialog();
}
private void ShowFindDialog()
{
if (findDialog == null || findDialog.IsDisposed)
{
findDialog = new FindDialog(MyTextArea);
findDialog.FindNextEvent += FindDialog_FindNextEvent;
findDialog.Show();
}
else
{
findDialog.BringToFront();
}
}
private void FindDialog_FindNextEvent(object sender, EventArgs e)
{
// FindDialog에서 발생한 이벤트를 처리
FindNext();
}
private void FindNext()
{
if (findDialog != null)
{
int startIndex = MyTextArea.SelectionStart + MyTextArea.SelectionLength;
int index = MyTextArea.Text.IndexOf(findDialog.SearchText, startIndex, StringComparison.CurrentCultureIgnoreCase);
if (index != -1)
{
MyTextArea.Select(index, findDialog.SearchText.Length);
MyTextArea.ScrollToCaret();
}
else
{
MessageBox.Show("더 이상 찾을 문자열이 없습니다.", "찾기 완료", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
//다음 찾기(F3)
private void FindNextToolTip_Click(object sender, EventArgs e)
{
}
//이전 찾기(SHIFT+F3)
private void FindBeforeToolTip_Click(object sender, EventArgs e)
{
}
//바꾸기(Ctrl+H)
private void ChangeTextToolTip_Click(object sender, EventArgs e)
{
}
//이동(Ctrl+G)
private void MoveTextToolTip_Click(object sender, EventArgs e)
{
}
//모두 선택(Ctrl+A)
private void AllSelectTextToolTip_Click(object sender, EventArgs e)
{
MyTextArea.SelectAll();
}
//시간 입력(F5)
private void TimeTextToolTip_Click(object sender, EventArgs e)
{
//현재 시간 추가
MyTextArea.Text += DateTime.Now.ToString();
ControlFocusBack();
}
#endregion
#region 메소드
// 파일 저장 메소드
private void SaveFile()
{
if (string.IsNullOrEmpty(currentFilePath))
{
// 파일 경로가 없는 경우 SaveFileDialog 표시
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "텍스트 파일 (*.txt)|*.txt|모든 파일 (*.*)|*.*";
saveFileDialog.FilterIndex = 1;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
currentFilePath = saveFileDialog.FileName;
}
else
{
return; // 사용자가 취소한 경우 저장 중단
}
}
try
{
// 텍스트 에디터의 내용을 파일에 저장
File.WriteAllText(currentFilePath, MyTextArea.Text);
isTextChanged = false; // 저장 후 변경되지 않은 상태로 표시
UpdateFormTitle(); // 저장 후 파일 이름 표시 갱신
}
catch (Exception ex)
{
MessageBox.Show($"파일 저장 중 오류가 발생했습니다: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// 텍스트 변경 여부 확인 메소드
private void MyTextArea_TextChanged(object sender, EventArgs e)
{
isTextChanged = true;
UpdateFormTitle();
}
//파일 이름 변경 메소드
private void UpdateFormTitle()
{
string fileName = string.IsNullOrEmpty(currentFilePath) ? "제목 없음" : Path.GetFileName(currentFilePath);
this.Text = isTextChanged ? $"*{fileName}" : fileName;
}
// 프린트할 때 호출되는 이벤트 핸들러
private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
{
Font font = new Font("Arial", 12);
e.Graphics.DrawString(MyTextArea.Text, font, Brushes.Black, 10, 10);
}
//커서 위치 이동(맨 뒤)
private void ControlFocusBack()
{
//커서 맨 뒤로 이동
MyTextArea.SelectionStart = MyTextArea.Text.Length;
MyTextArea.SelectionLength = 0;
MyTextArea.Focus();
}
private void 메모장_FormClosing(object sender, FormClosingEventArgs e)
{
// 모든 폼이 닫히면 프로그램 종료
if (Application.OpenForms.Count == 1)
{
Application.Exit();
}
}
#endregion
}
//찾기 커스텀 다이어로그
public class FindDialog : Form
{
private Label findLabel;
private RichTextBox textBoxToSearch;
private Button findNextButton;
private Button cancleButton;
private CheckBox caseSensitiveCheckBox;
private CheckBox roundCheckBox;
private RadioButton forwardRadioButton;
private RadioButton backwardRadioButton;
public event EventHandler FindNextEvent;
public string SearchText => textBoxToSearch.Text;
public bool CaseSensitive => caseSensitiveCheckBox.Checked;
public bool SearchForward => forwardRadioButton.Checked;
public FindDialog(RichTextBox richtextBox)
{
textBoxToSearch = richtextBox;
InitializeUI();
this.Text = "찾기";
this.Width = 430;
this.Height = 180;
}
private void InitializeUI()
{
findLabel = new Label();
textBoxToSearch = new RichTextBox();
findNextButton = new Button();
cancleButton = new Button();
caseSensitiveCheckBox = new CheckBox();
forwardRadioButton = new RadioButton();
backwardRadioButton = new RadioButton();
roundCheckBox = new CheckBox();
//라벨
findLabel.Text = "찾을 내용(N) :";
findLabel.Location = new Point(10, 25);
findLabel.AutoSize = true;
//찾을 내용 TextBox
textBoxToSearch.Height = 25;
textBoxToSearch.Width = 200;
textBoxToSearch.Location = new Point(100, 20);
//다음 찾기 버튼 UI
findNextButton.Text = "다음 찾기(F)";
findNextButton.Height = 25;
findNextButton.Width = 80;
findNextButton.Location = new Point(310, 20);
findNextButton.Click += FindNextButton_Click;
//취소 버튼 UI
cancleButton.Text = "취소";
cancleButton.Height = 25;
cancleButton.Width = 80;
cancleButton.Location = new Point(310, 60);
cancleButton.Click += CancelButton_Click;
//대/소문자 구분 UI
caseSensitiveCheckBox.Text = "대/소문자 구분(C)";
caseSensitiveCheckBox.Location = new Point(10, 60);
caseSensitiveCheckBox.AutoSize = true;
// 찾기 방향 라디오 버튼
forwardRadioButton.Text = "위로(U)";
forwardRadioButton.Location = new Point(150, 60);
forwardRadioButton.Checked = false;
forwardRadioButton.AutoSize = true;
backwardRadioButton.Text = "아래로(D)";
backwardRadioButton.Location = new Point(220, 60);
backwardRadioButton.Checked = true;
backwardRadioButton.AutoSize = true;
//주위에 배치(R)
roundCheckBox.Text = "주위에 배치(R)";
roundCheckBox.Location = new Point(10, 90);
roundCheckBox.AutoSize = true;
// Add controls to the form
Controls.Add(findLabel);
Controls.Add(textBoxToSearch);
Controls.Add(findNextButton);
Controls.Add(cancleButton);
Controls.Add(caseSensitiveCheckBox);
Controls.Add(forwardRadioButton);
Controls.Add(backwardRadioButton);
Controls.Add(roundCheckBox);
}
private void FindNextButton_Click(object sender, EventArgs e)
{
FindNextEvent?.Invoke(this, EventArgs.Empty);
}
private void CancelButton_Click(object sender, EventArgs e)
{
// 취소 버튼 클릭 시 폼 닫기
this.Close();
}
}
}
반응형
'[C#] > [C# 윈폼] 혼자해보는 윈도우 메모장 만들기' 카테고리의 다른 글
[C#] 텍스트 에디터(윈도우 메모장) 만들기 7 (0) | 2024.02.07 |
---|---|
[C#] 텍스트 에디터(윈도우 메모장) 만들기 6 (0) | 2024.02.06 |
[C#] 텍스트 에디터(윈도우 메모장) 만들기 4 (0) | 2024.02.04 |
[C#] 텍스트 에디터(윈도우 메모장) 만들기 3 (0) | 2024.02.04 |
[C#] 텍스트 에디터(윈도우 메모장) 만들기 2 (0) | 2024.02.02 |