Logo
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
PREGNANCY
 
 
Windows 7

Visual Basic 2010 : Discussing the New Drag and Drop Data-Binding (part 1) - Creating Tabular Data Forms

8/16/2011 4:51:59 PM
Visual Studio 2010 introduces to the WPF development a new interesting feature at the IDE level. The feature is known as drag’n’drop data-binding and is something that was already available in Windows Forms for many years. Now you can simply build data forms in WPF too with such new tooling. The base idea is that you can build a data form by simply dragging items from the Data Sources window, and Visual Studio will generate all the code for you, including master-details scenarios. There is also other good news in Visual Studio 2010, which is the Data Sources window support for entities from an Entity Data Model based on the ADO.NET Entity Framework. This section explains how you can take advantage of the new WPF drag’n’drop data-binding to easily build data forms, explaining the meaning and behavior of the auto-generated code.

Tip

The drag’n’drop data-binding has obviously some limitations, and in many cases you need to put your hands over the auto-generated code or, differently, write your own data-binding code from scratch. This new technique offers several advantages: The result is completely customizable, as in the style of WPF applications; second, if you are new to data-binding in WPF, it allows you to simply understand how things work against a more complex data-source (such as an EDM or a DataSet). Finally, it also provides the ability of separating the data-source from the user interface, although this is something that you will probably need to edit according to your application logic.


To complete the next code examples, follow these steps after creating a new WPF project in Visual Basic:

1.
Create a new WPF project for Visual Basic.

2.
Add a new Entity Data Model based on the Northwind sample database, ensuring that you include the Customers and Orders tables.

After this brief introduction, it is time to understand how easy building data forms is with WPF 4.

Creating Tabular Data Forms

The goal of the next example is to show how simple it is to create tabular data representations, also taking a look at necessary objects for performing data-binding in code. To accomplish this, first divide the default Grid into two columns as follows:

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>

Next, add a ListBox control either by dragging it from the Toolbox or by writing the following code (for better layout purposes, ensure that you place it in the left column):

<ListBox Name="CustomersListBox"
Grid.Column="0"/>

This ListBox stores a list of customers’ names that will be added shortly. Now open the Data Sources window by clicking Shift+Alt+D. The result looks similar to Figure 1, depending on how many entities you added to the Entity Data Model.

Figure 1. The Data Sources window now lists entities from EDMs, too.


As you can see, the Data Sources window now also lists entities coming from Entity Data Models, and this is a new feature in Visual Studio 2010. The default icon near each entity name indicates that data will be represented as tabular, but you can replace this representation with a list view or with a details view simply by selecting the appropriate value from the combo box on the right side of each entity name. (At the moment leave unchanged the default selection.) Now, expand the Customers entity (as shown in Figure 1) and select the CompanyName item; then drag it onto the ListBox and release the mouse. When you release the mouse, you will not notice anything new on the designer surface, but look at what happened in the XAML code editor:

<Window.Resources>
<CollectionViewSource x:Key="CustomersViewSource"
d:DesignSource=
"{d:DesignInstance my:Customer,
CreateList=True}" />
</Window.Resources>
<Grid DataContext="{StaticResource CustomersViewSource}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox Name="CustomersListBox"
Grid.Column="0" DisplayMemberPath="CompanyName"
ItemsSource="{Binding}" />
</Grid>

Visual Studio generates some code, both XAML and Visual Basic, each time you perform some drag’n’drop action. For now it generated a CollectionViewSource object within the window’s resources. You may compare the WPF CollectionViewSource to the Windows Forms’ BindingSource control, which basically acts like a bridge between the underlying data collection and the user interface. The code states that such CollectionViewSource is populated via a list (CreateList=True) of Customer instances. This statement is accomplished via the d:DesignInstance custom markup extension, exposed by the d Xml name-space that points to Microsoft Expression Blend schema for WPF. This is useful because it provides resources for design-time data-binding. Notice also how Visual Studio added a DataContext property for the default Grid, whose source is the above described CollectionViewSource. In this way, all child controls will populate picking data from the CollectionViewSource. You can get an example of this by taking a look at the ListBox overridden definition: It is populated with data-binding (ItemsSource property) and shows just the value of the CompanyName property (DisplayMemberPath) for each item in the bound collection. Now drag onto the form the Orders item from the Data Sources window, ensuring that you drag the one nested within Customers. When dragged and dropped, the result should look like in Figure 2.

Figure 2. The result of the drag’n’drop operations in the Visual Studio designer.

First, notice how the new DataGrid control simply enables building tabular data representations. By simply dragging the data source, Visual Studio generated all the necessary items for you. If you now take a look at the XAML code editor, you will first notice a second CollectionViewSource referring to the Orders data:

<CollectionViewSource x:Key="CustomersOrdersViewSource"
Source="{Binding Path=Orders,
Source={StaticResource CustomersViewSource}}" />

Notice how the source for the data-binding is the Orders collection from the previously generated CustomersViewSource object of type CollectionViewSource. Next, Visual Studio also generated markup code for the DataGrid. For this, it did not take advantage of columns auto-generation, whereas it instead created specific columns for each property in the bound collection. This enables the IDE to also generate custom cell templates that can show data with the appropriate control. The following is the XAML code for the DataGrid:

<DataGrid AutoGenerateColumns="False"
EnableRowVirtualization="True"
Grid.Column="1"
ItemsSource="{Binding
Source={StaticResource CustomersOrdersViewSource}}"
Name="OrdersDataGrid"
RowDetailsVisibilityMode="VisibleWhenSelected">
<DataGrid.Columns>
<DataGridTextColumn x:Name="OrderIDColumn"
Binding="{Binding Path=OrderID}"
Header="Order ID"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="CustomerIDColumn"
Binding="{Binding Path=CustomerID}"
Header="Customer ID"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="EmployeeIDColumn"
Binding="{Binding Path=EmployeeID}"
Header="Employee ID"
Width="SizeToHeader" />
<DataGridTemplateColumn x:Name="OrderDateColumn"
Header="Order Date"
Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker
SelectedDate="{Binding Path=OrderDate}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn x:Name="RequiredDateColumn"
Header="Required Date"
Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker
SelectedDate="{Binding Path=RequiredDate}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn x:Name="ShippedDateColumn"
Header="Shipped Date"
Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker
SelectedDate="{Binding Path=ShippedDate}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn x:Name="ShipViaColumn"
Binding="{Binding Path=ShipVia}"
Header="Ship Via"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="FreightColumn"
Binding="{Binding Path=Freight}"
Header="Freight"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="ShipNameColumn"
Binding="{Binding Path=ShipName}"
Header="Ship Name"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="ShipAddressColumn"
Binding="{Binding Path=ShipAddress}"
Header="Ship Address"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="ShipCityColumn"
Binding="{Binding Path=ShipCity}"
Header="Ship City"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="ShipRegionColumn"
Binding="{Binding Path=ShipRegion}"
Header="Ship Region"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="ShipPostalCodeColumn"
Binding="{Binding Path=ShipPostalCode}"
Header="Ship Postal Code"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="ShipCountryColumn"
Binding="{Binding Path=ShipCountry}"
Header="Ship Country"
Width="SizeToHeader" />
</DataGrid.Columns>
</DataGrid>


The DataGrid data source is set via the ItemsSource property pointing to the CustomersOrdersViewSource object, which includes information from both Customers and related Orders. The rest of the code is quite simple to understand. Each column has a cell template, which is of type DataGridTextColumn for text fields. Other built-in types are DataGridHyperLinkColumn for displaying hyperlinks, DataGridCheckBoxColumn for displaying Boolean values with a check box control, and DataGridComboBoxColumn that allows selecting items from within a combo box. It is worth mentioning that for data types that the DataGrid has no default counterpart for, Visual Studio generates a custom cell template with DataGridTemplateColumn objects. In this case the custom template has been generated for embedding DatePicker controls for setting and displaying dates within cells.

Designing Columns

The IDE provides a convenient way for designing columns with the designer instrumentation. Simply select the DataGrid and in the Properties window, click Columns. Figure 3 shows how you can edit existing columns or add new ones, also setting data-binding at design time.

Figure 3. Designing columns with Visual Studio.


This is not enough, of course, in that some Visual Basic code is also required for fetching data and assigning such data to the user interface for presenting. If you now open the Visual Basic code behind the file for the current Window, you get the result shown in Listing 1.

Listing 1. The VB Auto-Generated Code for the Drag’n’Drop Data-Binding
'Add an Imports directive followed by the project namespace
Imports IntroducingDataBinding
Class MainWindow

Private Function GetCustomersQuery(ByVal NorthwindEntities As NorthwindEntities)_
As System.Data.Objects.ObjectQuery(Of Customer)

Dim CustomersQuery As System.Data.Objects.ObjectQuery(Of Customer) = _
NorthwindEntities.Customers
'Update the query to include Orders data in Customers.
'You can modify this code as needed.
CustomersQuery = CustomersQuery.Include("Orders")
'Returns an ObjectQuery.
Return CustomersQuery
End Function

Private Sub Window_Loaded(ByVal sender As System.Object,
ByVal e As System.Windows.RoutedEventArgs) _
Handles MyBase.Loaded

Dim NorthwindEntities As NorthwindEntities = New NorthwindEntities()
'Load data into Customers. You can modify this code as needed.
Dim CustomersViewSource As System.Windows.Data.CollectionViewSource = _
CType(Me.FindResource("CustomersViewSource"),
System.Windows.Data.CollectionViewSource)
Dim CustomersQuery As System.Data.Objects.ObjectQuery(Of Customer) = _
Me.GetCustomersQuery(NorthwindEntities)
CustomersViewSource.Source = CustomersQuery.Execute(System.Data.Objects.
MergeOption.AppendOnly)
End Sub
End Class


The GetCustomersQuery method returns the full list of customers and related orders, returning a new Entity Framework object, ObjectQuery(Of T). Such an object type represents a typed query and is also capable of receiving data back. Of course such a query is a default one; therefore, you may customize it according to your needs. When the window is loaded, other than the ObjectContext instance, notice how the code retrieves the instance of the CustomersViewSource (of type CollectionViewSource) via the FindResource method, which enables searching for a resource declared in XAML. This instance will finally receive the executed query so that its result will be reflected to the user interface. Basically the process is the following: The query fetches data; data is assigned to a CollectionViewSource instance; because this instance is bound to a UI control (such as the DataGrid), fetched data is reflected to the UI and vice versa. This is also because the DataGrid control provides support for the two-way data-binding, and this is also allowed by the ObjectQuery(Of T) class. At this point you can run the application to see the result shown in Figure 4.

Figure 4. The tabular data application running.

With a few mouse clicks you can build an application that can present tabular data. You can click inside the DataGrid for editing existing data or for adding new rows. If you want to save data to the underlying database, you should simply implement a control, such as a Button, whose Click event handler invokes the ObjectContext.SaveChanges method, and you are done. But you see this example in the next section, which is interesting but that requires a little bit of manual work.

Other -----------------
- Visual Basic 2010 : Introducing the Data-Binding
- Microsoft PowerPoint 2010 : Adding a Digital Signature
- Microsoft PowerPoint 2010 : Adding Security Encryption to a Presentation & Marking a Presentation as Read-Only
- Microsoft Visio 2010 : Creating a New Report
- Microsoft Visio 2010 : Running a Predefined Report
- Microsoft Excel 2010 : Building More Powerful Worksheets - Using Information Functions & Using Compatibility Functions
- Microsoft Excel 2010 : Building More Powerful Worksheets - Using Math Functions & Using Statistical Functions
- Microsoft Word 2010 : Expanding Word Functionality - Recording a Macro & Creating a Macro
- Microsoft Word 2010 : Expanding Word Functionality - Setting Developer Options & Understanding How Macros Automate Your Work
- Microsoft PowerPoint 2010 : Adding Password Protection to a Presentation
- Microsoft PowerPoint 2010 : Creating, Opening OneNotes & Inspecting Documents
- Visual Basic 2010 : Documenting the Source Code - Implementing XML Comments
- Visual Basic 2010 : Documenting the Source Code - Understanding XML Documents
- Microsoft Visio 2010 : Linking Data to Shapes Automatically
- Microsoft Visio 2010 : Refreshing Selected Data in Linked Diagrams & Scheduling Data Refresh
- Microsoft Excel 2010 : Building More Powerful Worksheets - Using Logical & Financial Functions
- Microsoft Excel 2010 : Building More Powerful Worksheets - Using Date & Time Functions
- Microsoft PowerPoint 2010 : Editing Comments in a Presentation
- Microsoft PowerPoint 2010 : Adding Comments to a Presentation
- Microsoft Visio 2010 : Creating New Shape Data Fields
 
 
Most view of day
- SharePoint 2010 : Configuring Search Settings and the User Interface - Federated Search
- System Center Configuration Manager 2007 : Operating System Install Packages and Image Packages (part 1) - Automated Image Creation and Capture
- Zero Touch Installations : Creating and Capturing a Reference Image (part 2) - Install Packages on the Distribution Points, Create a Collection and a Computer Association
- Microsoft Word 2010 : Creating Desktop Publishing Documents - Adding Page Backgrounds (part 2) - Add or Remove a Page Border , Add Page Color
- Microsoft Visio 2010 : Working with Text (part 2) - Editing and Formatting Text
- Microsoft Exchange Server 2010 : Completing Transport Server Setup (part 3) - Enabling Anti-Spam Features
- Backup and Restore of Microsoft Lync Server 2010 : Backup Processes (part 1) - Backing Up Lync Server Databases
- Microsoft Dynamics CRM 2011 : Using Advanced Find (part 5) - Using Edit Multiple Records and Assign Multiple Records from Advanced Find
- Windows Phone 7 : 3D Game Development (part 2) - Rendering 3D Primitives
- Deploying Applications Using Group Policy and SCCM 2007 : Creating Software Installation Policies
Top 10
- Windows Server 2012 : Administering Active Directory using Windows PowerShell (part 3) - Performing an advanced Active Directory administration task
- Windows Server 2012 : Administering Active Directory using Windows PowerShell (part 2) - Finding Active Directory administration cmdlets
- Windows Server 2012 : Administering Active Directory using Windows PowerShell (part 1) - Managing user accounts with Windows PowerShell
- Windows Server 2012 : Enabling advanced features using ADAC (part 3) - Creating fine-grained password policies
- Windows Server 2012 : Enabling advanced features using ADAC (part 2) - Configuring fine-grained password policies
- Windows Server 2012 : Enabling advanced features using ADAC (part 1) - Enabling and using the Active Directory Recycle Bin
- Microsoft Excel 2010 : Protecting and Securing a Workbook - Marking a Workbook as Read-Only
- Microsoft Excel 2010 : Protecting and Securing a Workbook - Working with Office Safe Modes
- Microsoft Excel 2010 : Protecting and Securing a Workbook - Setting External Content Security Options
- Microsoft Excel 2010 : Protecting and Securing a Workbook - Setting Privacy Options - Set Parental Controls for Online Research
 
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro