演练:用 WPF 设计器生成简单的 WPF 应用程序

更新:2007 年 11 月

本演练演示如何使用 WPF 设计器生成简单的 Windows Presentation Foundation (WPF) 应用程序。 

在本演练中,您将执行下列任务:

  • 创建项目。

  • 创建布局。

  • 向布局添加控件。

  • 设置与布局相关的属性。

  • 创建数据源。

  • 连接到数据源。

  • 绑定控件属性。

在完成本演练后,您将具有一个可用来浏览文件系统的简单应用程序。该应用程序的用户界面将用可扩展应用程序标记语言 (XAML) 来实现。有关更多信息,请参见 XAML。下面的插图说明您的应用程序将如何显示。

FolderExplorer 树视图和列表视图

说明:

显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您的当前设置或版本。若要更改设置,请在“工具”菜单上选择“导入和导出设置”。有关更多信息,请参见 Visual Studio 设置

先决条件

您需要以下组件来完成本演练:

  • Visual Studio 2008。

创建项目

第一步是为应用程序创建项目。

创建项目

  1. 使用 Visual Basic 或 Visual C# 创建一个名为 FolderExplorer 的新 WPF 应用程序项目。有关更多信息,请参见如何:创建新的 WPF 应用程序项目

    Window1.xaml 在 WPF 设计器中打开。

  2. 在“设计”视图中,选择该窗口。有关更多信息,请参见如何:在设计图面上选择和移动元素

  3. 在“属性”窗口中,将 Title 属性的值设置为 Folder Explorer。

创建布局

布局定义控件在应用程序的主窗口中的排列方式。下面的步骤演示如何构造将包含应用程序控件的布局元素。

创建布局

  1. 在窗口上选择 Grid 根控件。

  2. 向网格中添加第二行。有关更多信息,请参见如何:向网格中添加行和列

  3. 向网格中添加第二列。

向布局添加控件

定义了布局后,可用控件来填充布局。只需在“工具箱”中单击所需控件并将该控件拖动到设计图面上。

向布局添加控件

  1. 从“工具箱”中将一个 TreeView 控件拖动到网格的第一个单元格中。根据需要调整该控件的大小。

  2. 从“工具箱”中将一个 ListView 控件拖动到占据网格第一行第二列的单元格中。根据需要调整该控件的大小。

  3. 从“工具箱”中将一个 ListView 控件拖动到占据网格第二行第二列的单元格中。根据需要调整该控件的大小。

设置与布局相关的属性

下面的步骤演示如何对控件设置与布局相关的属性。在对每个控件设置属性时,布局将越来越接近最终的应用程序。

设置与布局相关的属性

  1. 选择 TreeView 控件。

  2. 在“属性”窗口中,如下所示设置下列属性。

    属性

    Grid.ColumnSpan

    1

    Grid.RowSpan

    2

    Height

    Auto

    HorizontalAlignment

    Stretch

    Margin

    0,0,0,0

    VerticalAlignment

    Stretch

    Width

    Auto

    TreeView 控件将调整大小,以适合第一个网格列,并跨越两个网格行。

  3. 同时选择两个 ListView 控件。

  4. 在“属性”窗口中,如下所示设置下列属性。

    属性

    Grid.ColumnSpan

    1

    Grid.RowSpan

    1

    Height

    Auto

    HorizontalAlignment

    Stretch

    Margin

    0,0,0,0

    VerticalAlignment

    Stretch

    Width

    Auto

    ListView 控件将调整大小,以适合其各自的网格单元格。

  5. 在“文档大纲”窗口中,展开网格的“ColumnDefinitions”节点。有关更多信息,请参见浏览 WPF 文档的元素层次结构

  6. 选择第一个“ColumnDefinition”项。

  7. 在“属性”窗口中,将 Width 属性设置为 *。

  8. 在“文档大纲”窗口中,选择第二个“ColumnDefinition”。

  9. 在“属性”窗口中,将 Width 属性设置为 2*。

    两列将重新调整大小,第一列占窗口宽度的三分之一,第二列占三分之二。

  10. 在“文档大纲”窗口中,展开网格的“RowDefinitions”节点。

  11. 选择第一个“RowDefinition”项。

  12. 在“属性”窗口中,将 Height 属性设置为 *。

  13. 在“文档大纲”窗口中,选择第二个“RowDefinition”。

  14. 在“属性”窗口中,将 Height 属性设置为 *。

    行的大小将重新调整为占窗口高度的一半。

  15. 生成并运行项目。

  16. 重新调整窗口大小以查看 TreeViewListView 控件如何动态调整大小。

创建数据源

FolderExplorer 应用程序的数据源是一个名为 Folder 的类。此类提供文件系统的简单模型。每个 Folder 实例都有一个 SubFolders 和一个 Files 集合。

创建数据源

  1. 将一个名为 Folder 的新类添加到 FolderExplorer 项目。有关更多信息,请参见如何:添加新项目项

  2. 用下面的代码替换 Folder 源代码文件的内容。

    Imports System
    Imports System.IO
    Imports System.Linq
    Imports System.Collections.Generic
    Imports System.Collections.ObjectModel
    Imports System.Text
    
    Public Class Folder
        Private _folder As DirectoryInfo
        Private _subFolders As ObservableCollection(Of Folder)
        Private _files As ObservableCollection(Of FileInfo)
    
        Public Sub New() 
            Me.FullPath = "c:\"
    
        End Sub 'New
    
    
        Public ReadOnly Property Name() As String 
            Get
                Return Me._folder.Name
            End Get
        End Property
    
    
        Public Property FullPath() As String 
            Get
                Return Me._folder.FullName
            End Get
    
            Set
                If Directory.Exists(value) Then
                    Me._folder = New DirectoryInfo(value)
                Else
                    Throw New ArgumentException("must exist", "fullPath")
                End If
            End Set
        End Property
    
        ReadOnly Property Files() As ObservableCollection(Of FileInfo)
            Get
                If Me._files Is Nothing Then
                    Me._files = New ObservableCollection(Of FileInfo)
    
                    Dim fi As FileInfo() = Me._folder.GetFiles()
    
                    Dim i As Integer
                    For i = 0 To fi.Length - 1
                        Me._files.Add(fi(i))
                    Next i
                End If
    
                Return Me._files
            End Get
        End Property
    
        ReadOnly Property SubFolders() As ObservableCollection(Of Folder)
    
            Get
                If Me._subFolders Is Nothing Then
                    Try
    
                    Me._subFolders = New ObservableCollection(Of Folder)
    
                        Dim di As DirectoryInfo() = Me._folder.GetDirectories()
    
                        Dim i As Integer
                        For i = 0 To di.Length - 1
                            Dim newFolder As New Folder()
                            newFolder.FullPath = di(i).FullName
                            Me._subFolders.Add(newFolder)
                        Next i
                    Catch ex As Exception
    
                        System.Diagnostics.Trace.WriteLine(ex.Message)
    
                    End Try
                End If
    
                Return Me._subFolders
            End Get
        End Property
    End Class
    
    using System;
    using System.IO;
    using System.Linq;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Text;
    
    namespace FolderExplorer
    {
        public class Folder
        {
            private DirectoryInfo _folder;
            private ObservableCollection<Folder> _subFolders;
            private ObservableCollection<FileInfo> _files;
    
            public Folder()
            {
                this.FullPath = @"c:\";
            }
    
            public string Name
            {
                get
                {
                    return this._folder.Name;
                }
            }
    
            public string FullPath
            {
                get
                {
                    return this._folder.FullName;
                }
    
                set
                {
                    if (Directory.Exists(value))
                    {
                        this._folder = new DirectoryInfo(value);
                    }
                    else
                    {
                        throw new ArgumentException("must exist", "fullPath");
                    }
                }
            }
    
            public ObservableCollection<FileInfo> Files
            {
                get
                {
                    if (this._files == null)
                    {
                        this._files = new ObservableCollection<FileInfo>();
    
                        FileInfo[] fi = this._folder.GetFiles();
    
                        for (int i = 0; i < fi.Length; i++)
                        {
                            this._files.Add(fi[i]);
                        }
                    }
    
                    return this._files;
                }
            }
    
            public ObservableCollection<Folder> SubFolders
            {
                get
                {
                    if (this._subFolders == null)
                    {
                        this._subFolders = new ObservableCollection<Folder>();
    
                        DirectoryInfo[] di = this._folder.GetDirectories();
    
                        for (int i = 0; i < di.Length; i++)
                        {
                            Folder newFolder = new Folder();
                            newFolder.FullPath = di[i].FullName;
                            this._subFolders.Add(newFolder);
                        }
                    }
    
                    return this._subFolders;
                }
            }
        }
    }
    

连接到数据源

WPF 控件通过数据绑定连接到数据源。下面的过程演示如何声明和绑定到 ObjectDataProvider

连接到数据源

  1. 在 WPF 设计器中打开 Window1.xaml。 

  2. 在 XAML 视图中,向 <Window> 标记中插入以下 XAML 以及其他 xmlns 映射。有关更多信息,请参见如何:将命名空间导入 XAML

    xmlns:my="clr-namespace:FolderExplorer"
    
  3. 在 <Window> 开始标记后以及 <Grid> 开始标记前插入以下 XAML。

        <Window.Resources>
    
            <ObjectDataProvider x:Key="RootFolderDataProvider" >
                <ObjectDataProvider.ObjectInstance>
                    <my:Folder FullPath="c:\"/>
                </ObjectDataProvider.ObjectInstance>
            </ObjectDataProvider>
    
            <HierarchicalDataTemplate 
                DataType    = "{x:Type my:Folder}"
                ItemsSource = "{Binding Path=SubFolders}">
                <TextBlock Text="{Binding Path=Name}" />
            </HierarchicalDataTemplate>
    
        </Window.Resources>
    
    
     <Window.Resources>
    
            <ObjectDataProvider x:Key="RootFolderDataProvider" >
                <ObjectDataProvider.ObjectInstance>
                    <my:Folder FullPath="c:\"/>
                </ObjectDataProvider.ObjectInstance>
            </ObjectDataProvider>
    
            <HierarchicalDataTemplate 
                DataType    = "{x:Type my:Folder}"
                ItemsSource = "{Binding Path=SubFolders}">
                <TextBlock Text="{Binding Path=Name}" />
            </HierarchicalDataTemplate>
    
        </Window.Resources>
    
    
  4. 用下面的 XAML 替换 <TreeView> 标记。

         <TreeView Grid.ColumnSpan="1" Grid.RowSpan="2" Margin="0,0,0,0" Name="treeView1" >
                <TreeViewItem ItemsSource="{Binding Path=SubFolders, Source={StaticResource RootFolderDataProvider}}" Header="Folders"  />
            </TreeView>
    
         <TreeView Grid.ColumnSpan="1" Grid.RowSpan="2" Margin="0,0,0,0" Name="treeView1" >
                <TreeViewItem ItemsSource="{Binding Path=SubFolders, Source={StaticResource RootFolderDataProvider}}" Header="Folders"  />
            </TreeView>
    

绑定控件属性

可将一个控件的属性绑定到其他控件,这将启用自动属性更新。

绑定控件属性

  1. 在 XAML 视图中,将两个 <ListView> 标记均替换为以下 XAML。

            <ListView Name="listView1" 
            ItemsSource="{Binding Path=SelectedItem.SubFolders, ElementName=treeView1, Mode=OneWay}" 
            Grid.Column="1" 
            Grid.RowSpan="1" />
    
            <ListView Name="listView2" 
            ItemsSource="{Binding Path=SelectedItem.Files, ElementName=treeView1, Mode=OneWay}" 
            Grid.Column="1" 
            Grid.Row="1" />
    
         <ListView Name="listView1" 
            ItemsSource="{Binding Path=SelectedItem.SubFolders, ElementName=treeView1, Mode=OneWay}" 
            Grid.Column="1" 
            Grid.RowSpan="1" />
    
            <ListView Name="listView2" 
            ItemsSource="{Binding Path=SelectedItem.Files, ElementName=treeView1, Mode=OneWay}" 
            Grid.Column="1" 
            Grid.Row="1" />
    
  2. 生成并运行项目。

  3. 展开“Folders”项,以打开根文件夹。通过单击子文件夹和查看两个 ListView 控件的内容来进行试验。子文件夹显示在上面的 ListView 控件中,文件显示在下面的 ListView 控件中。

后续步骤

  • 当前,FolderExplorer 应用程序以默认样式来显示。您可以应用自己的样式来更改应用程序的外观和行为。

  • Visual Studio 还提供了许多用于调试 WPF 应用程序的工具。有关更多信息,请参见演练:在设计时调试 WPF 自定义控件

请参见

任务

如何:使用附加事件

演练:在设计时调试 WPF 自定义控件

概念

拆分视图:同时查看 WPF 设计图面和 XAML

浏览 WPF 文档的元素层次结构

其他资源

使用 WPF 设计器中的控件