[WPF] 공공데이터 포털 API 이용 클라이언트 구현 Part 3

이미지
그룹핑 ListViewItem 그룹핑 할 수 있습니다. 먼저 CheckBox에 Checked 이벤트를 통해 그룹핑을 추가하고 RemoveChecked 이벤트를 통해 그룹핑을 제거 할 수 있도록 CheckBox를 선언 합니다. 1: <!-- Group CheckBox --> 2: <CheckBox Grid.Column="0" 3: Grid.Row="0" 4: Checked="AddGrouping" 5: Unchecked="RemoveGrouping">Group by Name</CheckBox> 그룹 스타일 선언 GroupStyle 속성에 ContainerStyle 속성을 이용해 Style을 지정 합니다. Expander 컨트롤을 이용해 아파트명과 그룹 아이템의 개수를 Expander Header에 표시 하도록 ControlTemlate를 선언 합니다. 1: <!-- Group Style --> 2: <ListView.GroupStyle> 3: <GroupStyle> 4: <GroupStyle.ContainerStyle> 5: <Style TargetType="{x:Type GroupItem}"> 6: <Setter Property="Margin" Value="0,0,0,5" /> 7: <Setter Property="Te...

MSDN WPF 샘플 따라하기 - DialogBox

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:      }  
























댓글

이 블로그의 인기 게시물

[C#] Task 완료 시 다른 Task를 자동으로 수행

[C#] 태스크(Task)가 완료될 때 까지 대기하여 결과를 얻는 방법

[C#] 명시적으로 Task 생성 및 실행