DialogBox
이 샘플에서는 메시지 상자 및 공용 대화 상자를 사용하는 방법을 보여줍니다. 이 샘플에서는 모달 및 모덜리스 대화 상자를 만들고 사용하는 방법도 보여줍니다.
예제 시나리오:
- 대화상자를 이용한 파일 열기
- 대화상자를 이용한 파일 저장
- 대화상자를 이용한 파일 프린트
- 응용 프로그램 수동 종료
- 종료 시 문서를 저장
- 검색 기능을 하는 모달 대화 상자 만들기
- 폰트 설정 모달 대화 상자 만들기
- 문서 간격 설정 모달 대화 상자 만들기
예제에는 Window 외에 다른 기술들(Binding, ValidationRule 등)이 사용되고 있지만 해당 기술에 대해서는 예제를 벗어나는 주제 이므로 설명을 생각 하도록 하겠습니다.
메인 창 구성
Window는 Closing 이벤트를 추가하고, 상단은 Menu 컨트롤과 컨텐츠 영역은 TextBox로 포함하는 DockPanel로 구성 합니다.
메뉴 하위 자식인 MenuItem에 각 대화상자를 생성하는 이벤트를 추가 하고 마지막으로 본문인 TextBox에 TextChanged 이벤트를 추가 합니다.
1: <Window x:Class="DialogBox.MainWindow"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6: xmlns:local="clr-namespace:DialogBox"
7: mc:Ignorable="d"
8: Title="MainWindow" Height="350" Width="525" Closing="Window_Closing">
9: <DockPanel>
10: <Menu DockPanel.Dock="Top">
11: <MenuItem Header="_File">
12: <MenuItem Header="_Open" Click="fileOpen_Click" />
13: <MenuItem Header="_Save" Click="fileSave_Click" />
14: <MenuItem Header="_Print" Click="filePrint_Click" />
15: <Separator />
16: <MenuItem Header="_Exit" Click="fileExit_Click" />
17: </MenuItem>
18: <MenuItem Header="_Edit">
19: <!-- Main Window -->
20: <MenuItem Name="editFindMenuItem" Header="_Find" InputGestureText="Ctrl+F" Click="editFindMenuItem_Click" />
21: </MenuItem>
22: <MenuItem Header="F_ormat">
23: <MenuItem Name="formatFontMenuItem" Header="_Font..." Click="formatFontMenuItem_Click" />
24: <!-- Main Window -->
25: <MenuItem Name="formatMarginMenuItem" Header="_Margins..." Click="formatMarginMenuItem_Click" />
26: </MenuItem>
27: </Menu>
28: <TextBox Name="documentTextBox"
29: TextChanged="documentTextBox_TextChanged"
30: ScrollViewer.CanContentScroll="True"
31: ScrollViewer.HorizontalScrollBarVisibility="Visible"
32: ScrollViewer.VerticalScrollBarVisibility="Visible"
33: AcceptsReturn="True"
34: AcceptsTab="True"
35: BorderThickness="0">
36: The quick brown fox jumped over the lazy old brown dog.
37: </TextBox>
38: </DockPanel>
39: </Window>
대화 상자를 이용한 파일 열기
OpenFileDialog 클래스를 이용해 열려고 하는 파일을 선택할 수 있습니다. 선택된 파일은 FileName 속성을 이용해 파일 경로를 확인 합니다.
1: /// <summary>
2: /// 대화상자를 이용해 파일 경로를 가져 옵니다.
3: /// </summary>
4: private void OpenDocument()
5: {
6: // 대화상자 인스턴스 생성
7: var dlg = new OpenFileDialog()
8: {
9: // 기본 파일 이름
10: FileName = "Document",
11: // 기본 파일 확장자
12: DefaultExt = ".wpf",
13: // 확장자 별 파일 필터링
14: Filter = "Word Processor Files (.wpf)|*.wpf"
15: };
16: // 모덜리스로 대화상자 열기
17: var result = dlg.ShowDialog();
18: // 열기 대화상자 결과 처리
19: if (result == true)
20: {
21: // 문서 열기
22: var filename = dlg.FileName;
23: }
24: }
대화 상자를 이용한 파일 저장
SaveFileDialog 클래스를 이용해 저장하려는 파일 경로를 가져올 수 있습니다. 선택된 파일 경로는 FileName 속성을 이용해 확인 할 수 있습니다.
1: /// <summary>
2: /// 저장 대화상자를 이용해 파일 경로를 가져 옵니다.
3: /// </summary>
4: private void SaveDocument()
5: {
6: // 저장파일 대화상자 구성
7: var dlg = new SaveFileDialog()
8: {
9: // 기본 파일 이름
10: FileName = "Document",
11: // 기본 파일 확장자
12: DefaultExt = ".wpf",
13: // 확장자 별 파일 필터링
14: Filter = "Word Processor Files (.wpf)|*.wpf"
15: };
16: // 파일저장 대화상자를 표시
17: var result = dlg.ShowDialog();
18: // 파일저장 대화상자 결과 처리
19: if (result == true)
20: {
21: // 문서 저장
22: var filename = dlg.FileName;
23: }
24: }
대화 상자를 이용한 파일 프린트
PrintDialog 클래스를 이용해 프린트 대화 상자를 표시 할 수 있습니다. ShowDialog 메소드의 bool 결과를 이용하여 결과를 확인 합니다.
1: /// <summary>
2: /// 프린트 대화상자를 이용해 문서를 프린트 합니다.
3: /// </summary>
4: private void PrintDocument()
5: {
6: // 프린트 대화상자 구성
7: var dlg = new PrintDialog
8: {
9: PageRangeSelection = PageRangeSelection.AllPages,
10: UserPageRangeEnabled = true
11: };
12: // 프린트 대화상자를 표시
13: var result = dlg.ShowDialog();
14: // 프린트 대화상자 결과 처리
15: if (result == true)
16: {
17: // 문서 프린트
18: }
19: }
Window 수동 종료
1: private void fileExit_Click(object sender, RoutedEventArgs e)
2: {
3: Close();
4: }
종료 시 문서 저장
TextChanged 이벤트를 통해 TextBox의 Text가 변경 되었을 경우 윈도우 종료 시 문서 저장 여부를 사용자에게 물어보도록 합니다.
1: /// <summary>
2: /// MainWindow Closing 이벤트
3: /// </summary>
4: /// <param name="sender"></param>
5: /// <param name="e"></param>
6: private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
7: {
8: // 종료 시 문서를 저장
9: if (_needsToBeSaved)
10: {
11: // 메시지 박스 구성
12: var messageBoxText =
13: "This document needs to be saved. Click Yes to save and exit, No to exit without saving, or Cancel to not exit.";
14: var caption = "Word Processor";
15: var button = MessageBoxButton.YesNoCancel;
16: var icon = MessageBoxImage.Warning;
17: // 메시지 박스 표시
18: var messageBoxResult = MessageBox.Show(messageBoxText, caption, button, icon);
19: // 메시지 박스 결과 처리
20: switch (messageBoxResult)
21: {
22: case MessageBoxResult.Cancel: // 종료 취소
23: e.Cancel = true;
24: break;
25: case MessageBoxResult.Yes: // 저장 후 종료
26: SaveDocument();
27: break;
28: case MessageBoxResult.No: // 저장하지 않고 종료
29: break;
30: }
31: }
32: }
검색 기능을 하는 모달 대화 상자 만들기
검색 모달 대화 상자 창에 필요한 속성
- MinWidth - 최소 창 넓이
- MinHeight - 최소 창 높이
- Width - 창 넓이
- SizeToContent - 창이 자동으로 크기를 내용에 맞게 조정할지 여부
- ShowInTaskbar - 윈도우 작업 표시줄에 표시 여부
- ResizeMode - 창 사이즈 조절 여부
- WindowStartupLocation - 창 시작 위치
검색 모달 대화 상자 창 속성 정의
- 최소 창 넓이가 350
- 최소 창 높이가 100
- 창 넓이 350
- 창 높이는 내용에 맞게 조정
- 작업 표시줄에 표시 하지 않음
- 크기 조정 그립을 표시하며, 창 크기 조정 가능
- 시작 위치를 부모 창의 가운데에서 시작
검색 모달 대화 창 구성
1: <Window x:Class="DialogBox.FindDialogBox"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6: xmlns:local="clr-namespace:DialogBox"
7: mc:Ignorable="d"
8: Title="Find"
9: MinWidth="350"
10: MinHeight="100"
11: Width="350"
12: SizeToContent="Height"
13: ShowInTaskbar="False"
14: ResizeMode="CanResizeWithGrip"
15: WindowStartupLocation="CenterOwner"
16: FocusManager.FocusedElement="{Binding ElementName=findWhatTextBox}">
17: <Grid>
18: <Grid.ColumnDefinitions>
19: <ColumnDefinition Width="10" />
20: <ColumnDefinition Width="Auto" />
21: <ColumnDefinition />
22: <ColumnDefinition Width="10" />
23: <ColumnDefinition Width="Auto" />
24: <ColumnDefinition Width="10" />
25: </Grid.ColumnDefinitions>
26: <Grid.RowDefinitions>
27: <RowDefinition Height="10" />
28: <RowDefinition Height="Auto" />
29: <RowDefinition Height="5" />
30: <RowDefinition Height="Auto" />
31: <RowDefinition Height="5" />
32: <RowDefinition Height="Auto" />
33: <RowDefinition />
34: <RowDefinition Height="10" />
35: </Grid.RowDefinitions>
36: <!-- Find Controls -->
37: <Label Grid.Column="1" Grid.Row="1">_Find What:</Label>
38: <TextBox Name="findWhatTextBox" Grid.Column="2" Grid.Row="1" TextChanged="findWhatTextBox_TextChanged" />
39: <!-- Match case? -->
40: <CheckBox Name="caseSensitiveCheckBox" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="2" Click="criteria_Click" Margin="5,0,0,5" IsChecked="True">Match case?</CheckBox>
41: <!-- Match whole word? -->
42: <CheckBox Name="matchWholeWordCheckBox" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="2" Click="criteria_Click" Margin="5,0,0,0" IsChecked="True">Match whole word?
43: </CheckBox>
44: <!-- Action Controls -->
45: <StackPanel Grid.Column="4" Grid.Row="1" Grid.RowSpan="6">
46: <Button Name="findNextButton" Height="25" Width="70" Click="findNextButton_Click" IsDefault="True" Margin="0,0,0,5">Find Next</Button>
47: <Button Name="closeButton" Height="25" Width="70" Click="closeButton_Click" IsCancel="True">Close</Button>
48: </StackPanel>
49: </Grid>
50: </Window>
대화 상자 생성 시 부모 컨트롤 참조
창 생성자 호출 시 참조하고자 하는 컨트롤을 매개 변수로 설정하여 상호 작용을 할 수 있도록 할 수 있습니다. 이 예제에서는 부모창의 TextBox의 TextChanged 이벤트를 수신하여 텍스트 변경이 있을 경우 검색 조건을 초기화 합니다.
1: public FindDialogBox(TextBox textBoxToSearch)
2: {
3: InitializeComponent();
4: _textBoxToSearch = textBoxToSearch;
5: // 검색중인 텍스트 상자가 변경되면 검색을 재설정합니다.
6: textBoxToSearch.TextChanged += TextBoxToSearch_TextChanged;
7: }
이벤트를 통한 부모 창과의 상호작용
검색 모달 창은 TextFound라는 이벤트를 제공하여 부모창과 검색 결과가 있을 경우 이벤트 발생을 통해 상호작용이 가능 합니다.
1: private void editFindMenuItem_Click(object sender, RoutedEventArgs e)
2: {
3: // 대화상자 인스턴스 생성
4: var dlg = new FindDialogBox(documentTextBox) { Owner = this };
5: // 대화상자 설정
6: dlg.TextFound += Dlg_TextFound;
7: // 모달 대화상자 열기
8: dlg.Show();
9: }
10: private void Dlg_TextFound(object sender, EventArgs e)
11: {
12: // 이벤트를 발생시킨 찾기 대화 상자를 가져옵니다.
13: var dlg = sender as FindDialogBox;
14: // 찾기 결과 및 발견 된 텍스트 선택
15: documentTextBox.Select(dlg.Index, dlg.Length);
16: documentTextBox.Focus();
17: }
1: public event TextFoundEventHandler TextFound;
2: private void findNextButton_Click(object sender, RoutedEventArgs e)
3: {
4: // 일치하는 항목 찾기
5: if (_matches == null)
6: {
7: var pattern = findWhatTextBox.Text;
8: // 전체 단어와 일치?
9: if ((bool)matchWholeWordCheckBox.IsChecked) pattern = @"(?<=\W{0,1})" + pattern + @"(?=\W)";
10: // 대소 문자 구분
11: if ((bool)caseSensitiveCheckBox.IsChecked) pattern = "(?i)" + pattern;
12: // 일치하는 항목 찾기
13: _matches = Regex.Matches(_textBoxToSearch.Text, pattern);
14: _matchIndex = 0;
15: // 단어를 찾을 수 없음
16: if (_matches.Count == 0)
17: {
18: MessageBox.Show("'" + findWhatTextBox.Text + "' not found.", "Find");
19: _matches = null;
20: return;
21: }
22: }
23: // 최종 일치 항목이 마지막 일치 항목을 선택한 경우 일치 항목의 시작 부분에서 시작
24: if (_matchIndex == _matches.Count)
25: {
26: var result = MessageBox.Show("Nmore matches found. Start at beginning?", "Find",
27: MessageBoxButton.YesNo);
28: if (result == MessageBoxResult.No) return;
29: // 초기화
30: _matchIndex = 0;
31: }
32: // 텍스트를 선택할 수 있도록 클라이언트에게 일치 세부 정보를 반환합니다.
33: var match = _matches[_matchIndex];
34: if (TextFound != null)
35: {
36: // 문자 찾음
37: Index = match.Index;
38: Length = match.Length;
39: OnTextFound();
40: }
41: _matchIndex++;
42: }
댓글
댓글 쓰기