Partager via


Silverlight Object Binding in Visual Studio 2010 Beta2

Visual Studio 2010 provides drag-and-drop data binding from the Data Sources window in Silverlight applications. The Data Sources window simplifies the process of creating data-bound controls to present application data to users. This example shows how to display data from 2 related business objects in a Silverlight application.

For a video version of this blog entry, see https://go.microsoft.com/fwlink/?LinkId=182988 .

This blog demonstrates the following tasks:

  • Creating a Silverlight application.
  • Creating 2 custom objects.
  • Running the Data Source Configuration Wizard (which populates the Data Sources window).
  • Creating a set of data-bound controls by dragging items from the Data Sources window.
  • Loading the custom objects with data.

Create the Silverlight Application

Open Visual Studio 2010 Beta2 and create a new (VB or C#) Silverlight Application and name it SilverlightObjectBinding.

Leave the default settings in the New Silverlight Application dialog box.

Creating Custom Objects to Bind To

To expose data to an application, a data model must be defined. In this example, create custom objects that represent customers and orders for the data model.

Creating the Customer Class
  • Add a new Class item named Customer to the SilverlightObjectBinding project.
  • In the Customer code file, replace the Customer class with the following code:

Visual Basic:

 ''' <summary>
''' A single customer
''' </summary>
Public Class Customer

    Public Sub New()
    End Sub

    ''' <summary>
    ''' Creates a new customer
    ''' </summary>
    ''' <param name="customerId">The ID that uniquely identifies this customer</param>
    ''' <param name="companyName">The name for this customer</param>
    ''' <param name="city">The city for this customer</param>
    Public Sub New(ByVal customerId As String,
                   ByVal companyName As String,
                   ByVal city As String)
        customerIDValue = customerId
        companyNameValue = companyName
        cityValue = city
    End Sub

    Private customerIDValue As String
    ''' <summary>
    ''' The ID that uniquely identifies this customer
    ''' </summary>
    Public Property CustomerID() As String
        Get
            Return customerIDValue
        End Get
        Set(ByVal value As String)
            customerIDValue = value
        End Set
    End Property

    Private companyNameValue As String
    ''' <summary>
    ''' The name for this customer
    ''' </summary>
    Public Property CompanyName() As String
        Get
            Return companyNameValue
        End Get
        Set(ByVal Value As String)
            companyNameValue = Value
        End Set
    End Property

    Private cityValue As String
    ''' <summary>
    ''' The city for this customer
    ''' </summary>
    Public Property City() As String
        Get
            Return cityValue
        End Get
        Set(ByVal Value As String)
            cityValue = Value
        End Set
    End Property

    Private ordersValue As Orders
    ''' <summary>
    ''' The orders for this customer
    ''' </summary>
    Public Property Orders As Orders
        Get
            Return ordersValue
        End Get
        Set(ByVal value As Orders)
            ordersValue = value
        End Set
    End Property


    Public Overrides Function ToString() As String
        Return Me.CompanyName & " (" & Me.CustomerID & ")"
    End Function
End Class


''' <summary>
''' A collection of Customer objects.
''' </summary>
''' <remarks></remarks>
Public Class Customers
    Inherits System.Collections.Generic.List(Of Customer)

End Class

C#:

 /// <summary>
/// A single customer
/// </summary>
public class Customer
{
    /// <summary>
    /// Creates a new customer
    /// </summary>
    public Customer()
    {
    }

    /// <summary>
    /// Creates a new customer
    /// </summary>
    /// <param name="customerID"></param>
    /// <param name="companyName"></param>
    /// <param name="city"></param>
    public Customer(string customerID, string companyName,
       string city)
    {
        customerIDValue = customerID;
        companyNameValue = companyName;
        cityValue = city;
    }

    private string customerIDValue;
    /// <summary>
    /// The ID that uniquely identifies this customer
    /// </summary>
    public string CustomerID
    {
        get { return customerIDValue; }
        set { customerIDValue = value; }
    }

    private string companyNameValue;
    /// <summary>
    /// The name for this customer
    /// </summary>
    public string CompanyName
    {
        get { return companyNameValue; }
        set { companyNameValue = value; }
    }

    private string cityValue;
    /// <summary>
    /// The city for this customer
    /// </summary>
    public string City
    {
        get { return cityValue; }
        set { cityValue = value; }
    }

    private Orders ordersValue;
    /// <summary>
    /// The orders for this customer
    /// </summary>
    public Orders Orders
    {
        get { return ordersValue; }
        set { ordersValue = value; }
    }

    public override string ToString()
    {
        return this.CompanyName + " (" + this.CustomerID + ")";
    }
}

/// <summary>
/// A collection of Customer objects
/// </summary>
public class Customers : System.Collections.Generic.List<Customer>
{

}
Creating the Order Class
  • Add a new Class item named Order to the SilverlightObjectBinding project.
  • In the Order code file, replace the Order class with the following code:

Visual Basic:

 ''' <summary>
''' A single order
''' </summary>
Public Class Order

    Public Sub New()
    End Sub

    ''' <summary>
    ''' Creates a new order
    ''' </summary>
    ''' <param name="orderid">The identifier for this order</param>
    ''' <param name="customerID">The customer who placed this order</param>
    Public Sub New(ByVal orderid As Integer,
                   ByVal customerID As String)
        orderIDValue = orderid
        customerIDValue = customerID
    End Sub

    Private orderIDValue As Integer
    ''' <summary>
    ''' Identifier for this order
    ''' </summary>
    Public Property OrderID() As Integer
        Get
            Return orderIDValue
        End Get
        Set(ByVal value As Integer)
            orderIDValue = value
        End Set
    End Property

    Private customerIDValue As String
    ''' <summary>
    ''' The customer who placed this order
    ''' </summary>
    Public Property CustomerID() As String
        Get
            Return customerIDValue
        End Get
        Set(ByVal Value As String)
            customerIDValue = Value
        End Set
    End Property
End Class

''' <summary>
''' A collection of Orders
''' </summary>
Public Class Orders
    Inherits System.Collections.Generic.List(Of Order)

End Class

C#:

 /// <summary>
/// A single order
/// </summary>
public class Order
{
    /// <summary>
    /// Creates a new order
    /// </summary>
    /// <param name="orderid"></param>
    /// <param name="customerID"></param>
    public Order(int orderid, string customerID)
    {
        orderIDValue = orderid;
        customerIDValue = customerID;
    }

    private int orderIDValue;
    /// <summary>
    /// The ID that uniquely identifies this order
    /// </summary>
    public int OrderID
    {
        get { return orderIDValue; }
        set { orderIDValue = value; }
    }

    private string customerIDValue;
    /// <summary>
    /// The customer who placed this order
    /// </summary>
    public string CustomerID
    {
        get { return customerIDValue; }
        set { customerIDValue = value; }
    }
}

/// <summary>
/// A collection of Order objects
/// </summary>
public class Orders : System.Collections.Generic.List<Order>
{

}

Creating the Object Data Source

Create an object data source and populate the Data Sources window by running the Data Source Configuration Wizard.

  • In the Data Sources window, click Add New Data Source.
  • In the Choose a Data Source Type page, click Object and then click Next.

ObjectBinding1

  • In the Select the Data Objects page, expand the tree view twice, and then select the check box next to Customers. Be sure to select Customers, and not the singular Customer. If Customers is not available, exit the wizard and rebuild the solution.

ObjectBinding2

  • Finish the wizard and the Data Sources window is populated with the object data source.

 

Creating Data-Bound Controls

Create controls that display data in the objects by dragging the Customers and Orders nodes from the Data Sources window to the designer.

  • Open MainPage.xaml in design view.
  • From the Data Sources window, drag the Customers node to the designer.
  • From the Data Sources window, drag the Orders node to the designer below the customers grid.

ObjectBinding3

 

Populate the Objects with Data and Bind Them to the Controls

After you drag an object data source from the Data Sources window onto the Silverlight designer, a CollectionViewSource (System.Windows.Data.CollectionViewSource.Source) is generated as a resource to bind controls in the UI.

Create Sample Data to Bind To

Now we need some data to bind to and display so create some sample data. The following code creates 3 customers, each with 3 orders:

  • Open the MainPage.xaml code file (MainPage.xaml.vb or MainPage.xaml.cs) and add the following method to the MainPage class:

Visual Basic:

     ' Create sample data.
    Private Function GetCustomers() As Customers

        Dim customers As New Customers

        ' Create 3 sample customers,
        ' each with 3 sample orders.
        Dim cust1 As New Customer("1", "A Bike Store", "Seattle")
        Dim cust1Orders As New Orders
        cust1Orders.Add(New Order(1, cust1.CustomerID))
        cust1Orders.Add(New Order(2, cust1.CustomerID))
        cust1Orders.Add(New Order(3, cust1.CustomerID))
        cust1.Orders = cust1Orders

        Dim cust2 As New Customer("2", "Progressive Sports", "Renton")
        Dim cust2Orders As New Orders
        cust2Orders.Add(New Order(4, cust2.CustomerID))
        cust2Orders.Add(New Order(5, cust2.CustomerID))
        cust2Orders.Add(New Order(6, cust2.CustomerID))
        cust2.Orders = cust2Orders

        Dim cust3 As New Customer("3", "Advanced Bike Components", "Irving")
        Dim cust3Orders As New Orders
        cust3Orders.Add(New Order(7, cust3.CustomerID))
        cust3Orders.Add(New Order(8, cust3.CustomerID))
        cust3Orders.Add(New Order(9, cust3.CustomerID))
        cust3.Orders = cust3Orders

        ' Add the sample customer objects to the 
        ' Customers collection.
        customers.Add(cust1)
        customers.Add(cust2)
        customers.Add(cust3)

        Return customers
    End Function

C#:

 // Create sample data.
private Customers GetCustomers()
{
    Customers customers = new Customers();

    // Create 3 sample customers,
    // each with 3 sample orders.
    Customer cust1 = new Customer("1", "A Bike Store", "Seattle");
    Orders cust1Orders = new Orders();
    cust1Orders.Add(new Order(1, cust1.CustomerID));
    cust1Orders.Add(new Order(2, cust1.CustomerID));
    cust1Orders.Add(new Order(3, cust1.CustomerID));
    cust1.Orders = cust1Orders;

    Customer cust2 = new Customer("2", "Progressive Sports", "Renton");
    Orders cust2Orders = new Orders();
    cust2Orders.Add(new Order(4, cust2.CustomerID));
    cust2Orders.Add(new Order(5, cust2.CustomerID));
    cust2Orders.Add(new Order(6, cust2.CustomerID));
    cust2.Orders = cust2Orders;

    Customer cust3 = new Customer("3", "Advanced Bike Components", "Irving");
    Orders cust3Orders = new Orders();
    cust3Orders.Add(new Order(7, cust3.CustomerID));
    cust3Orders.Add(new Order(8, cust3.CustomerID));
    cust3Orders.Add(new Order(9, cust3.CustomerID));
    cust3.Orders = cust3Orders;

    // Add the sample customer objects to the 
    // Customers collection.
    customers.Add(cust1);
    customers.Add(cust2);
    customers.Add(cust3);

    return customers;
}
Load the Objects with Sample Data and Assign the Data to the CollectionViewSource to Facilitate Databinding

Load data into your objects and bind to the controls by setting the generated CollectionViewSource (CustomersViewSource in this example) to your data. Be sure to load your data at runtime. Set the CollectionViewSource.Source property to your data in the controls Loaded event handler. The following code shows how to load data when the application is running (not in design mode):

  • Create an event handler for the control’s Loaded event and replace the generated code with the following:

Visual Basic:

         'Do not load your data at design time.
        If Not (System.ComponentModel.DesignerProperties.GetIsInDesignMode(Me)) Then
            'Load your data here and assign the result to the CollectionViewSource.
            Dim myCollectionViewSource As System.Windows.Data.CollectionViewSource =
                CType(Me.Resources("CustomersViewSource"), System.Windows.Data.CollectionViewSource)
            myCollectionViewSource.Source = GetCustomers()
        End If

C#:

         // Do not load your data at design time.
        if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
        {
            //Load your data here and assign the result to the CollectionViewSource.
            System.Windows.Data.CollectionViewSource myCollectionViewSource = 
                (System.Windows.Data.CollectionViewSource)this.Resources["customersViewSource"];
            myCollectionViewSource.Source = GetCustomers();
        }

 

Run and Test the Application

Build and run the application to verify that you can view customer records.

  • Verify that the 3 sample customers appear in the datagrid and the selected customer's orders are displayed in the orders grid.
  • Select a different customer and verify that the orders are updated to display only the orders for the selected customer.

ObjectBinding4

 

Conclusion

Visual Studio 2010 provides drag-and-drop data binding from the Data Sources window to the Silverlight designer. Running the Data Source Configuration Wizard in Silverlight applications simplifies the process of rendering data-bound controls to present application data to users.

Comments

  • Anonymous
    April 26, 2010
    If the object I want to bind is not a list (i.e. customer instead of customers), what would I have to do? If I select details in the combo, VS2010 also generates a collectionView, and customer is not a list.

  • Anonymous
    April 27, 2010
    Hi Oscar, In the Data Source Window pattern, the CollectionViewSource is always generated for databinding. May I know what you want to achieve here? Thanks, Xiaoying Guo Program Manager, Visual Studio Business Applications Tooling

  • Anonymous
    May 04, 2010
    I'm stuck with this example, when I drag the Customers data source to the design surface I get the following error in the XAML for this entry: xmlns:my="clr-namespace:" "A namespace prefix declaration cannot be empty". I have built the project, cleaned, rebuilt but still get the same error.  I'm using VS 2010 Pro RTM and SL 4. What is the code for the namespace and why would it not be automatically added?

  • Anonymous
    May 04, 2010
    Hi WebMinder, The code missing here is the namespace name of your object. For example, if your object is defined under namespace SilverlightApplication1, the code for this is xmlns:my="clr-namespace:SilverlightApplication1". May I know what language you are using? Does it happen all the times in different projects? Thanks, Xiaoying

  • Anonymous
    May 04, 2010
    Thanks for the quick response Xiaoying.  I'm using C# and don't get the problem when I define a simple class such as (Person.cs): namespace SilverlightApplication {    public class Person {        public string FirstName { get; set; }    } } Dropping that produces: xmlns:my="clr-namespace:SilverlightApplication" In the same project, when I drop the Customer class, and add "SilverlightApplication" to the namespace declaration, I get "'my:Customers' was not found".  I created a new app and got exactly the same problem.