Walkthrough: Building a Simple WPF Application with the WPF Designer
[This documentation is for preview only, and is subject to change in later releases. Blank topics are included as placeholders.]
This walkthrough shows how to build a simple Windows Presentation Foundation (WPF) application with the WPF Designer.
In this walkthrough, you perform the following tasks:
Create the project.
Create the layout.
Add controls to the layout.
Set layout-related properties.
Create a data source.
Connect to a data source.
Bind control properties.
When you are finished, you will have a simple application which lets you browse the file system. Your application's user interface will be implemented in Extensible Application Markup Language (XAML). For more information, see XAML in WPF. The following illustration shows how your application will appear.
Note
A hands-on lab version of this walkthrough that runs inside of Visual Studio 2012 RC is available at WPF Simple Application Walkthrough Hands on Lab.
Prerequisites
You need the following components to complete this walkthrough:
- Visual Studio 2012 RC.
Creating the Project
The first step is to create the project for the application.
To create the project
Create a new WPF Application project in Visual Basic or Visual C# named FolderExplorer. For more information, see How to: Create a New WPF Application Project.
MainWindow.xaml opens in the WPF Designer.
In Design view, select the window. For more information, see How to: Select and Move Elements on the Design Surface.
In the Properties window, set the value of the Title property to Folder Explorer.
Creating the Layout
The layout defines how controls are arranged in your application's main window. The following steps show how to construct layout elements which will contain the application's controls.
To create the layout
Select the root Grid control on the window.
Add a second row to the grid. For more information, see How to: Add Rows and Columns to a Grid.
Add a second column to the grid.
Adding Controls to the Layout
With the layout defined, you can populate it with controls.
To add controls to the layout
From the Toolbox, drag a TreeView control into the first cell of the grid.
From the Toolbox, drag a ListView control into the cell occupying the first row and second column of the grid.
From the Toolbox, drag a ListView control into the cell occupying the second row and second column of the grid.
Setting Layout-related Properties
The following steps show how to set layout-related properties on the controls. As you set properties on each control, the layout will more closely resemble the final application.
To set layout-related properties
Select the TreeView control.
In the Properties window, set the following properties as shown.
Property
Value
Grid.ColumnSpan
1
Grid.RowSpan
2
Height
Auto
HorizontalAlignment
Stretch
Margin
0,0,0,0
VerticalAlignment
Stretch
Width
Auto
The TreeView control resizes to fit in the first grid column and to span the two grid rows.
Select both ListView controls.
In the Properties window, set the following properties as shown.
Property
Value
Grid.ColumnSpan
1
Grid.RowSpan
1
Height
Auto
HorizontalAlignment
Stretch
Margin
0,0,0,0
VerticalAlignment
Stretch
Width
Auto
The ListView controls resize to fit in their respective grid cells.
Open the Document Outline window. For more information, see Navigating the Element Hierarchy of a WPF Document.
Expand the ColumnDefinitions node for the grid.
Select the first ColumnDefinition item.
In the Properties window, set the Width property to *.
In the Document Outline window, select the second ColumnDefinition.
In the Properties window, set the Width property to 2*.
The columns are resized with the first column taking one-third of the window's width and the second column taking two-thirds.
In the Document Outline window, expand the RowDefinitions node for the grid.
Select the first RowDefinition item.
In the Properties window, set the Height property to *.
In the Document Outline window, select the second RowDefinition.
In the Properties window, set the Height property to *.
The rows resize to occupy half the window's height.
Build and run the solution.
Resize the window to see the TreeView and ListView controls dynamically resizing.
Creating a Data Source
The data source for the FolderExplorer application is a class named Folder. This class provides a simple model of the file system. Each Folder instance has a SubFolders and a Files collection.
To create a data source
Add a new class named Folder to the FolderExplorer project. For more information, see How to: Add New Project Items.
Replace the contents of the Folder source code file with the following code.
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; } } } }
Connecting to a Data Source
WPF controls are connected to data sources through data binding. The following procedure shows how to declare and bind to an ObjectDataProvider.
To connect to a data source
Open MainWindow.xaml in the WPF Designer.
In XAML view, insert the following XAML into the <Window> tag, with the other xmlns mappings. For more information, see How to: Import a Namespace into XAML.
xmlns:my="clr-namespace:FolderExplorer"
Insert the following XAML after the opening <Window> tag and before the opening <Grid> tag.
<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>
Replace the <TreeView> tag with the following XAML.
<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>
Binding Control Properties
You can bind a control's properties to another control, which enables automatic property updating.
To bind control properties
In XAML view, replace both <ListView> tags with the following 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" />
Build and run the solution.
Expand the Folders item to see folders from your C: drive.
Experiment by clicking subfolders and observing the contents of the two ListView controls.
Subfolders are displayed in the upper ListView control and files are displayed in the lower ListView control.
Next Steps
Currently, the FolderExplorer application is displayed with the default styling. You can apply your own styles to change the application's appearance and behavior.
Visual Studio also provides many tools for debugging your WPF application. For more information, see Walkthrough: Debugging WPF Custom Controls at Design Time.
See Also
Tasks
Walkthrough: Debugging WPF Custom Controls at Design Time
Concepts
Split View: Viewing the WPF Design Surface and XAML at the Same Time
Navigating the Element Hierarchy of a WPF Document