演练:用 WPF 设计器生成简单的 WPF 应用程序
[本文档仅供预览,在以后的发行版中可能会发生更改。包含的空白主题用作占位符。]
本演练演示如何建立与 WPF Designer简单 (WPF)的 windows presentation foundation 应用程序。
在本演练中,您将执行下列任务:
创建项目。
创建布局。
将控件添加到格式。
设置与布局相关的属性。
创建数据源。
连接到数据源。
绑定控件属性。
完成本演练后,您将允许您在浏览文件系统的简单应用程序。 您的应用程序的用户界面将实现使用可扩展应用程序标记语言 (xaml)。 有关更多信息,请参见 WPF 中的 XAML。 下图显示应用程序将如何显示。
备注
运行在 Visual Studio 2012 RC 内本演练的动手实验版本的中可用 在实验室的 WPF 简单应用程序演练手。
系统必备
您需要以下组件来完成本演练:
- Visual Studio 2012 RC.
创建项目
第一步是创建应用程序的项目。
创建项目
创建新的 WPF 名为 FolderExplorer的应用程序项目在 Visual Basic 或 Visual C#。 有关更多信息,请参见 如何:创建新的 WPF 应用程序项目。
在 MainWindow.xaml WPF Designer打开。
在设计视图中,选择窗口。 有关更多信息,请参见 如何:在设计图面上选择和移动元素。
在 属性 窗口中,将 Title 属性的值设置为 文件夹资源管理器。
创建布局
布局定义控件如何在应用程序的主窗口中。 下面的步骤演示如何构造布局元素将包含应用程序的控件。
创建布局
在窗口中选择根 Grid 控件。
添加第二行到网格中。 有关更多信息,请参见 如何:向网格中添加行和列。
添加第二列到网格中。
向布局添加控件
在布局中定义,您可以填充其与控件关联。
向布局添加控件
从 工具箱,将 TreeView 控件拖动到网格的第一个单元格。
从 工具箱,将 ListView 控件拖动到占据网格第一行第二列的单元格。
从 工具箱,将 ListView 控件拖动到占据网格第二行第二列的单元格。
设置与布局相关的属性
下面的步骤演示如何对控件设置与布局相关的属性。 因为在每个控件的属性,布局非常类似于最终应用程序。
设置与布局相关的属性
选择 TreeView 控件。
在 属性 窗口,如下所示设置下列属性。
属性
value
Grid.ColumnSpan
1
Grid.RowSpan
2
高度
自动
HorizontalAlignment
拉伸
页边距
0,0,0,0
VerticalAlignment
拉伸
宽度
自动
TreeView 控件调整大小以适应第一个网格列和跨两网格行。
选择两个 ListView 控件。
在 属性 窗口,如下所示设置下列属性。
属性
value
Grid.ColumnSpan
1
Grid.RowSpan
1
高度
自动
HorizontalAlignment
拉伸
页边距
0,0,0,0
VerticalAlignment
拉伸
宽度
自动
ListView 控件调整大小以适应其各自的网格。
打开 文档大纲 窗口。 有关更多信息,请参见 浏览 WPF 文档的元素层次结构。
展开网格的 ColumnDefinitions 节点。
选择第一个 删除 项目。
在 属性 窗口中,将的 width 属性设置为 *。
在 文档大纲 窗口中,选择第二 删除。
在 属性 窗口中,将的 width 属性设置为 2*。
列调整大小与第一个列将窗口的宽度的 1/3 一并采取 1/3 第二列。
在 文档大纲 窗口中,展开网格的 RowDefinitions 节点。
选择第一个 删除 项目。
在 属性 窗口中,将的 height 属性设置为 *。
在 文档大纲 窗口中,选择第二 删除。
在 属性 窗口中,将的 height 属性设置为 *。
行调整占窗口高度的一半。
生成并运行解决方案。
创建数据源
FolderExplorer 应用程序的数据源是一个名为 Folder的类。 此类提供文件系统的简单模型。 每 Folder 实例都有 SubFolders 和 Files 集合。
创建数据源
将名为 文件夹 的新类添加到 FolderExplorer 项目。 有关更多信息,请参见 How to: Add New Project Items。
用下面的代码替换 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。
连接到数据源
打开在 WPF Designer的 MainWindow.xaml。
在 XAML 视图中,插入以下 XAML 添加到 <Window> 标记中,与其他 xmlns 映射。 有关更多信息,请参见 如何:将命名空间导入 XAML。
xmlns:my="clr-namespace:FolderExplorer"
插入以下 XAML 在打开的 <Window> 标记之后且在打开的 <Grid> 标记之前。
<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>
用下面的 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>
绑定控件属性
可以将控件的属性绑定到另一个控件,启用自动更新属性。
绑定控件属性
在 XAML 视图中,用以下 XAML 替换两 <ListView> 标记。
<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 控件的内容测试。
后续步骤
目前, FolderExplorer 应用程序演示默认样式。 您可以应用自己的样式来更改应用程序的外观和行为。
Visual Studio 还提供对调试 WPF 应用程序的许多工具。 有关更多信息,请参见 演练:在设计时调试 WPF 自定义控件。