연습: WPF 시작

업데이트: 2010년 12월

이 연습에서는 Extensible Application Markup Language (XAML) 태그, 코드 숨김, 응용 프로그램 정의, 컨트롤, 레이아웃, 데이터 바인딩, 스타일 등 대부분의 WPF 응용 프로그램에 공통적인 요소를 포함하는 Windows Presentation Foundation (WPF) 응용 프로그램의 개발에 대해 소개합니다.

이 연습에서는 다음 단계에 따라 간단한 WPF 응용 프로그램을 개발하는 과정을 보여 줍니다.

  • XAML을 정의하여 응용 프로그램의 user interface (UI) 모양 디자인

  • 코드를 작성하여 응용 프로그램 동작 빌드

  • 응용 프로그램 정의를 만들어 응용 프로그램 관리

  • 컨트롤을 추가하고 레이아웃을 만들어 응용 프로그램 UI 구성

  • 스타일을 만들어 응용 프로그램 UI 전체에서 일관된 모양 유지

  • UI를 데이터에 바인딩하여 데이터에서 UI를 채우고 데이터와 UI를 동기화된 상태로 유지

이 연습을 마치면 사용자가 선택한 사람에 대한 비용 보고서를 보는 데 사용할 수 있는 독립 실행형 Windows 응용 프로그램이 빌드됩니다. 이 응용 프로그램은 브라우저 스타일 창에 호스팅되는 여러 WPF 페이지로 구성됩니다.

이 연습을 빌드하는 데 사용되는 샘플 코드는 Microsoft Visual Basic 및 C#에서 모두 사용할 수 있습니다. Introduction to Building WPF Applications를 참조하십시오.

사전 요구 사항

이 연습을 완료하려면 다음 구성 요소가 필요합니다.

  • Visual Studio 2010

Visual Studio 설치에 대한 자세한 내용은 Visual Studio 설치를 참조하십시오.

응용 프로그램 프로젝트 만들기

이 단원에서는 응용 프로그램 정의, 두 개의 페이지 및 이미지를 포함하는 응용 프로그램 인프라를 만듭니다.

  1. Visual Basic 또는 Visual C#에서 ExpenseIt라는 새 WPF 응용 프로그램 프로젝트를 만듭니다. 자세한 내용은 방법: 새 WPF 응용 프로그램 프로젝트 만들기를 참조하십시오.

    참고참고

    이 연습에서는 .NET Framework 4에서 사용할 수 있는 DataGrid 컨트롤을 사용합니다.따라서 프로젝트의 대상이 .NET Framework 4여야 합니다.자세한 내용은 방법: 특정 .NET Framework 버전 또는 프로필을 대상으로 지정을 참조하십시오.

  2. Application.xaml(Visual Basic) 또는 App.xaml(C#)을 엽니다.

    이 XAML 파일은 WPF 응용 프로그램과 응용 프로그램 리소스를 정의합니다. 이 파일을 사용하여 응용 프로그램 시작 시 자동으로 표시되는 UI(이 예제의 경우 MainWindow.xaml)를 지정할 수도 있습니다.

    XAML은 Visual Basic에서 다음과 같이 나타납니다.

    <Application x:Class="Application"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="MainWindow.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    

    C#에서는 다음과 같이 나타납니다.

    <Application x:Class="ExpenseIt.App"
         xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    
  3. MainWindow.xaml을 엽니다.

    이 XAML 파일은 응용 프로그램의 주 창이며 여러 페이지에서 만들어지는 콘텐츠를 표시합니다. Window 클래스에서는 제목, 크기 또는 아이콘 같은 창의 속성을 정의하고 닫기 또는 숨기기 같은 이벤트를 처리합니다.

  4. Window 요소를 NavigationWindow로 변경합니다.

    이 응용 프로그램은 사용자 상호 작용에 따라 다른 콘텐츠를 탐색합니다. 따라서 주 WindowNavigationWindow로 변경되어야 합니다. NavigationWindowWindow의 모든 속성을 상속합니다. XAML 파일에서 NavigationWindow 요소는 NavigationWindow 클래스의 인스턴스를 만듭니다. 자세한 내용은 탐색 개요를 참조하십시오.

  5. NavigationWindow 요소의 다음 속성을 변경합니다.

    • Title 속성을 "ExpenseIt"로 설정합니다.

    • Width 속성을 500픽셀로 설정합니다.

    • Height 속성을 350픽셀로 설정합니다.

    • NavigationWindow 태그 사이에 있는 Grid 요소를 제거합니다.

    XAML은 Visual Basic에서 다음과 같이 나타납니다.

    <NavigationWindow x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
    
    </NavigationWindow>
    

    C#에서는 다음과 같이 나타납니다.

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
    
    </NavigationWindow>
    
  6. MainWindow.xaml.vb 또는 MainWindow.xaml.cs를 엽니다.

    이 파일은 MainWindow.xaml에 선언된 이벤트를 처리할 코드를 포함하는 코드 숨김 파일입니다. 이 파일에는 XAML로 정의된 창에 대한 partial 클래스가 포함되어 있습니다.

  7. C#을 사용하는 경우에는 MainWindow 클래스가 NavigationWindow에서 파생되도록 변경합니다.

    Visual Basic에서는 창을 XAML에서 변경하면 자동으로 이와 같이 변경됩니다.

    코드는 다음과 같습니다.

    Class MainWindow
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : NavigationWindow
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    }
    

응용 프로그램에 파일 추가

이 단원에서는 두 페이지와 이미지를 응용 프로그램에 추가합니다.

  1. 새 페이지(WPF)를 ExpenseItHome.xaml이라는 프로젝트에 추가합니다. 자세한 내용은 방법: WPF 프로젝트에 새 항목 추가를 참조하십시오.

    이 페이지는 응용 프로그램이 시작될 때 가장 먼저 표시됩니다. 이 페이지에서는 사용자가 비용 보고서를 표시할 사람을 선택할 수 있는 사람 목록을 표시합니다.

  2. ExpenseItHome.xaml을 엽니다.

  3. Title을 "ExpenseIt - Home"으로 설정합니다.

    XAML은 Visual Basic에서 다음과 같이 나타납니다.

    <Page x:Class="ExpenseItHome"
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
      Title="ExpenseIt - Home">
        <Grid>
    
        </Grid>
    </Page>
    

    C#에서는 다음과 같이 나타납니다.

    <Page x:Class="ExpenseIt.ExpenseItHome"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
        Title="ExpenseIt - Home">
    
        <Grid>
    
        </Grid>
    </Page>
    
  4. MainWindow.xaml을 엽니다.

  5. NavigationWindowSource 속성을 "ExpenseItHome.xaml"로 설정합니다.

    이렇게 설정하면 응용 프로그램 시작 시 ExpenseItHome.xaml 페이지가 첫 번째로 열리게 됩니다. XAML은 Visual Basic에서 다음과 같이 나타납니다.

    <NavigationWindow x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    
    </NavigationWindow>
    

    C#에서는 다음과 같이 나타납니다.

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    
    </NavigationWindow>
    
  6. 새 페이지(WPF)를 ExpenseReportPage.xaml이라는 프로젝트에 추가합니다.

    이 페이지는 ExpenseItHome.xaml에서 선택한 사람의 비용 보고서를 표시합니다.

  7. ExpenseReportPage.xaml을 엽니다.

  8. Title을 "ExpenseIt - View Expense"로 설정합니다.

    XAML은 Visual Basic에서 다음과 같이 나타납니다.

    <Page x:Class="ExpenseReportPage"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
          Title="ExpenseIt - View Expense">
        <Grid>
    
        </Grid>
    </Page>
    

    C#에서는 다음과 같이 나타납니다.

    <Page x:Class="ExpenseIt.ExpenseReportPage"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
        Title="ExpenseIt - View Expense">
    
        <Grid>
    
        </Grid>
    </Page>
    
  9. ExpenseItHome.xaml.vb 및 ExpenseReportPage.xaml.vb를 열거나 ExpenseItHome.xaml.cs 및 ExpenseReportPage.xaml.cs를 엽니다.

    새 페이지 파일을 만들면 Visual Studio에서 자동으로 코드 숨김 파일을 만듭니다. 이러한 코드 숨김 파일은 사용자 입력에 응답하는 논리를 처리합니다.

    코드는 다음과 같습니다.

    Class ExpenseItHome
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for ExpenseItHome.xaml
        /// </summary>
        public partial class ExpenseItHome : Page
        {
            public ExpenseItHome()
            {
                InitializeComponent();
            }
        }
    }
    
    Class ExpenseReportPage
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for ExpenseReportPage.xaml
        /// </summary>
        public partial class ExpenseReportPage : Page
        {
            public ExpenseReportPage()
            {
                InitializeComponent();
            }
        }
    }
    
  10. watermark.png라는 이미지를 프로젝트에 추가합니다. 이미지를 직접 만들거나 샘플 코드에서 파일을 복사할 수 있습니다. 자세한 내용은 방법: 프로젝트에 기존 항목 추가를 참조하십시오.

응용 프로그램 빌드 및 실행

이 단원에서는 응용 프로그램을 빌드하고 실행합니다.

  1. F5 키를 눌러 응용 프로그램을 빌드 및 실행하거나 디버그 메뉴에서 디버깅 시작을 선택합니다.

    다음 그림에서는 NavigationWindow 단추가 있는 응용 프로그램을 보여 줍니다.

    ExpenseIt 샘플 스크린 샷

  2. 응용 프로그램을 닫고 Visual Studio로 돌아갑니다.

레이아웃 만들기

레이아웃을 사용하면 UI 요소를 순서대로 배치하고 UI의 크기 조정 시 이러한 요소의 크기와 위치를 관리할 수 있습니다. 일반적으로 다음과 같은 레이아웃 컨트롤 중 하나를 사용하여 레이아웃을 만듭니다.

이러한 각 레이아웃 컨트롤은 해당 자식 요소에 대해 특수 레이아웃 형식을 지원합니다. ExpenseIt 페이지는 크기를 조정할 수 있으며 각 페이지의 요소는 다른 요소와 수평 및 수직으로 정렬됩니다. 따라서 Grid가 응용 프로그램에 적합한 레이아웃 요소입니다.

참고참고

Panel 요소에 대한 자세한 내용은 Panel 개요를 참조하십시오.레이아웃에 대한 자세한 내용은 레이아웃 시스템을 참조하십시오.

이 단원에서는 ExpenseItHome.xaml의 Grid에 열 및 행 정의를 추가하여 여백이 10픽셀이고 행이 3개인 단일 열 테이블을 만듭니다.

  1. ExpenseItHome.xaml을 엽니다.

  2. Grid 요소의 Margin 속성을 왼쪽, 위쪽, 오른쪽 및 아래쪽 여백에 해당하는 값인 "10,0,10,10"으로 설정합니다.

  3. Grid 태그 사이에 다음 XAML을 추가하여 행 및 열 정의를 만듭니다. 

    <Grid.ColumnDefinitions>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    

    두 행의 Height는 행의 크기가 해당 행의 콘텐츠에 따라 결정됨을 의미하는 Auto로 설정됩니다. 기본 Height는 사용 가능한 공간에 대한 가중치에 따라 행의 높이가 결정됨을 의미하는 Star 크기 조정입니다. 예를 들어 두 행의 높이가 각각 "*"이면 사용 가능한 공간의 절반에 해당하는 높이를 갖게 됩니다.

    이제 Grid는 다음 XAML과 같습니다.

    <Grid Margin="10,0,10,10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
    </Grid>
    

컨트롤 추가

이 단원에서는 사용자가 선택한 사람에 대한 비용 보고서를 표시하기 위해 선택할 수 있는 사람 목록이 표시되도록 홈 페이지 UI를 업데이트합니다. 컨트롤은 사용자가 응용 프로그램과 상호 작용할 수 있게 하는 UI 개체입니다. 자세한 내용은 컨트롤를 참조하십시오.

이 UI를 만들려면 ExpenseItHome.xaml에 다음 요소를 추가합니다.

  • ListBox(사람 목록에 사용)

  • Label(목록 머리글에 사용)

  • Button(목록에서 선택한 사람의 비용 보고서를 보기 위해 클릭하는 데 사용)

각 컨트롤은 연결된 속성 Grid.Row를 설정하여 Grid의 행에 배치됩니다. 연결된 속성에 대한 자세한 내용은 연결된 속성 개요를 참조하십시오.

  1. ExpenseItHome.xaml을 엽니다.

  2. 다음 XAML을 Grid 태그 사이에 추가합니다.

    
      <!-- People list -->
      <Border Grid.Column="0" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4">
          <Label VerticalAlignment="Center" Foreground="White">Names</Label>
      </Border>
      <ListBox Name="peopleListBox" Grid.Column="0" Grid.Row="1">
          <ListBoxItem>Mike</ListBoxItem>
          <ListBoxItem>Lisa</ListBoxItem>
          <ListBoxItem>John</ListBoxItem>
          <ListBoxItem>Mary</ListBoxItem>
      </ListBox>
    
      <!-- View report button -->
      <Button Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Width="125"
    Height="25" HorizontalAlignment="Right">View</Button>
    
  3. 응용 프로그램을 빌드하고 실행합니다.

다음 그림에서는 XAML을 사용하여 이 단원에서 만든 컨트롤을 보여 줍니다.

ExpenseIt 샘플 스크린 샷

이미지 및 제목 추가

이 단원에서는 이미지와 페이지 제목을 사용하여 홈 페이지 UI를 업데이트합니다.

  1. ExpenseItHome.xaml을 엽니다.

  2. Width가 230픽셀로 고정된 ColumnDefinitions에 또 다른 열을 추가합니다.

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
  3. RowDefinitions에 다른 열을 추가합니다.

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
  4. Grid.Column을 1로 설정하여 컨트롤을 두 번째 열로 이동합니다. Grid.Row를 1로 늘려 행 아래로 각 컨트롤을 이동합니다.

      <Border Grid.Column="1" Grid.Row="1" Height="35" Padding="5" Background="#4E87D4">
          <Label VerticalAlignment="Center" Foreground="White">Names</Label>
      </Border>
      <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2">
          <ListBoxItem>Mike</ListBoxItem>
          <ListBoxItem>Lisa</ListBoxItem>
          <ListBoxItem>John</ListBoxItem>
          <ListBoxItem>Mary</ListBoxItem>
      </ListBox>
    
      <!-- View report button -->
      <Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125"
    Height="25" HorizontalAlignment="Right">View</Button>
    
  5. GridBackground를 watermark.png 이미지 파일로 설정합니다.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"/>
    </Grid.Background>
    
  6. Border 앞에 콘텐츠가 "View Expense Report"인 Label을 추가하여 해당 페이지의 제목으로 지정합니다.

    <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
        View Expense Report
    </Label>
    
  7. 응용 프로그램을 빌드하고 실행합니다.

다음 그림에서는 이 단원의 결과를 보여 줍니다.

ExpenseIt 샘플 스크린 샷

이벤트 처리 코드 추가

  1. ExpenseItHome.xaml을 엽니다.

  2. Button 요소에 Click 이벤트 처리기를 추가합니다. 자세한 내용은 방법: 단순한 이벤트 처리기 만들기를 참조하십시오.

      <!-- View report button -->
      <Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125"
    Height="25" HorizontalAlignment="Right" Click="Button_Click">View</Button>
    
  3. ExpenseItHome.xaml.vb 또는 ExpenseItHome.xaml.cs를 엽니다.

  4. 창이 ExpenseReportPage.xaml 파일을 탐색하도록 하는 다음 코드를 Click 이벤트 처리기에 추가합니다.

            Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                ' View Expense Report
                Dim expenseReportPage As New ExpenseReportPage()
                Me.NavigationService.Navigate(expenseReportPage)
    
            End Sub
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage();
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

ExpenseReportPage의 UI 만들기

ExpenseReportPage.xaml은 ExpenseItHome.xaml에서 선택한 사람의 비용 보고서를 표시합니다. 이 단원에서는 컨트롤을 추가하고 ExpenseReportPage.xaml 관련 UI를 만듭니다. 또한 이 단원에서는 UI 요소에 배경 및 채우기 색도 추가합니다.

  1. ExpenseReportPage.xaml을 엽니다.

  2. Grid 태그 사이에 다음 XAML을 추가합니다.

    이 UI는 보고서 데이터가 DataGrid에 표시된다는 점을 제외하고는 ExpenseItHome.xaml에 만든 UI와 비슷합니다.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png" />
    </Grid.Background>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    
    
    <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" 
    FontWeight="Bold" FontSize="18" Foreground="#0066cc">
        Expense Report For:
    </Label>
    <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
    
        <!-- Name -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
            <Label Margin="0,0,0,5" FontWeight="Bold">Name:</Label>
            <Label Margin="0,0,0,5" FontWeight="Bold"></Label>
        </StackPanel>
    
        <!-- Department -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal">
            <Label Margin="0,0,0,5" FontWeight="Bold">Department:</Label>
            <Label Margin="0,0,0,5" FontWeight="Bold"></Label>
        </StackPanel>
    
        <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Top" 
              HorizontalAlignment="Left">
            <!-- Expense type and Amount table -->
            <DataGrid  AutoGenerateColumns="False" RowHeaderWidth="0" >
                <DataGrid.ColumnHeaderStyle>
                    <Style TargetType="{x:Type DataGridColumnHeader}">
                        <Setter Property="Height" Value="35" />
                        <Setter Property="Padding" Value="5" />
                        <Setter Property="Background" Value="#4E87D4" />
                        <Setter Property="Foreground" Value="White" />
                    </Style>
                </DataGrid.ColumnHeaderStyle>
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ExpenseType" />
                    <DataGridTextColumn Header="Amount"  />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
    
  3. 응용 프로그램을 빌드하고 실행합니다.

    참고참고

    DataGrid를 찾지 못했다거나 이 컨트롤이 없다는 오류가 나타나면 프로젝트의 대상이 .NET Framework 4인지 확인합니다.자세한 내용은 방법: 특정 .NET Framework 버전 또는 프로필을 대상으로 지정을 참조하십시오.

  4. View 단추를 클릭합니다.

    비용 보고서 페이지가 나타납니다.

다음 그림에서는 ExpenseReportPage.xaml에 추가된 UI 요소를 보여 줍니다. 뒤로 탐색 단추는 사용할 수 없습니다.

ExpenseIt 샘플 스크린 샷

컨트롤 스타일 설정

UI에서는 같은 형식의 모든 요소에 대해 다양한 요소의 모양이 동일한 경우가 많습니다. UI에서는 스타일을 통해 여러 요소에서 모양을 다시 사용할 수 있습니다. 다시 사용 가능한 스타일을 통해 XAML 만들기 및 관리 작업이 간단해집니다. 스타일에 대한 자세한 내용은 스타일 지정 및 템플릿을 참조하십시오. 이 단원에서는 이전 단계에서 정의한 요소별 특성을 스타일로 바꿉니다.

  1. Application.xaml 또는 App.xaml을 엽니다.

  2. Application.Resources 태그 사이에 다음 XAML을 추가합니다.

    
    <!-- Header text style -->
    <Style x:Key="headerTextStyle">
        <Setter Property="Label.VerticalAlignment" Value="Center"></Setter>
        <Setter Property="Label.FontFamily" Value="Trebuchet MS"></Setter>
        <Setter Property="Label.FontWeight" Value="Bold"></Setter>
        <Setter Property="Label.FontSize" Value="18"></Setter>
        <Setter Property="Label.Foreground" Value="#0066cc"></Setter>
    </Style>
    
    <!-- Label style -->
    <Style x:Key="labelStyle" TargetType="{x:Type Label}">
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="Margin" Value="0,0,0,5" />
    </Style>
    
    <!-- DataGrid header style -->
    <Style x:Key="columnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Height" Value="35" />
        <Setter Property="Padding" Value="5" />
        <Setter Property="Background" Value="#4E87D4" />
        <Setter Property="Foreground" Value="White" />
    </Style>
    
    <!-- List header style -->
    <Style x:Key="listHeaderStyle" TargetType="{x:Type Border}">
        <Setter Property="Height" Value="35" />
        <Setter Property="Padding" Value="5" />
        <Setter Property="Background" Value="#4E87D4" />
    </Style>
    
    <!-- List header text style -->
    <Style x:Key="listHeaderTextStyle" TargetType="{x:Type Label}">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="HorizontalAlignment" Value="Left" />
    </Style>
    
    <!-- Button style -->
    <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
        <Setter Property="Width" Value="125" />
        <Setter Property="Height" Value="25" />
        <Setter Property="Margin" Value="0,10,0,0" />
        <Setter Property="HorizontalAlignment" Value="Right" />
    </Style>
    

    이 XAML에서는 다음 스타일을 추가합니다.

    • headerTextStyle: 페이지 제목 Label의 서식을 지정합니다.

    • labelStyle: Label 컨트롤의 서식을 지정합니다.

    • columnHeaderStyle: DataGridColumnHeader의 서식을 지정합니다.

    • listHeaderStyle: 목록 머리글 Border 컨트롤의 서식을 지정합니다.

    • listHeaderTextStyle: 목록 머리글 Label의 서식을 지정합니다.

    • buttonStyle: ExpenseItHome.xaml에 있는 Button의 서식을 지정합니다.

    스타일은 Application.Resources 속성 요소의 자식이며 리소스입니다. 이 위치의 스타일은 응용 프로그램의 모든 요소에 적용됩니다. .NET Framework 응용 프로그램의 리소스를 사용하는 예제는 방법: 응용 프로그램 리소스 사용을 참조하십시오.

  3. ExpenseItHome.xaml을 엽니다.

  4. Grid 요소 사이의 모든 내용을 다음 XAML로 바꿉니다.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"  />
    </Grid.Background>
    
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
    <!-- People list -->
    
    <Label Grid.Column="1" Style="{StaticResource headerTextStyle}" >
        View Expense Report
    </Label>
    
    <Border Grid.Column="1" Grid.Row="1" Style="{StaticResource listHeaderStyle}">
        <Label Style="{StaticResource listHeaderTextStyle}">Names</Label>
    </Border>
    <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2">
        <ListBoxItem>Mike</ListBoxItem>
        <ListBoxItem>Lisa</ListBoxItem>
        <ListBoxItem>John</ListBoxItem>
        <ListBoxItem>Mary</ListBoxItem>
    </ListBox>
    
    <!-- View report button -->
    <Button Grid.Column="1" Grid.Row="3" Click="Button_Click" Style="{StaticResource buttonStyle}">View</Button>
    

    각 컨트롤의 모양을 정의하는 VerticalAlignmentFontFamily 같은 속성은 스타일을 적용하면 제거 및 대체됩니다. 예를 들어 headerTextStyle은 Label "View Expense Report"에 적용됩니다.

  5. ExpenseReportPage.xaml을 엽니다.

  6. Grid 요소 사이의 모든 내용을 다음 XAML로 바꿉니다.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png" />
    </Grid.Background>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    
    
    <Label Grid.Column="1" Style="{StaticResource headerTextStyle}">
        Expense Report For:
    </Label>
    <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
    
        <!-- Name -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Name:</Label>
            <Label Style="{StaticResource labelStyle}"></Label>
        </StackPanel>
    
        <!-- Department -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" 
    Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Department:</Label>
            <Label Style="{StaticResource labelStyle}"></Label>
        </StackPanel>
    
        <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Top" 
              HorizontalAlignment="Left">
            <!-- Expense type and Amount table -->
            <DataGrid ColumnHeaderStyle="{StaticResource columnHeaderStyle}" 
                      AutoGenerateColumns="False" RowHeaderWidth="0" >
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ExpenseType" />
                    <DataGridTextColumn Header="Amount"  />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
    

    이렇게 하면 LabelBorder 요소에 스타일이 추가됩니다.

  7. 응용 프로그램을 빌드하고 실행합니다.

    이 단원에서 XAML을 추가하면 응용 프로그램의 모양이 스타일을 사용하여 업데이트하기 전과 동일해집니다.

컨트롤에 데이터 바인딩

이 단원에서는 다양한 컨트롤에 바인딩되는 XML 데이터를 만듭니다.

  1. ExpenseItHome.xaml을 엽니다.

  2. Grid 요소를 연 후 다음 XAML을 추가하여 각 개인에 대한 데이터를 포함하는 XmlDataProvider를 만듭니다.

    데이터는 Grid 리소스로 만들어집니다. 일반적으로 이 데이터는 파일로 로드되지만 간단하게 인라인으로 추가될 수도 있습니다.

    <Grid.Resources>
    
    
    ...
    
    
    <!-- Expense Report Data -->
    <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
        <x:XData>
            <Expenses >
                <Person Name="Mike" Department="Legal">
                    <Expense ExpenseType="Lunch" ExpenseAmount="50" />
                    <Expense ExpenseType="Transportation" ExpenseAmount="50" />
                </Person>
                <Person Name="Lisa" Department="Marketing">
                    <Expense ExpenseType="Document printing"
          ExpenseAmount="50"/>
                    <Expense ExpenseType="Gift" ExpenseAmount="125" />
                </Person>
                <Person Name="John" Department="Engineering">
                    <Expense ExpenseType="Magazine subscription" 
         ExpenseAmount="50"/>
                    <Expense ExpenseType="New machine" ExpenseAmount="600" />
                    <Expense ExpenseType="Software" ExpenseAmount="500" />
                </Person>
                <Person Name="Mary" Department="Finance">
                    <Expense ExpenseType="Dinner" ExpenseAmount="100" />
                </Person>
            </Expenses>
        </x:XData>
    </XmlDataProvider>
    
    
    ...
    
    
    </Grid.Resources>
    
  3. Grid 리소스에서 다음 DataTemplate을 추가하여 ListBox에서 데이터가 표시되는 방식을 정의합니다. 데이터 템플릿에 대한 자세한 내용은 데이터 템플릿 개요를 참조하십시오.

    <Grid.Resources>
    
    
    ...
    
    
    <!-- Name item template -->
    <DataTemplate x:Key="nameItemTemplate">
        <Label Content="{Binding XPath=@Name}"/>
    </DataTemplate>
    
    
    ...
    
    
    </Grid.Resources>
    
  4. 기존 ListBox를 다음 XAML로 바꿉니다.

    <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
             ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
             ItemTemplate="{StaticResource nameItemTemplate}">
    </ListBox>
    

    이 XAML은 ListBoxItemsSource 속성을 데이터 소스에 바인딩하고 데이터 템플릿을 ItemTemplate으로 적용합니다.

컨트롤에 데이터 연결

이 단원에서는 ExpenseItHome.xaml의 사람 목록에서 선택한 현재 항목을 검색하는 코드를 작성하고 인스턴스화 중 이에 대한 참조를 ExpenseReportPage의 생성자에 전달합니다. ExpenseReportPage는 전달된 항목을 사용하여 해당 데이터 컨텍스트를 설정하고 ExpenseReportPage.xaml에서 정의한 컨트롤을 이 컨텍스트에 바인딩합니다.

  1. ExpenseReportPage.xaml.vb 또는 ExpenseReportPage.xaml.cs를 엽니다.

  2. 선택한 사람의 비용 보고서 데이터를 전달할 수 있도록 개체를 받아들이는 생성자를 추가합니다.

        Partial Public Class ExpenseReportPage
            Inherits Page
            Public Sub New()
                InitializeComponent()
            End Sub
    
            ' Custom constructor to pass expense report data
            Public Sub New(ByVal data As Object)
                Me.New()
                ' Bind to expense report data.
                Me.DataContext = data
            End Sub
    
        End Class
    
    public partial class ExpenseReportPage : Page
    {
        public ExpenseReportPage()
        {
            InitializeComponent();
        }
    
        // Custom constructor to pass expense report data
        public ExpenseReportPage(object data):this()
        {
            // Bind to expense report data.
            this.DataContext = data;
        }
    
    }
    
  3. ExpenseItHome.xaml.vb 또는 ExpenseItHome.xaml.cs를 엽니다.

  4. 선택한 사람의 비용 보고서 데이터를 전달하는 새 생성자를 호출하도록 Click 이벤트 처리기를 변경합니다.

            Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                ' View Expense Report
                Dim expenseReportPage As New ExpenseReportPage(Me.peopleListBox.SelectedItem)
                Me.NavigationService.Navigate(expenseReportPage)
    
            End Sub
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

데이터 템플릿을 사용하여 데이터에 스타일 지정

이 단원에서는 데이터 바인딩된 목록의 각 항목에 대한 UI를 데이터 템플릿을 사용하여 업데이트합니다.

  1. ExpenseReportPage.xaml을 엽니다.

  2. "Name" 및 "Department" Label 요소의 콘텐츠를 해당하는 데이터 소스에 올바르게 바인딩합니다. 데이터 바인딩에 대한 자세한 내용은 데이터 바인딩 개요를 참조하십시오.

    <!-- Name -->
    <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
        <Label Style="{StaticResource labelStyle}">Name:</Label>
        <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Name}"></Label>
    </StackPanel>
    
    <!-- Department -->
    <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal">
        <Label Style="{StaticResource labelStyle}">Department:</Label>
        <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Department}"></Label>
    </StackPanel>
    
  3. Grid 요소를 연 후 비용 보고서 데이터 표시 방법을 정의하는 다음 데이터 템플릿을 추가합니다.

    <!--Templates to display expense report data-->
    <Grid.Resources>
        <!-- Reason item template -->
        <DataTemplate x:Key="typeItemTemplate">
            <Label Content="{Binding XPath=@ExpenseType}"/>
        </DataTemplate>
        <!-- Amount item template -->
        <DataTemplate x:Key="amountItemTemplate">
            <Label Content="{Binding XPath=@ExpenseAmount}"/>
        </DataTemplate>
    </Grid.Resources>
    
  4. 비용 보고서 데이터를 표시하는 템플릿을 DataGrid 열에 추가합니다.

    <!-- Expense type and Amount table -->
    <DataGrid ItemsSource="{Binding XPath=Expense}" ColumnHeaderStyle="{StaticResource columnHeaderStyle}" AutoGenerateColumns="False" RowHeaderWidth="0" >
    
        <DataGrid.Columns>
            <DataGridTextColumn Header="ExpenseType" Binding="{Binding XPath=@ExpenseType}"  />
            <DataGridTextColumn Header="Amount" Binding="{Binding XPath=@ExpenseAmount}" />
        </DataGrid.Columns>
    
    </DataGrid>
    
  5. 응용 프로그램을 빌드하고 실행합니다.

  6. 사람을 선택하고 View 단추를 클릭합니다.

다음 그림에서는 컨트롤, 레이아웃, 스타일, 데이터 바인딩 및 데이터 템플릿을 적용한 ExpenseIt 응용 프로그램의 두 페이지를 보여 줍니다.

ExpenseIt 샘플 스크린 샷

최선의 구현 방법

이 샘플에서는 WPF의 특정 기능에 대해 설명하므로 최선의 응용 프로그램 개발 방법을 따르지 않습니다. WPF 및 .NET Framework 응용 프로그램 개발을 위한 최선의 방법에 대한 자세한 내용은 다음에서 적절한 항목을 참조하십시오.

새로운 기능

Windows Presentation Foundation (WPF)을 사용하여 UI를 만들 수 있는 여러 기술을 배웠습니다. 이제 데이터 바인딩된 .NET Framework 응용 프로그램의 기본 빌딩 블록에 대해 잘 이해할 것입니다. 이 항목에서는 모든 내용을 다루지는 않지만 이 항목에 제공된 기술 이외의 새로운 가능성을 탐색하는 계기를 스스로 마련해 볼 수 있습니다.

WPF 아키텍처 및 프로그래밍 모델에 대한 자세한 내용은 다음 항목을 참조하십시오.

응용 프로그램 만들기에 대한 자세한 내용은 다음 도움말 항목을 참조하십시오.

참고 항목

개념

Panel 개요

데이터 템플릿 개요

WPF 응용 프로그램 만들기(WPF)

기타 리소스

스타일 및 템플릿

변경 기록

날짜

변경 내용

이유

2010년 12월

.NET Framework 4를 대상으로 지정할 때의 참고 사항을 추가했습니다.

향상된 기능 관련 정보