Skip to content

Example 8

This example illustrates data binding using a matrix and is practically identical to Example 7 except that it uses a matrix instead of a vector of namespaces.

Each row in the WPF DataGrid control is represented by an object, and each column as a property of that object. Each row in the DataGrid is bound to an object in the data source, and each column in the data grid is bound to a property of the data object.

data binding datagrid1
Figure 1: data binding datagrid1

The XAML

The XAML shown below, describes a Window containing a DockPanel, inside which is a DataGrid. The XAML is identical to the XAML in Example 7, except for the window caption.

 <Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="DataGrid Matrix Example" Height="500"
    SizeToContent="Width"
    Topmost="true">
    <DockPanel>
        <DataGrid Name="DG1" ItemsSource="{Binding}"
                  AutoGenerateColumns="False" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Wine"
                 Binding="{Binding Name}"/>
                <DataGridTextColumn Header="Price"
                 Binding="{Binding Price, StringFormat=C}" />
            </DataGrid.Columns>
        </DataGrid>
    </DockPanel>
 </Window>

The phrase ItemsSource="{Binding}" states that the content of the DataGrid is bound to a data source, which in this case will be inherited from the DataContext property of the parent Window.

Binding="{Binding Name}" specifies that the contents of the first column are bound to a Path named Name in the data source.

Similarly, Binding="{Binding Price, StringFormat=C}" specifies that the Path for the second column is Price (the phrase StringFormat=C merely specifies the default currency format).

The APL Code

The function Grid is shown below.

      Grid;⎕USING;MySource;win;info
[1]    ⎕USING'System'
[2]    ⎕EX'winelist'
[3]    winelistWines,[1.5]0.01×10000+?(Wines)10000
[4]    winLoadXAML XAML
[5]    info('Name' 'Price'),⊂Object
[6]    win.DataContextinfo(2015)'winelist'
[7]    win.Show
     

As in Example 7, the global variable Wines contains a vector of character vectors, each of which is the name of a wine.

Grid[2-4] creates a matrix winelist, whose first column contains the names of the wines, and whose second column their (randomly generated) prices. As this is a global variable, the variable is expunged before being used in order to remove any previous data binding information that was associated with it.

Grid[5]creates the left argument for (2015⌶) which defines the names and data types of the properties which the columns of the matrix winelist will be exposed as. In this case, the names of the paths are Name and Price, and their data types are both System.Object. So the first column will be exposed as Name and the second as Price, matching the path names specified in the XAML:

            <DataGridTextColumn Header="Wine"
            Binding="{Binding Name}"/>
            <DataGridTextColumn Header="Price"
            Binding="{Binding Price, StringFormat=C}" />

Testing the Data Binding

      )LOAD wpfintro
      )CS DataBinding.DataGridMatrix
      Grid

data binding datagrid1
Figure 2: data binding datagrid1

Let's round the prices to the nearest $5.

 winelist[;2]5×⌊0.5+winelist[;2]÷5

data binding datagrid2
Figure 3: data binding datagrid2

Using Code

The same result can be achieved using code instead of XAML as illustrated by the function GridCodeNoFmt. The function is so-named because this code is insufficient to display the second column in currency format.

      GridCodeNoFmt;⎕USING;MySource;win;info;fmt
[1]    ⎕USING'System'
[2]    ⎕USING,,⊂'System.Windows.Controls,WPF/PresentationFramework.dll'
[3]    ⎕USING,'System.Windows.Controls.Primitives,WPF/PresentationFramework.dll'
[4]    ⎕USING,'System.Windows,WPF/PresentationFramework.dll'
[5]    ⎕USING,'System.Windows,WPF/PresentationCore.dll'
[6]
[7]    ⎕EX'winelist'
[8]    winelistWines,[1.5]0.01×10000+?(Wines)10000
[9]    win⎕NEW Window
[10]   win.Title'DataGrid Matrix (Code)'
[11]   win.grid⎕NEW DataGrid
[12]   info('Name' 'Price'),⊂Object
[13]   win.grid.ItemsSourceinfo(2015)'winelist'
[14]   win.grid.Height500
[15]   win.Contentwin.grid
[16]   win.SizeToContentSizeToContent.WidthAndHeight
[17]   win.Show
     

This is because by default the DataGrid generates its columns automatically with default formatting.

data binding datagrid3
Figure 4: data binding datagrid3

In order to apply special formatting to one or more columns, it is necessary to set the AutoGenerateColumns property to 0, and to generate the columns programmatically as is shown in the second version of the function, GridCode.

      GridCode;⎕USING;MySource;win;info;fmt
[1]    ⎕USING'System'
[2]    ⎕USING,,⊂'System.Windows.Controls,WPF/PresentationFramework.dll'
[3]    ⎕USING,'System.Windows.Controls.Primitives,WPF/PresentationFramework.dll'
[4]    ⎕USING,'System.Windows,WPF/PresentationFramework.dll'
[5]    ⎕USING,'System.Windows,WPF/PresentationCore.dll'
[6]
[7]    ⎕EX'winelist'
[8]    winelistWines,[1.5]0.01×10000+?(Wines)10000
[9]    win⎕NEW Window
[10]   win.Title'DataGrid Matrix (Code with Formatting)'
[11]   win.grid⎕NEW DataGrid
[12]   info('Name' 'Price'),⊂Object
[13]   win.grid.ItemsSourceinfo(2015)'winelist'
[14]   win.grid.Height500
[15]   win.grid.AutoGenerateColumns0
[16]   win.Contentwin.grid
[17]   win.SizeToContentSizeToContent.WidthAndHeight
[18]   ⍝ Add columns and set format
[19]   win.grid.Columns.Add¨'' 'C'{
[20]       col⎕NEW DataGridTextColumn
[21]       col.Header
[22]       col.Binding⎕NEW Data.Binding()
[23]       col.Binding.StringFormat,
[24]       col
[25]   }¨'Name' 'Price'
[26]
[27]   win.Show
     

In this version of the function, lines [19-25] create the two columns Name and Price, applying currency format to the Price column.

data binding datagrid4
Figure 5: data binding datagrid4