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)

Concepts

Binding Objects to Controls (Entity Framework)