How to: Bind Controls to Derived Types (Entity Framework)
Object Services enables you to bind Windows Forms controls such as a ComboBox or DataGridView to an EntityCollection. However, when you execute the OfType method on an EntityCollection to return a collection of objects of a derived type, you cannot bind the returned IEnumerable directly to a control. The example in this topic shows how to use the CreateSourceQuery method to create an ObjectQuery that defines the EntityCollection. This query is executed with the OfType method to perform the binding to a specific subtype. For more information, see Binding Objects to Controls (Entity Framework).
The example in this topic is based on a modified version of the School model. This version supports table-per-type inheritance with Course as an abstract type. Complete the Mapping Inheritance - Table-per-Type walkthrough to modify the School model to support the table-per-type inheritance example used in this topic.
Example
The following example is from a Windows Form. When the form is loaded, an ObjectResult of Department objects is returned by calling the Execute method of the ObjectQuery. This result is bound to a combo box. When an order is selected, the CreateSourceQuery method is called on the related EntityCollection of Course objects. The returned ObjectQuery executed using the OfType method and the result is bound to a DataGridView control. The type that is used with the OfType method is set based on a radio-box setting in the form.
Imports System
Imports System.Collections.Generic
Imports System.Collections
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports System.Data.Objects
Imports System.Data.Objects.DataClasses
Public Class SchoolForm
Dim context As SchoolEntities
Dim isOnlineCourse As Boolean = False
Public Sub New()
' Initializes the designer-generated controls.
InitializeComponent()
If isOnlineCourse Then
radioButtonOnline.Checked = True
Else
radioButtonOnsite.Checked = True
End If
End Sub
Private Sub SchoolForm_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
' Initialize the object context.
Try
context = New SchoolEntities()
' Create a query for all departments.
Dim departmentQuery As ObjectQuery(Of Department) = _
context.Department
' Display the department name in the combo box.
Me.comboBoxDepartment.DisplayMember = "Name"
' Bind the combo box to the ObjectResult of the departments
' that are returned when the query is executed.
Me.comboBoxDepartment.DataSource = _
departmentQuery.Execute(MergeOption.AppendOnly)
Catch ex As EntitySqlException
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub BindToCourseByType()
' Get the currently selected Department object.
Dim selectedDepartment As Department = _
CType(Me.comboBoxDepartment.SelectedItem, Department)
Try
If isOnlineCourse Then
' Bind the data grid to the result of the execution of the ObjectQuery
' that returns only the online courses for the selected department.
dataGridViewCourses.DataSource = _
selectedDepartment.Course.CreateSourceQuery() _
.OfType(Of OnlineCourse)().Execute(MergeOption.AppendOnly)
Else
' Bind the data grid to the result of the execution of the ObjectQuery
' that returns only the on-site courses for the selected department.
dataGridViewCourses.DataSource = _
selectedDepartment.Course.CreateSourceQuery() _
.OfType(Of OnsiteCourse)().Execute(MergeOption.AppendOnly)
End If
' Hide the columns bound to navigation properties.
dataGridViewCourses.Columns("Department").Visible = False
dataGridViewCourses.Columns("CourseGrade").Visible = False
dataGridViewCourses.Columns("Person").Visible = False
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub comboBoxDepartment_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comboBoxDepartment.SelectedIndexChanged
Me.BindToCourseByType()
End Sub
Private Sub radioButtonOnline_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles radioButtonOnline.CheckedChanged
If Me.radioButtonOnline.Checked Then
isOnlineCourse = True
Me.BindToCourseByType()
Else
isOnlineCourse = False
Me.BindToCourseByType()
End If
End Sub
Private Sub buttonClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonClose.Click
Me.Close()
End Sub
End Class
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
namespace Microsoft.Samples.Edm
{
public partial class SchoolForm : Form
{
private SchoolEntities context;
private bool isOnlineCourse = false;
public SchoolForm()
{
// Initializes the designer-generated controls.
InitializeComponent();
if (isOnlineCourse) radioButtonOnline.Checked = true;
else radioButtonOnsite.Checked = true;
}
private void SchoolForm_Load(object sender, EventArgs e)
{
// Initialize the object context.
try
{
context = new SchoolEntities();
// Create a query for all departments.
ObjectQuery<Department> departmentQuery =
context.Department;
// Display the department name in the combo box.
this.comboBoxDepartment.DisplayMember = "Name";
// Bind the combo box to the ObjectResult of the departments
// that are returned when the query is executed.
this.comboBoxDepartment.DataSource =
departmentQuery.Execute(MergeOption.AppendOnly);
}
catch (EntitySqlException ex)
{
MessageBox.Show(ex.Message);
}
}
private void BindToCourseByType()
{
// Get the currently selected Department object.
Department selectedDepartment =
(Department)this.comboBoxDepartment.SelectedItem;
try
{
if (isOnlineCourse)
{
// Bind the data grid to the result of the execution of the ObjectQuery
// that returns only the online courses for the selected department.
dataGridViewCourses.DataSource =
selectedDepartment.Course.CreateSourceQuery()
.OfType<OnlineCourse>().Execute(MergeOption.AppendOnly);
}
else
{
// Bind the data grid to the result of the execution of the ObjectQuery
// that returns only the on-site courses for the selected department.
dataGridViewCourses.DataSource =
selectedDepartment.Course.CreateSourceQuery()
.OfType<OnsiteCourse>().Execute(MergeOption.AppendOnly);
}
// Hide the columns bound to navigation properties.
dataGridViewCourses.Columns["Department"].Visible = false;
dataGridViewCourses.Columns["CourseGrade"].Visible = false;
dataGridViewCourses.Columns["Person"].Visible = false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void departmentComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
this.BindToCourseByType();
}
private void onlineRadio_CheckedChanged(object sender, EventArgs e)
{
if (this.radioButtonOnline.Checked)
{
isOnlineCourse = true;
this.BindToCourseByType();
}
else
{
isOnlineCourse = false;
this.BindToCourseByType();
}
}
private void Close_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
See Also
Tasks
How to: Bind Objects to Windows Presentation Foundation Controls (Entity Framework)
How to: Bind Objects to Windows Form Controls (Entity Framework)