Windows Presentation Foundation 시작

업데이트: 2007년 11월

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

이 항목에는 다음 단원이 포함되어 있습니다.

  • 요약
  • 사전 요구 사항
  • 응용 프로그램 코드 파일 만들기
  • 응용 프로그램 빌드 및 실행
  • 레이아웃 추가
  • 컨트롤 추가
  • 이미지 및 제목 추가
  • 이벤트를 처리할 코드 추가
  • ExpenseReportPage의 UI 만들기
  • 코드를 추가하여 컨트롤의 스타일 지정
  • 컨트롤에 데이터 바인딩
  • 컨트롤에 데이터 연결
  • 데이터 템플릿을 사용하여 데이터에 스타일 추가
  • 최선의 구현 방법
  • 새로운 기능
  • 관련 항목

요약

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

  • XAML 태그를 정의하여 응용 프로그램의 UI(사용자 인터페이스) 모양 디자인

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

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

  • 컨트롤 및 레이아웃을 추가하여 응용 프로그램 UI 구성

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

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

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

이 자습서를 빌드하는 데 사용되는 샘플 코드는 C# 및 Microsoft Visual Basic .NET에서 모두 사용할 수 있습니다. Windows Presentation Foundation 응용 프로그램 빌드 소개를 참조하십시오.

사전 요구 사항

이 자습서에서 개발하는 응용 프로그램을 빌드하려면 Microsoft .NET Framework과 Windows SDK(소프트웨어 개발 키트)를 모두 설치해야 합니다.

이 두 프로그램을 설치하면 명령 창에서 응용 프로그램을 빌드할 수 있습니다. 그러나 원하는 경우 Microsoft Visual Studio와 같이 IDE(통합 개발 환경)를 사용할 수 있습니다. 명령 프롬프트에서 빌드하려면 Windows SDK(소프트웨어 개발 키트)가 함께 설치된 명령 창을 사용해야 합니다. 명령 창은 다음 메뉴 위치에 있습니다.

  • 시작 메뉴 | 모든 프로그램 | Microsoft Windows SDK | CMD Shell

다음 단계에 따라 Windows 명령 프롬프트를 열 수도 있습니다.

  1. 시작 메뉴에서 실행을 선택합니다.

  2. 다음을 입력합니다.

    C:\WINDOWS\system32\cmd.exe /E:ON /V:ON /T:0E /K "C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\SetEnv.Cmd"

  3. 확인을 누릅니다.

SetEnv.cmd는 명령 프롬프트에서 WPF 응용 프로그램을 빌드하는 데 필요한 환경을 설정합니다.

응용 프로그램 코드 파일 만들기

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

  1. App.xaml이라는 새 XAML 태그를 만듭니다. 이 파일은 WPF 응용 프로그램을 정의합니다. 이 파일을 사용하여 응용 프로그램 시작 시 UI(이 경우 다음 단계에서 만드는 HomePage.xaml)가 자동으로 표시되도록 지정할 수도 있습니다. XAML 태그는 다음과 같습니다.

    <Application 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      StartupUri="HomePage.xaml">
    </Application>
    
  2. HomePage.xaml이라는 새 XAML 태그 파일을 만듭니다. 이 파일은 응용 프로그램 시작 시 표시되는 첫 페이지가 됩니다. HomePage.xaml은 사용자가 비용 보고서를 표시할 사람을 선택할 수 있는 사람 목록을 표시합니다. HomePage.xaml에 다음과 같은 구성으로 Page 요소를 추가합니다.

    • 브라우저의 제목 표시줄은 "ExpenseIt"입니다.

    • 브라우저의 너비는 장치에 관계없이 550픽셀입니다.

    • 브라우저의 높이는 장치에 관계없이 350픽셀입니다.

    • 페이지의 제목은 "ExpenseIt - Home"입니다.

    XAML 태그는 다음과 같습니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    </Page>
    
  3. HomePage.xaml.cs라는 새 코드 파일을 만듭니다. 이 파일은 HomePage.xaml에 선언된 이벤트를 처리할 코드를 포함하는 코드 숨김 파일입니다. 코드를 다음과 같이 편집해야 합니다.

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class HomePage : Page
        {
            public HomePage()
            {
                InitializeComponent();
            }
        }
    }
    
  4. ExpenseReportPage.xaml이라는 새 XAML 태그 파일을 만듭니다. Page 요소를 추가하고 "ExpenseIt - View Expense Report"를 페이지 제목으로 설정합니다. 이 페이지는 HomePage.xaml에서 선택한 사람의 비용 보고서를 표시합니다. XAML 태그는 다음과 같습니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.ExpenseReportPage"
      Title="ExpenseIt - View Expense Report">
    </Page>
    
  5. ExpenseReportPage.xaml.cs라는 새 파일을 만듭니다. 이 파일은 ExpenseReportPage.xaml에 정의된 UI에 비용 보고서 데이터를 바인딩하는 코드 숨김 파일입니다. 코드를 다음과 같이 편집해야 합니다.

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class ExpenseReportPage : Page
        {
            public ExpenseReportPage()
            {
                InitializeComponent();
            }
        }
    }
    
  6. 이전 단계에서 만든 다섯 개의 코드 파일과 동일한 폴더에 watermark.png라는 이미지를 추가합니다. 이미지를 직접 만들거나 샘플 코드에서 같은 이름의 파일을 복사할 수 있습니다.

응용 프로그램 빌드 및 실행

이 단계에서는 이전 단원에서 정의한 응용 프로그램을 MSBuild를 사용하여 빌드합니다.

  1. ExpenseIt.csproj라는 새 파일을 만듭니다. 이 파일은 응용 프로그램의 빌드 구성과 다음을 포함하는 특수 XML 파일인 MSBuild 파일이 됩니다.

    • 빌드된 어셈블리의 이름, 빌드할 어셈블리의 형식, 빌드된 어셈블리를 추가할 폴더 등을 비롯하여 컴파일된 프로젝트에 대한 전역 빌드 변수

    • 코드 파일에 대한 참조

    • 응용 프로그램에서 사용하는 형식을 포함하는 Microsoft .NET Framework 어셈블리에 대한 참조

    빌드 파일의 내용은 다음과 같습니다.

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
        <PropertyGroup>
            <AssemblyName>ExpenseIt</AssemblyName>
            <TargetType>winexe</TargetType>
            <OutputPath>bin\$(Configuration)\</OutputPath>
        </PropertyGroup>
        <ItemGroup>
            <Reference Include="System"/>
            <Reference Include="System.Xml"/>
            <Reference Include="System.Data"/>
            <Reference Include="WindowsBase"/>
            <Reference Include="PresentationCore"/>
            <Reference Include="PresentationFramework"/>
        </ItemGroup>
        <ItemGroup>
            <ApplicationDefinition Include="App.xaml"/>
            <Page Include="HomePage.xaml"/>
            <Compile Include="HomePage.xaml.cs" />
            <Page Include="ExpenseReportPage.xaml"/>
            <Compile Include="ExpenseReportPage.xaml.cs" />
            <Resource Include="watermark.png"/>
        </ItemGroup>
        <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/>
        <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets"/>
    </Project>
    
  2. 명령 창에서 프로젝트 파일 및 응용 프로그램 코드 파일과 같은 폴더를 엽니다.

  3. 명령 프롬프트에서 다음 명령을 실행합니다.

    MSBuild ExpenseIt.csproj

    Microsoft Visual Basic .NET의 경우 대신 다음 명령을 실행합니다.

    MSBuild ExpenseIt.vbproj

    Visual Studio를 사용하여 응용 프로그램을 컴파일하고 실행하려면 Visual Studio에서 프로젝트 파일을 열고 F5 키를 누릅니다.

참고

Visual Studio 2005는 프로젝트 파일을 자동으로 생성합니다. 이 자습서에서는 Visual Studio가 설치되어 있지 않다고 가정하므로 프로젝트 파일을 만드는 프로세스를 자세히 설명합니다. .csproj 파일을 만드는 방법에 대한 자세한 내용은 WPF 응용 프로그램 만들기(WPF)를 참조하십시오. Visual Studio를 사용하여 이 자습서를 수행하는 경우에는 생성된 .csproj 파일의 내용을 앞의 MSBuild 텍스트로 덮어쓰십시오.

  1. 빌드된 응용 프로그램 실행 파일 expenseit.exe가 포함된 폴더를 엽니다. 명령 프롬프트에서 빌드한 경우 expenseit.exe는 다음 폴더에 있습니다.

    Folder Containing Application Code Files\bin\

    Visual Studio를 사용하여 빌드한 경우에는 expenseit.exe가 대신 다음 폴더에 있습니다.

    Folder Containing Application Code Files\bin\debug\

  2. 명령 프롬프트에서 expenseit.exe를 실행합니다. 다음 그림에서는 실행 중인 응용 프로그램을 보여 줍니다.

    ExpenseIt 샘플 스크린 샷

레이아웃 추가

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

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

참고

Panel 요소에 대한 자세한 내용은 Panel 개요를 참조하십시오.

다음 XAML 태그는 HomePage.xaml에 Grid를 추가하여 세 개의 행과 10픽셀의 여백이 있는 단일 열 표를 만듭니다.

  1. HomePage.xaml을 엽니다.

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

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
        <Grid Margin="10">
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
        </Grid>
    </Page>
    

컨트롤 추가

이 단계에서는 사용자가 선택한 사람에 대한 비용 보고서를 표시하기 위해 선택할 수 있는 사람 목록이 표시되도록 홈 페이지 UI를 업데이트합니다. 이 UI를 만들려면 HomePage.xaml에 다음 요소를 추가합니다.

  • ListBox(사람 목록에 사용)

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

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

다음 단계에 따라 HomePage.xaml을 업데이트합니다.

  1. HomePage.xaml 파일의 내용을 다음 XAML로 덮어씁니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    
      <Grid Margin="10">
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
          <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
    
        <!-- 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>
    
      </Grid>
    
    </Page>
    
  2. 응용 프로그램을 컴파일하여 실행합니다.

다음 그림에서는 이 단계의 코드로 만든 컨트롤을 보여 줍니다.

ExpenseIt 샘플 스크린 샷

이미지 및 제목 추가

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

  1. HomePage.xaml을 엽니다.

  2. HomePage.xaml 파일의 내용을 다음 XAML로 덮어씁니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    
      <Grid>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Source="watermark.png" />
          </Canvas>
          <Label VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
            View Expense Report
          </Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
    
          <!-- 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>
    
        </Grid>
    
      </Grid>
    </Page>
    

    이 XAML은 Grid를 다음과 같이 업데이트합니다.

    • 두 개의 행을 포함하는 새 표를 만듭니다.

    • Canvas, ImageLabel을 포함하는 DockPanel을 첫 번째 행에 추가합니다. 이 DockPanel은 첫 번째 행의 두 열에 걸쳐 있으므로 왼쪽에 도킹되는 Canvas와 함께 사용하면 LabelImage와 겹칠 수 있습니다.

    • Image 요소의 Source 특성을 사용하여 소스 이미지 watermark.png를 지정합니다.

    • Label에 "View Expense Report"라는 제목 텍스트를 추가합니다.

    • CanvasLabel의 특성을 사용하여 해당 모양과 크기를 구성합니다.

    • 원래 HomePage.xaml에 포함된 표를 새 표에 있는 두 번째 행의 두 번째 열로 이동합니다.

  3. 응용 프로그램을 컴파일하여 실행합니다.

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

ExpenseIt 샘플 스크린 샷

이벤트를 처리할 코드 추가

  1. HomePage.xaml을 엽니다.

  2. 이전 단계에서 정의한 Button 요소를 다음 코드로 덮어씁니다.

    ...
    <!-- View report button -->
    <Button Grid.Column="0" Grid.Row="2" Width="125" Height="25" 
      Margin="0,10,0,0" HorizontalAlignment="Right" 
      Click="viewButton_Click">View</Button>
    ...
    

    참고

    처리할 Button 이벤트의 이름은 Click입니다. 개발자가 정의한 이벤트 처리기의 이름은 viewButton_Click입니다. 이 이벤트 처리기는 Button 컨트롤의 Click 이벤트에 등록됩니다.

  3. 이 자습서의 응용 프로그램 코드 파일 만들기 단계에서 만든 HomePage.xaml.cs를 엽니다.

  4. 파일의 내용을 다음 코드로 덮어씁니다. 그러면 ExpenseReportPage.xaml 파일을 탐색하는 Click 이벤트 처리 코드가 추가됩니다.

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class HomePage : Page
        {
            public HomePage()
            {
                InitializeComponent();
            }
            private void viewButton_Click(object sender, RoutedEventArgs args)
            {
                // View Expense Report
                ExpenseReportPage expenseReportPage = new ExpenseReportPage();
                this.NavigationService.Navigate(expenseReportPage);
            }
        }
    }
    

ExpenseReportPage의 UI 만들기

ExpenseReportPage.xaml은 HomePage.xaml에서 선택한 사람의 비용 보고서를 표시합니다. 다음 업데이트는 컨트롤과 레이아웃을 추가하여 ExpenseReportPage.xaml의 기본 UI를 만듭니다. 또한 다양한 UI 요소에 배경 및 채우기 색을 추가합니다.

  1. ExpenseReportPage.xaml 파일을 열고 다음 코드를 추가합니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.ExpenseReportPage"
      Title="ExpenseIt - View Expense Report">
    
      <Grid>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Source="watermark.png" />
          </Canvas>
          <Label VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
            Expense Report For:
          </Label>
        </DockPanel>
    
        <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="3">
    
            <Grid.ColumnDefinitions>
              <ColumnDefinition />
              <ColumnDefinition Width="10" />
              <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition />
            </Grid.RowDefinitions>
    
            <!-- Expense type list -->
            <Border Grid.Column="0" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4">
              <Label VerticalAlignment="Center" Foreground="White">Expense Type</Label>
            </Border>
            <ListBox Grid.Column="0" Grid.Row="1" />
    
            <!-- Amount list -->
            <Border Grid.Column="2" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4">
              <Label VerticalAlignment="Center" Foreground="White">Amount</Label>
            </Border>
            <ListBox Grid.Column="2" Grid.Row="1" />
    
          </Grid>
        </Grid>
      </Grid>
    </Page>
    
  2. 응용 프로그램을 컴파일하여 실행합니다.

다음 그림에서는 ExpenseReportPage.xaml에 추가된 UI 요소를 보여 줍니다.

ExpenseIt 샘플 스크린 샷

코드를 추가하여 컨트롤의 스타일 지정

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

  1. 이 자습서의 응용 프로그램 코드 파일 만들기 단계에서 만든 App.xaml 파일을 엽니다.

  2. 파일의 내용을 다음 XAML 태그로 덮어씁니다.

    <Application 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      StartupUri="HomePage.xaml">
    
      <Application.Resources>
    
        <!-- Background image style -->
        <Style x:Key="backgroundImageStyle">
          <Setter Property="Image.Source" Value="watermark.png"/>
        </Style>
    
        <!-- 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>
    
        <!-- 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>
    
      </Application.Resources>
    
    </Application>
    

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

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

    • labelStyle: Label 레이블의 서식을 지정합니다.

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

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

    • buttonStyle: HomePage.xaml에 있는 단추의 서식을 지정합니다.

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

  3. HomePage.xaml을 엽니다.

  4. 파일의 내용을 다음 코드로 덮어씁니다. 이 단계에서는 각 요소의 모양 관련 특성을 적절한 스타일로 바꿉니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    
      <Grid>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Style="{StaticResource backgroundImageStyle}" />
          </Canvas>
          <Label Style="{StaticResource headerTextStyle}">View Expense Report</Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
    
          <!-- People list -->
          <Border Grid.Column="0" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
            <Label Style="{StaticResource listHeaderTextStyle}">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" Style="{StaticResource buttonStyle}" 
            Click="viewButton_Click">View
          </Button>
    
        </Grid>
    
      </Grid>
    
    </Page>
    
  5. ExpenseReportPage.xaml을 엽니다.

  6. 파일의 내용을 다음 코드로 덮어씁니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.ExpenseReportPage"
      Title="ExpenseIt - View Expense Report">
    
      <Grid>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Style="{StaticResource backgroundImageStyle}" />
          </Canvas>
          <Label Style="{StaticResource headerTextStyle}">Expense Report For:</Label>
        </DockPanel>
    
        <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="3">
    
            <Grid.ColumnDefinitions>
              <ColumnDefinition />
              <ColumnDefinition Width="10" />
              <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition />
            </Grid.RowDefinitions>
    
            <!-- Expense type list -->
            <Border Grid.Column="0" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
              <Label Style="{StaticResource listHeaderTextStyle}">Expense Type</Label>
            </Border>
            <ListBox Grid.Column="0" Grid.Row="1" />
    
            <!-- Amount list -->
            <Border Grid.Column="2" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
              <Label Style="{StaticResource listHeaderTextStyle}">Amount</Label>
            </Border>
            <ListBox Grid.Column="2" Grid.Row="1" />
    
          </Grid>
    
        </Grid>
    
      </Grid>
    
    </Page>
    
  7. 응용 프로그램을 컴파일하여 실행합니다. 이 단계에서 XAML 태그를 추가하면 응용 프로그램의 모양이 스타일을 사용하여 업데이트하기 전과 동일해집니다.

컨트롤에 데이터 바인딩

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

  1. HomePage.xaml을 엽니다.

  2. 파일의 내용을 다음 XAML 태그로 덮어씁니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    
      <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>
    
          <!-- Name item template -->
          <DataTemplate x:Key="nameItemTemplate">
            <Label Content="{Binding XPath=@Name}"/>
          </DataTemplate>
    
        </Grid.Resources>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Style="{StaticResource backgroundImageStyle}" />
          </Canvas>
          <Label Style="{StaticResource headerTextStyle}">View Expense Report</Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
    
          <!-- People list -->
          <Border Grid.Column="0" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
            <Label Style="{StaticResource listHeaderTextStyle}">Names</Label>
          </Border>
          <ListBox Name="peopleListBox" Grid.Column="0" Grid.Row="1" 
            ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}" 
            ItemTemplate="{StaticResource nameItemTemplate}" />
    
          <!-- View report button -->
          <Button Grid.Column="0" Grid.Row="2" Style="{StaticResource buttonStyle}" 
            Click="viewButton_Click">View</Button>
    
        </Grid>
    
      </Grid>
    
    </Page>
    

    데이터는 Grid 리소스로 만들어집니다.

컨트롤에 데이터 연결

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

  1. HomePage.xaml.cs를 엽니다.

  2. 파일의 내용을 다음 코드로 덮어씁니다.

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class HomePage : Page
        {
            public HomePage()
            {
                InitializeComponent();
            }
    
            private void viewButton_Click(object sender, RoutedEventArgs args)
            {
                // Create a new expense report page and pass it the selected person
                // by using the non-default constructor.
                ExpenseReportPage expenseReportPage = 
                    new ExpenseReportPage(this.peopleListBox.SelectedItem);
    
                // Navigate to the expense report page,
                this.NavigationService.Navigate(expenseReportPage);
            }
        }
    }
    
  3. ExpenseReportPage.xaml.cs를 엽니다.

  4. 파일의 내용을 다음 코드로 덮어씁니다.

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class ExpenseReportPage : Page
        {
            public ExpenseReportPage(object data)
            {
                InitializeComponent();
    
                // Bind to expense report data.
                this.DataContext = data;
            }
        }
    }
    

데이터 템플릿을 사용하여 데이터에 스타일 추가

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

  1. ExpenseReportPage.xaml을 엽니다.

  2. 파일의 내용을 다음 코드로 덮어씁니다.

    <Page 
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.ExpenseReportPage"
      Title="ExpenseIt - View Expense Report">
    
      <Grid>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Style="{StaticResource backgroundImageStyle}" />
          </Canvas>
          <Label Style="{StaticResource headerTextStyle}">Expense Report For:</Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <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>
    
          <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 Content="{Binding XPath=@Name}" Style="{StaticResource labelStyle}"/>
          </StackPanel>
    
          <!-- Department -->
          <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Department:</Label>
            <Label Content="{Binding XPath=@Department}" Style="{StaticResource labelStyle}"/>
          </StackPanel>
          <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3">
    
            <Grid.ColumnDefinitions>
              <ColumnDefinition />
              <ColumnDefinition Width="10" />
              <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition />
            </Grid.RowDefinitions>
    
            <!-- Expense type list -->
            <Border Grid.Column="0" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
              <Label Style="{StaticResource listHeaderTextStyle}">Expense Type</Label>
            </Border>
            <ListBox Grid.Column="0" Grid.Row="1" ItemsSource="{Binding XPath=Expense}" 
              ItemTemplate="{StaticResource typeItemTemplate}" />
    
            <!-- Amount list -->
            <Border Grid.Column="2" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
              <Label Style="{StaticResource listHeaderTextStyle}">Amount</Label>
            </Border>
            <ListBox Grid.Column="2" Grid.Row="1" ItemsSource="{Binding XPath=Expense}" 
              ItemTemplate="{StaticResource amountItemTemplate}" />
    
          </Grid>
    
        </Grid>
    
      </Grid>
    
    </Page>
    
  3. 응용 프로그램을 컴파일하여 실행합니다.

데이터 템플릿은 Grid 리소스로 정의됩니다.

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

ExpenseIt 샘플 스크린 샷

최선의 구현 방법

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

내게 필요한 옵션 - 액세스 가능성에 대한 유용한 정보

보안 - Windows Presentation Foundation 보안

지역화 - WPF 전역화 및 지역화 개요

WPF 응용 프로그램 성능 최적화

새로운 기능

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

패널에 대해서는 Panel 개요에서 자세히 다룹니다. 데이터 템플릿에 대해서는 데이터 템플릿 개요에서 자세히 다룹니다.

참고 항목

개념

레이아웃 시스템

Panel 개요

데이터 바인딩 개요

데이터 템플릿 개요

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