WPF(Windows Presentation Foundation)는 데스크톱 애플리케이션 개발에 있어 매우 강력하고 유연한 프레임워크입니다. WPF의 매력 중 하나는 UI의 시각적 요소와 백엔드 로직을 쉽게 분리할 수 있다는 점입니다. 이번 글에서는 WPF를 사용하여 기본적인 텍스트 편집기를 만드는 과정을 자세하게 살펴보겠습니다.
WPF 개요
WPF는 .NET Framework의 일부로, Windows 기반 애플리케이션을 개발하기 위한 플랫폼입니다. WPF는 XAML(Extensible Application Markup Language)을 사용하여 UI를 디자인하며, MVVM(Model-View-ViewModel) 패턴을 통해 더욱 쉽게 데이터와 UI 상태를 관리할 수 있습니다.
편집기 애플리케이션의 기능 요구사항
- 텍스트 입력 및 편집 기능
- 기본적인 파일 열기/저장 기능
- 서체 및 텍스트 서식 변경 기능
- 간단한 검색 기능
- Undo/Redo 기능
프로젝트 설정
Visual Studio를 열고 새로운 WPF 애플리케이션 프로젝트를 생성합니다. 프로젝트 이름은 SimpleTextEditor로 설정합니다.
XAML을 통한 UI 설계
WPF에서 UI는 XAML 파일을 통해 정의됩니다. MainWindow.xaml 파일을 열고 다음 코드를 입력하여 기본 UI를 구성합니다.
<Window x:Class="SimpleTextEditor.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Simple Text Editor" Height="450" Width="800">
<Grid>
<Menu VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem Header="Open" Click="Open_Click" />
<MenuItem Header="Save" Click="Save_Click" />
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Undo" Click="Undo_Click" />
<MenuItem Header="Redo" Click="Redo_Click" />
</MenuItem>
</Menu>
<TextBox x:Name="textBox" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
FontSize="14" VerticalAlignment="Stretch" Margin="0,25,0,0" />
</Grid>
</Window>
WPF 코드 비하인드 구현
이제 MainWindow.xaml.cs 파일로 가서 기본 기능을 구현해 보겠습니다.
using Microsoft.Win32;
using System;
using System.IO;
using System.Windows;
namespace SimpleTextEditor
{
public partial class MainWindow : Window
{
private string currentFile;
private bool isDirty;
public MainWindow()
{
InitializeComponent();
currentFile = string.Empty;
isDirty = false;
textBox.TextChanged += (s, e) => { isDirty = true; };
}
private void Open_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
if (openFileDialog.ShowDialog() == true)
{
currentFile = openFileDialog.FileName;
textBox.Text = File.ReadAllText(currentFile);
isDirty = false;
Title = "Simple Text Editor - " + currentFile;
}
}
private void Save_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(currentFile))
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
if (saveFileDialog.ShowDialog() == true)
{
currentFile = saveFileDialog.FileName;
}
}
if (!string.IsNullOrEmpty(currentFile))
{
File.WriteAllText(currentFile, textBox.Text);
isDirty = false;
Title = "Simple Text Editor - " + currentFile;
}
}
private void Undo_Click(object sender, RoutedEventArgs e)
{
// 간단한 Undo 구현 - 이를 위해 Stack 사용
// UndoStack.Push(textBox.Text);
// textBox.Text = UndoStack.Pop();
}
private void Redo_Click(object sender, RoutedEventArgs e)
{
// 간단한 Redo 구현 - 이를 위해 Stack 사용
// RedoStack.Push(textBox.Text);
// textBox.Text = RedoStack.Pop();
}
}
}
기능 설명
- Open_Click: 사용자가 선택한 파일을 열어 텍스트 박스에 내용을 로드합니다. 파일이 열릴 때의 경로는
currentFile
변수에 저장됩니다. - Save_Click: 사용자가 현재 내용을 파일에 저장합니다. 파일 이름이 지정되지 않은 경우, 사용자가 저장할 파일 이름을 선택할 수 있는 대화 상자가 나타납니다.
- Undo_Click: 현재 텍스트 박스 상태를 이전 상태로 되돌리기 위한 준비를 하는 부분입니다. Stack 구조를 구현하여 Undo 및 Redo 기능을 완전하게 구현할 수 있습니다.
추가 기능: 서체 및 텍스트 서식 변경
간단한 편집기를 위해 서체 및 텍스트 서식을 변경하는 기능도 추가할 수 있습니다. 다음 코드를 추가해 보겠습니다.
<MenuItem Header="Format">
<MenuItem Header="Font" Click="ChangeFont_Click" />
</MenuItem>
그리고 코드 비하인드에 다음과 같은 메서드를 추가합니다.
private void ChangeFont_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FontDialog fontDialog = new System.Windows.Forms.FontDialog();
if (fontDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
textBox.FontFamily = new FontFamily(fontDialog.Font.Name);
textBox.FontSize = fontDialog.Font.Size;
}
}
결론
이번 글에서는 WPF를 사용하여 기본 텍스트 편집기를 만드는 방법을 설명했습니다. 간단한 UI를 설계하고 파일 처리 및 기본적인 편집 기능을 구현해 보았습니다. 물론, 더 많은 기능과 복잡한 요구 사항을 추가할 수 있지만, 여기서는 핵심적인 부분에 집중했습니다.
앞으로 이 편집기에 추가하고 싶은 기능이나 개선점이 있다면, 이를 바탕으로 확장할 수 있을 것입니다. WPF의 유연함 덕분에 더 복잡한 애플리케이션을 만들기도 용이할 것입니다.
프로젝트 소스 코드: 전체 소스 코드는 GitHub 저장소에서 확인할 수 있습니다.