Walkthrough: Constructing a Data-driven Dynamic Layout
Windows Presentation Foundation (WPF) provides controls that support data-driven dynamic layouts. Using these controls with the WPF Designer for Visual Studio makes it easy for you to create these types of layouts. You can use the following controls in your applications:
The ListView control provides the infrastructure to display a set of data items in different layouts. You typically use a GridView in conjunction with the ListView control to display data in columns. For more information, see ListView Overview and GridView Overview.
In this walkthrough, you perform the following tasks:
Prepare a data source.
Create a WPF application.
Configure the default Grid panel control.
Add and configure a ListView control.
Add and configure a GridView in XAML.
Add and configure a Button control.
Add data binding code.
Test the application.
The following illustration shows how your application will appear.
Note
The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or edition. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see Working with Settings.
Prerequisites
You need the following components to complete this walkthrough:
- Visual Studio 2010
Preparing the Data Source
For this walkthrough, you will need a sample data source to bind to. You will create a simple CSV file data source.
To prepare the data source
Create a new folder and name it Data.
In the Data folder, create a new text file and name it employees.csv.
Note
You can use any text editor, for example Notepad, to create the file.
Add the following to the text file:
LastName,FirstName,Title Davis,Sara,Sales Representative Funk,Don,Vice President, Sales Levin,Danny,Sales Representative Penor,Lori,Sales Representative Buschmann,Monika,Sales Manager Suominen,Ari,Sales Representative King,Russell,Sales Representative Cameron,Maria,Inside Sales Coordinator Doyle,Patricia,Sales Representative
Save and close the file.
Tip
You can open the file in Excel and confirm that the data separated by the commas appears in separate columns.
In the Data folder, create a new text file and name it schema.ini. The schema file describes the format of the text files in your data folder.
Add the following to the text file:
[employees.csv] Format=CSVDelimited ColNameHeader=True
Tip
In this walkthrough your CSV file has column headings. To bind to a CSV file that does not have column headings, change ColNameHeader=True to ColNameHeader=False.
Save and close the file.
Creating the Project
The next procedure is to create the Visual Studio project for the application.
To create the project
Create a new WPF Application project in Visual Basic or Visual C# named DataDrivenLayout. For more information, see How to: Create a New WPF Application Project.
MainWindow.xaml opens in the WPF Designer.
On the File menu, click Save All.
Configuring the Default Grid Panel Control
By default, the new WPF application contains a Window with a Grid panel. In this procedure you add two rows to the grid. You set the height of one row to Auto, so that it is sized to fit the content. You set the height of the other row to *, so that it uses the remaining available height.
To configure the default grid panel control
In Design view, select the Grid. For more information, see How to: Select and Move Elements on the Design Surface.
In the Properties window, locate the RowDefinitions property, and click the ellipsis button in the property value column.
The Collection Editor appears.
Click Add two times to add two rows.
Set the Height property of the first row to *.
Set the Height property of the second row to Auto.
Click OK to close the Collection Editor and return to the WPF Designer.
Now there are two rows in the grid, but only one row appears. The row whose Height property is set to Auto is temporarily hidden because it does not have any content. For this walkthrough, that is fine. To avoid this in the future, you can use star sizing while you work, and change to Auto when you are done.
On the File menu, click Save All.
Adding and Configuring a ListView
In this procedure you add a ListView. You give the ListView a name so that you can refer to it from the code-behind file. You configure its layout properties.
To add and configure a ListView
In Design view, select the Grid.
From the Toolbox, in the Controls group, drag a ListView control onto the Grid.
In the Properties window, set the following properties for the ListView:
Property
Value
Name
lvEmployees
Grid.Column
0
Grid.ColumnSpan
1
Grid.Row
0
Grid.RowSpan
1
Width
Auto
Height
Auto
HorizontalAlignment
Stretch
VerticalAlignment
Stretch
Margin
0
On the File menu, click Save All.
Adding and Configuring a GridView
In this procedure you add a GridView with three columns to display the data from the text file. You give the columns names because you are going to refer to them from the code-behind to bind the data to the columns individually. For more information, see How to: Display ListView Contents by Using a GridView.
To add and configure a GridView
In the XAML editor locate the ListView element. It looks like the following:
<ListView <ATTRIBUTES> />
Tip
To easily highlight elements in XAML view, click the control in Design view or use the Document Outline window.
Replace the ListView element with the following:
<ListView x:Name="lvEmployees"> <ListView.View> <GridView AllowsColumnReorder="True"> <GridViewColumn x:Name="c1Employees" Header="Last Name"></GridViewColumn> <GridViewColumn x:Name="c2Employees" Header="First Name"></GridViewColumn> <GridViewColumn x:Name="c3Employees" Header="Title"></GridViewColumn> </GridView> </ListView.View> </ListView>
On the File menu, click Save All.
Adding and Configuring a Button
In this procedure you add a Button and specify its Click event.
To add and configure a Button
In Design view, select the Grid.
From the Toolbox, in the Controls group, drag a Button control onto the Grid.
In the Properties window, set the following properties for the Button:
Property
Value
Name
btnGetData
Content
Get Data
Grid.Column
0
Grid.ColumnSpan
1
Grid.Row
1
Grid.RowSpan
1
Width
75
Height
23
HorizontalAlignment
Right
VerticalAlignment
Bottom
Margin
5
In the XAML editor locate the Button element. It looks like the following:
<Button <ATTRIBUTES>>Button</Button>
Tip
To easily highlight elements in XAML view, click the control in Design view or use the Document Outline window.
Edit the XAML to add a Click event attribute. It should look like the following:
<Button Click="btnGetData_Click" <ATTRIBUTES>>Button</Button>
On the File menu, click Save All.
Adding the Data Binding Code
In this procedure you add the code for the Click event of the Button. At run time you click the button to get the data and bind it to the ListView and the GridView.
To add the data binding code
Open the code-behind file; either MainWindow.xaml.cs or MainWindow.xaml.vb, depending on which language you selected for your project.
At the top of the code editor, add the following code. In order to bind to the data you need to access the System.Data and System.Data.OleDb namespaces.
Imports System.Data 'DataTable Imports System.Data.OleDb 'OleDbDataAdapter Imports System.Windows 'RoutedEventArgs Imports System.Windows.Data 'Binding Imports System.Windows.Controls 'ListView
using System; //Exception using System.Data; //DataTable using System.Data.OleDb; //OleDbDataAdapter using System.Windows; //RoutedEventArgs using System.Windows.Data; //Binding using System.Windows.Controls; //ListView
In the MainWindow class, add the following code. You use a DataTable to store the data.
Dim dtEmployees As DataTable
DataTable dtEmployees;
In the MainWindow class, add the following code. When the user clicks the button, you get the data, and then bind it to the ListView.
Private Sub btnGetData_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) dtEmployees = GetData() BindData() End Sub
private void btnGetData_Click(object sender, RoutedEventArgs e) { dtEmployees = GetData(); BindData(); }
In the MainWindow class, add the following code and specify the path to your Data folder. To get the data, you use an OleDbDataAdapter.
Function GetData() As DataTable Dim sConnection As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<Your Path>\Data\;Extended Properties=""text;HDR=yes;FMT=delimited"";" Dim sSQL As String = "select * from employees.csv" Dim dt As DataTable = New DataTable() Dim da As OleDbDataAdapter = New OleDbDataAdapter(sSQL, sConnection) Try da.Fill(dt) Catch ex As Exception MessageBox.Show(ex.ToString()) End Try Return dt End Function
DataTable GetData() { string sConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<Your Path>\\Data\\;Extended Properties=\"text;HDR=yes;FMT=delimited\";"; string sSQL = "select * from employees.csv"; DataTable dt = new DataTable(); OleDbDataAdapter da = new OleDbDataAdapter(sSQL, sConnection); try { da.Fill(dt); } catch (Exception e) { MessageBox.Show(e.ToString()); } return dt; }
In the MainWindow class, add the following code. To bind the data to the ListView, you set its DataContext to the DataTable. You display the data columns in the columns of the GridView.
Sub BindData() lvEmployees.DataContext = dtEmployees lvEmployees.SetBinding(ListView.ItemsSourceProperty, New Binding()) c1Employees.DisplayMemberBinding = New Binding("LastName") c2Employees.DisplayMemberBinding = New Binding("FirstName") c3Employees.DisplayMemberBinding = New Binding("Title") End Sub
void BindData() { lvEmployees.DataContext = dtEmployees; lvEmployees.SetBinding(ListView.ItemsSourceProperty, new Binding()); c1Employees.DisplayMemberBinding = new Binding("LastName"); c2Employees.DisplayMemberBinding = new Binding("FirstName"); c3Employees.DisplayMemberBinding = new Binding("Title"); }
On the File menu, click Save All.
Setting the Window to Size Dynamically
The SizeToContent property specifies how the size of a Window changes when the size of its content changes. By default, this property is set to Manual, which means that the user can manually resize the window to fit the content. In this procedure you set this property to WidthAndHeight, which means that the window resizes dynamically when its content changes.
To set the Window to size dynamically
Open MainWindow.xaml in the designer.
In Design view, select the Window.
In the Properties window, set the following properties for the Window:
Property
Value
SizeToContent
WidthAndHeight
Width
Auto
Height
Auto
On the File menu, click Save All.
Testing the Application
To test the application
On the Debug menu, click Start Debugging.
The application starts and the window appears. Because you set the SizeToContent property to WidthAndHeight, the window is only large enough for the GridView headers and the Button.
Click Get Data.
The application gets the data and binds it to the GridView. The GridView, ListView, and Window all resize dynamically to fit the new content.
Close the window.
Putting it all Together
The following is the completed MainWindow.xaml file:
<Window x:Class="MainWindow"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="Auto" Width="Auto" SizeToContent="WidthAndHeight">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView x:Name="lvEmployees">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn x:Name="c1Employees" Header="Last Name"></GridViewColumn>
<GridViewColumn x:Name="c2Employees" Header="First Name"></GridViewColumn>
<GridViewColumn x:Name="c3Employees" Header="Title"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Click="btnGetData_Click" Name="btnGetData" Margin="5" Height="23" Width="75" HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="1" Grid.RowSpan="1">Get Data</Button>
</Grid>
</Window>
Next Steps
In this walkthrough you used a GridView with three columns to display data. You bound data directly to each column individually. You can also use data templates to arrange and style the data in a ListView or a GridView. For more information, see Data Templating Overview.
You can experiment with using data templates in this walkthrough. For example, you can create a template such as the following:
<Window.Resources>
<DataTemplate x:Key="templateEmployees">
<Border BorderBrush="Silver" BorderThickness="1" Padding="5" Margin="5">
<DockPanel>
<StackPanel DockPanel.Dock="Left">
<TextBlock Text="{Binding Path=LastName}" />
<TextBlock Text="{Binding Path=FirstName}" />
</StackPanel>
<TextBlock Text="{Binding Path=Title}" DockPanel.Dock="Right" />
</DockPanel>
</Border>
</DataTemplate>
</Window.Resources>
Then use the data template in the GridView with code such as the following:
<ListView.View>
<GridView>
<GridViewColumn CellTemplate="{StaticResource templateEmployees}" />
</GridView>
</ListView.View>
Remove or comment the following code from the code-behind:
c1Employees.DisplayMemberBinding = New Binding("LastName")
c2Employees.DisplayMemberBinding = New Binding("FirstName")
c3Employees.DisplayMemberBinding = New Binding("Title")
c1Employees.DisplayMemberBinding = new Binding("LastName");
c2Employees.DisplayMemberBinding = new Binding("FirstName");
c3Employees.DisplayMemberBinding = new Binding("Title");
See Also
Tasks
How to: Construct a Data-driven Dynamic Layout
Concepts
WPF and Silverlight Designer Overview