Sei sulla pagina 1di 208

Events Overview for Silverlight

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

This topic describes the programming concept of events, and how the event concept works in Silverlight and its programming models. Silverlight events are essentially the same event concept as defined by the common language runtime (CLR) and the .NET Framework. Similar to WPF, you can assign handlers for events as part of the declarations for UI elements in XAML, or you can use language-specific syntax to add the handlers in code. Silverlight supports the concept of routed events, which is a feature whereby certain input events and data events can be handled by objects other than the object that raised the event. Routed events are useful when compositing control templates or when centralizing the event logic of an application page. This topic contains the following sections.

Events as a Programming Concept Button.Click: An Introduction to Using Silverlight Events Defining an Event Handler The sender Parameter and Event Data Adding Event Handlers in Managed Code Routed Events Input Event Handlers in Controls User-Initiated Events Programming Model Alternatives Removing Event Handlers Commanding What's Next Related Topics

Events as a Programming Concept

An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user interaction, such as a mouse click, or it could be triggered by the internal logic of a class. The object that raises the event is called the event sender. The object that captures the event and responds to it is called the event receiver. Basically the purpose of events is to communicate time-specific, relatively lightweight information from an object at run time, and potentially to deliver that information to other objects in the application.

Silverlight Events Generally speaking, Silverlight events are CLR events, and therefore are events that you can handle with managed code. If you know how to work with basic CLR events already, you have a head start on some of the concepts involved. But you do not necessarily need to know that much about the CLR event model in order to perform some basic tasks, such as attaching handlers. (If you want some more conceptual background, see Events, Delegates, and CLR Event System Conventions.) Because the UI for a typical Silverlight-based application is defined in markup (XAML), some of the principles of connecting UI events from markup elements to a runtime code entity are similar to other Web technologies, such as ASP.NET, or working with an HTML DOM. In Silverlight and WPF, the code that provides the runtime logic for a XAML-defined UI is often referred to as code-behind or the code-behind file. In the Visual Studio solution views, this relationship is shown graphically, with the code-behind file being a dependent and nested file versus the XAML page it refers to. In addition to the CLR events that act within its own runtime object model, Silverlight also has a few events that can invoke script-based handlers on the plug-in instance itself and at the HTML level, such as OnError. These events are exposed and can be handled by any script working against the plug-in instance in the HTML DOM. As a general event model for an application, HTML scripting should have first chance to do the handling, and if you handle events in an HTML, these events should not be passed on to the managed API.

Note:

Because Silverlight often operates within the plug-in architecture of the hosting browser, the input stimulus for input events is initially handled by the browser host. The input information is then sent to the Silverlight plug-in through that browser's API for general plug-in support, and you can handle the corresponding events defined in the Silverlight API. Most other non-input events in Silverlight do not necessarily have such browser implications.
Button.Click: An Introduction to Using Silverlight Events

Because Silverlight is a UI technology, one of the most common tasks you have is to capture user input to the UI. For example, your UI might have a button that the user must click to submit information or change your application's state. Generally, you define the UI for your Silverlight-based application by generating XAML. This XAML can be the output from a designer such as Microsoft Expression Blend or from a design surface in a larger IDE such as Silverlight Designer for Visual Studio. The XAML can also be written out in a plaintext editor or a third-party XAML editor. As part of generating that XAML,

you can wire event handlers for individual UI elements at the same time that you define all the other attributes that describe that UI element. Event wiring in XAML involves specifying the string-form name of the handler method that you define in your code-behind. For example, the following XAML defines a Button object with some important properties assigned as attributes and wires a handler for the button's Click event:
Copy to Clipboard
<Button Name="showUpdatesButton" Content="{Binding ShowUpdatesText}" Click="showUpdatesButton_Click"/>

The actual handler is written in one of the programming languages that are supported by the .NET Framework for Silverlight, such as Visual Basic or C#. With the attribute Click="showUpdatesButton_Click", you have created a contract that when the XAML is markup-compiled and parsed, both the XAML markup compile step in your development environment's build action and the eventual Silverlight runtime that parses the XAML can find a method named showUpdatesButton_Click. Moreover, showUpdatesButton_Click must be a method that implements a compatible method signature (based on a delegate) for any handler of the Click event. For example, the following code defines the showUpdatesButton_Click handler.
JavaScript C# C++ F# JScript VB Copy to Clipboard
private void showUpdatesButton_Click (object sender, RoutedEventArgs e) { Button b = e.OriginalSource as Button; //more logic to do here... ... }

If you are using Silverlight Designer for Visual Studio, you can use design features that make it very simple to wire event handlers from XAML and then define them in code-behind. This includes providing an automatic naming scheme for the handlers. For more information, see Walkthrough: Creating Your First Silverlight Application.

You can also use the .NET Framework Class Library for Silverlight documentation to look up a specific event and determine its delegate. The handler you write must be compatible with that delegate signature. For the previously shown example, the best matching delegate is RoutedEventHandler.

Note:

Silverlight event-handler functions cannot be called with parameter values (even empty ones), which is a notable difference from event handler syntax in the HTML DOM. The attribute value in XAML references the handler name only, and other mechanisms, such as the expected input parameters of your handler, pass the information.
Defining an Event Handler

For objects that are UI and declared in XAML, event handler code must be defined in the partial class that serves as the code-behind for a XAML page. For more information about how partial classes and code-behind for XAML work together, see Code-Behind and Partial Classes. Event handlers in the partial class are written as methods, based on the CLR delegates that are used by that particular event. Your event handler methods can be public, or they can have a private access level. Private access works because the handler and instance created by the XAML are ultimately joined by code generation. The general recommendation is to not make your event handler methods public in the class.
The sender Parameter and Event Data

Any handler you write for a managed Silverlight event can access two values that are available as input for each case where your handler is invoked. The first such value is sender, which is a reference to the object where the handler is attached. The sender parameter is typed as the base Object type. A common technique in Silverlight and WPF event handling is to cast sender to a more precise type. This technique is useful if you expect to check or change state on the sender object itself. Based on your own application design, you expect a type that is safe to cast sender to, based on where the handler is attached or other design specifics. The second value is event data, which generally appears in signatures as the e parameter. Per the CLR event model, all events send some kind of event data, with that data captured as an instance of a class that inherits EventArgs (or is EventArgs itself). You can discover which properties for event data are available by looking at the e parameter of the delegate that is assigned for the specific event you are handling, and then using Intellisense in Visual Studio or the .NET Framework Class Library for Silverlight. Some Silverlight events use the EventHandler<

TEventArgs> delegate or other generic handler types. An example is ColumnReordered. In most cases, the event definitions constrains the generic with a specific EventArgs derived event data class. You should then write the handler method as if it took that EventArgs derived event data class directly as the second parameter. For some events, the event data in the EventArgs derived class is as important as knowing that the event was raised. This is especially true of the input events. For mouse events, the position of the mouse when the event occurred might be important. For keyboard events, key presses on the keyboard raise the same KeyUp and KeyDown events. In order to determine which key was pressed, you must access the KeyEventArgs that is available to the event handler. For more information about handling input events, see Mouse Support and Keyboard Support. Input events and input scenarios often have additional considerations that are not covered in this topic, such as mouse capture for mouse events, and modifier keys and platform key codes for keyboard events.

Adding Event Handlers in Managed Code

XAML is not the only way to assign an event handler to an object. To add event handlers to any given object in managed code, including to objects that are not even usable in XAML, you can use the CLR language-specific syntax for adding event handlers. In C#, the syntax is to use the += operator. You instantiate the handler by declaring a new delegate that uses the event handler method name. If you are using code to add event handlers to objects that appear in the run-time UI, a common practice for Silverlight is to add such handlers in response to an object lifetime event or callback, such as Loaded or OnApplyTemplate, so that the event handlers on the relevant object are ready for user-initiated events at run time. The following example illustrates first the XAML outline to give some idea of the structure and then provides the C# language syntax.
JavaScript C# C++ F# JScript VB Copy to Clipboard

void LayoutRoot_Loaded(object sender, RoutedEventArgs e) { textBlock1.MouseEnter += new MouseEventHandler(textBlocks_MouseEnter); textBlock1.MouseLeave += new MouseEventHandler(textBlocks_MouseLeave); }

XAML Copy to Clipboard


<Grid x:Name="LayoutRoot" Loaded="LayoutRoot_Loaded"> <StackPanel> <TextBlock Name="textBlock1">Put the mouse over this text</TextBlock> ... </StackPanel> </Grid>

There are two possibilities for Visual Basic syntax. One is to parallel the C# syntax and attach handlers directly to instances. This requires the AddHandler keyword and also the AddressOf operator that dereferences the handler method name.
JavaScript C# C++ F# JScript VB Copy to Clipboard
Private Sub LayoutRoot_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs e) AddHandler textBlock1.MouseEnter, AddressOf textBlocks_MouseEnter AddHandler textBlock1.MouseLeave, AddressOf textBlocks_MouseLeave End Sub

The other option for Visual Basic syntax is to use the Handles keyword on event handlers. This technique is appropriate for cases where handlers are expected to exist on objects at load time and persist throughout the object lifetime. Using Handles on an object that is defined in XAML requires that you provide a Name / x:Name. This name becomes the instance qualifier that is needed for the Instance.Event part of the Handles syntax. In this case you do not need an object lifetime-based event handler to initiate attaching the other event handlers; the Handles connections are created when you compile your XAML page.
JavaScript C#

C++ F# JScript VB Copy to Clipboard


Sub textBlock1_MouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs) Handles textBlock1.MouseEnter '.... End Sub Sub textBlock1_MouseLeave(ByVal sender As Object, ByVal e As MouseEventArgs) Handles textBlock1.MouseLeave '.... End Sub

Note:

Visual Studio and its XAML design surface generally promote the instance-handling technique instead of the Handles keyword. This is because establishing the event handler wiring in XAML is part of typical designer-developer workflow for Silverlight and WPF, and the Handles keyword technique is incompatible with wiring the event handlers in XAML.
Routed Events

Silverlight supports the concept of a routed event for several input events that are defined in base classes and are present on most UI elements that support user interaction and input. The following is a list of input events that are routed events:

KeyDown KeyUp GotFocus LostFocus MouseLeftButtonDown MouseLeftButtonUp MouseRightButtonDown MouseRightButtonUp MouseMove MouseWheel BindingValidationError DragEnter DragLeave DragOver

Drop

A routed event is an event that is potentially passed on (routed) from a child object to each of its successive parent objects in the object tree. The object tree in question is approximated by the XAML structure of your UI, with the root of that tree being the root element in XAML. The true object tree might vary somewhat from the XAML because the object tree does not include XAML language features such as property element tags. In general you can think of the routed events as "bubbling" from XAML object element children that raise the event, toward the parent object element that contains them. The event occurrence and its event data continue and are reported to objects along the event route until the root element is reached. (If you have used certain Web technologies such as DHTML, the "bubbling" concept might already be familiar to you.)

Note:

WPF supports an analogous "tunneling" routing strategy, whereby the root of a page / object tree has the first chance to handle a routed event, and the event then "tunnels" down the object tree toward its event source. Silverlight does not use "tunneling" routed events. Events in Silverlight either follow the "bubbling" routing strategy (and are referred to as routed events) or do not route at all. There are also other API-level differences in routed event behavior between Silverlight and WPF. The OriginalSource Property of RoutedEventArgs When an event bubbles up an event route, sender is no longer the same object as the eventraising object. Instead, sender is the object where the handler that is being invoked is attached. In many cases, sender is not the object of interest, and you are instead interested in knowing information such as which of the possible child objects the mouse is over, or which object held focus when a keyboard key was pressed. For these cases, the value of the OriginalSource property is the object of interest. At all points on the route, OriginalSource reports the original object that raised the event, instead of where the handler is attached. For an example scenario where this is useful, consider an application where you want certain key combinations to be "hot keys" or accelerators, regardless of which control currently holds keyboard focus and initiated the event. In terms of the object tree, the focused object might be nested within some items list in a list box, or could be one of hundreds of objects in the overall UI. Having to attach handlers to every possible focusable object in an application to detect your accelerator is obviously impractical. But because the keyboard events are bubbling routed events, the event eventually reaches the root object in its route. Therefore, you can often attach a single KeyDown handler on the root object and rely on the behavior that a KeyDown event eventually bubbles to the root object. Then the handler can determine whether that key is the valid combination for an intended accelerator action, or whether no action is necessary.

The Handled Property Several event data classes for specific routed events contain a property named Handled. For examples, see MouseButtonEventArgs. Handled, KeyEventArgs. Handled, MouseWheelEventArgs. Handled, DragEventArgs. Handled, and ValidationError EventArgs. Handled.Handled is a settable Boolean property. Setting the Handled property to true influences the event system in Silverlight. When you set the value to true in event data, the routing stops for most event handlers; the event does not continue along the route to notify other attached handlers of that particular event case. What "handled" as an action means in the context of the event and how your application responds is up to you. However, you should keep in mind the behavior of the Silverlight event system if you set Handled in your event handlers. Not all of the routed events are cancellable in this way. GotFocus, LostFocus, and MouseMove will always route all the way to the root, and their event data classes do not have a Handled property that can influence that behavior. Therefore, checking OriginalSource values for those events is often a good idea, to make sure you are not handling an event and making incorrect assumptions about what the event means and here the input event originated in the UI layout.
Note:

The concept of a Handled property for routed events also exists in WPF. In WPF, the Handled property exists on all routed event-data classes; in Silverlight, only the specific event data classes that have their own Handled property can be used to cancel the related event's route. Routed Events Outside the Visual Tree Certain objects in Silverlight participate in a relationship with the primary visual tree that is conceptually like an overlay over the main visuals. These objects are not part of the usual parentchild relationships that connect all tree elements to the visual root. This is the case for any displayed Popup or ToolTip. If you want to handle routed events from a Popup or ToolTip, you should place the handlers on specific UI elements that are within the Popup or ToolTip and not the Popup or ToolTip elements themselves. You should not rely on routing inside any compositing that is performed for Popup or ToolTip content. This is because event routing for routed events works only along the main visual tree. Popup or ToolTip is not considered a parent of subsidiary UI elements and never receives the routed event, even if it is trying to use something like the Popup default background as the capture area for input events.
Input Event Handlers in Controls

Specific existing Silverlight controls sometimes use this Handled concept for input events internally. This can give the appearance from user code that an input event never occurs. For example, the Button class includes logic that deliberately handles the general input event MouseLeftButtonDown. It does so because the class raises a Click event that is initiated by that mouse input. For purposes of the class design, the raw mouse event is conceptually handled, and class consumers should instead choose to handle or not handle Click. Reference topics for specific control classes in the .NET Framework Library often note the event handling behavior implemented by the class. In some cases, the behavior can be changed or appended in subclasses by overriding OnEvent methods. For example, you can change how your TextBox derived class reacts to key input by overriding TextBox. OnKeyDown. Registering Handlers for Already-Handled Routed Events Earlier it was stated that setting Handled to true prevented most handlers from acting. The API AddHandler provides a technique where you can attach a handler that will always be invoked for the route, even if some other handler earlier in the route has set Handled to true. This technique is useful if a control you are using has handled the event in its internal compositing or for control-specific logic but you still want to respond to it on a control instance, or higher in the route. However, this technique should be used with caution because it can contradict the purpose of Handled and possibly violate a control's intended usage or object model. For more information including a usage example, see AddHandler.
User-Initiated Events

Silverlight enforces that certain operations are only permitted in the context of a handler that handles a user-initiated event. The following is a list of such operations:

Setting IsFullScreen. Showing certain dialogs. This includes SaveFileDialog, OpenFileDialog, and the print dialog displayed by PrintDocument. Print. Navigating from a HyperlinkButton. Accessing the primary Clipboard API.

Silverlight user-initiated events include the mouse events (such as MouseLeftButtonDown), and the keyboard events (such as KeyDown). Events of controls that are based on such events (such as Click) are also considered user-initiated. API calls that require user initiation should be called as soon as possible in an event handler. This is because the Silverlight user initiation concept also requires that the calls occur within a certain time window after the event occurrence. In Silverlight 5, this time window is approximately one second.

User-initiated event restrictions also apply to usages of JavaScript API for Silverlight. When Silverlight is in full-screen mode, some input events are deliberately limited for security reasons, although this can be mitigated for out-of-browser applications using elevated trust. For more information, see Full-Screen Support.
Programming Model Alternatives

This topic specifically discusses Silverlight events and the managed API. But you could also use the JavaScript API for Silverlight to perform event handling for a XAML page. JavaScript API for Silverlight is appropriate for a limited range of scenarios such as splash screens or similar XAML-based UI that is visual in character but not especially interactive. You declare the event handling model (managed API versus JavaScript API) at the page level by including or excluding the x:Class attribute on the root element. If the x:Class attribute exists, the page uses the managed API. Including x:Class and using managed API is the default for most if not all XAML page templates produced by development tools for Silverlight. To use the JavaScript API for event handling, make sure the XAML page does not declare an x:Class attribute. For a description of the JavaScript API for event handling, see Handling Silverlight Events by Using JavaScript.
Removing Event Handlers

In some circumstances, you might want to remove event handlers during the application lifetime. To remove event handlers, you use the CLR-language-specific syntax. In C#, you use the -= operator. In Visual Basic, you use the RemoveHandler function. In either case, you reference the event handler method name The following code shows how to remove an event handler named textBlocks_MouseEnter from the target object textBlock1.
JavaScript C# C++ F#

JScript VB Copy to Clipboard


void Cleanup() { textBlock1.MouseEnter -= textBlocks_MouseEnter; }

You can also remove handlers for cases where the event was added through a XAML attribute. This is easier to do if you provided a Name value for the element where the handler was attached because that provides an object reference for code later; however, you could also walk the object tree in order to find the necessary object reference if you had to.

Commanding

In Silverlight 5, a small number of UI elements support commanding. Commanding uses inputrelated routed events in its underlying implementation and enables processing of related UI input (a certain mouse action, a specific accelerator key) by invoking a single command handler. If commanding is available for a UI element, consider using its commanding APIs instead of any discrete input events. For more information, see one of the following: ButtonBase. Command Hyperlink. Command

What's Next

If you are interested in defining your own events for your own controls or other types, see Defining Events for Custom Silverlight Classes. If you want to learn more about Silverlight input events specifically, see Mouse Support or Keyboard Support. Other types of input that involve events that were not discussed in this topic include ink, multi-touch, and mouse wheel events. See Ink Overview, Touch, or Mouse Wheel Input. If you are interested in learning more about the CLR event system concepts that apply to Silverlight, see Events, Delegates, and CLR Event System Conventions.

See Also

Walkthrough: Displaying Related Data in a WPF Application

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

In this walkthrough, you will create a WPF application that displays data from database tables that have a parent/child relationship. The data is encapsulated in entities in an Entity Data Model. The parent entity contains overview information for a set of orders. Each property of this entity is bound to a different control in the application. The child entity contains details for each order. This set of data is bound to a DataGrid control. This walkthrough illustrates the following tasks:

Creating a WPF application and an Entity Data Model that is generated from data in the AdventureWorksLT sample database. Creating a set of data-bound controls that display overview information for a set of orders. You create the controls by dragging a parent entity from the Data Sources window to the WPF Designer. Creating a DataGrid control that displays related details for each selected order. You create the controls by dragging a child entity from the Data Sources window to a window in the WPF designer.

Note Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more information, see Visual Studio Settings.

Prerequisites

You need the following components to complete this walkthrough:

Visual Studio. Access to a running instance of SQL Server or SQL Server Express that has the AdventureWorksLT sample database attached to it. You can download the AdventureWorksLT database from the CodePlex Web site.

Prior knowledge of the following concepts is also helpful, but not required to complete the walkthrough:

Entity Data Models and the ADO.NET Entity Framework. For more information, see Introducing the Entity Framework. Working with the WPF Designer. For more information, see WPF and Silverlight Designer Overview. WPF data binding. For more information, see Data Binding Overview.

Creating the Project

Create a new WPF project to display the order records. To create a new WPF project 1. Start Visual Studio. 2. On the File menu, point to New, and then click Project. 3. Expand Visual C# or Visual Basic, and then select Windows. 4. Make sure that .NET Framework 4 is selected in the combo box at the top of the dialog box. The DataGrid control that you use in this walkthrough is available only in the .NET Framework 4. 5. Select the WPF Application project template. 6. In the Name box, type AdventureWorksOrdersViewer. 7. Click OK. Visual Studio creates the AdventureWorksOrdersViewer project.

Creating an Entity Data Model for the Application

Before you can create data-bound controls, you must define a data model for your application and add it to the Data Sources window. In this walkthrough, the data model is an Entity Data Model. To create an Entity Data Model 1. On the Data menu, click Add New Data Source to open the Data Source Configuration Wizard. 2. On the Choose a Data Source Type page, click Database, and then click Next. 3. On the Choose a Database Model page, click Entity Data Model, and then click Next. 4. On the Choose Model Contents page, click Generate from database, and then click Next. 5. On the Choose Your Data Connection page, do one of the following:
o

If a data connection to the AdventureWorksLT sample database is available in the dropdown list, select it.

-oro

Click New Connection and create a connection to the AdventureWorksLT database.

Make sure that the Save entity connection settings in App.Config as option is selected, and then click Next. 6. On the Choose Your Database Objects page, expand Tables, and then select the following tables:
o o

SalesOrderDetail SalesOrderHeader

7. Click Finish. 8. Build the project.

Creating Data-Bound Controls that Display the Orders

Create controls that display order records by dragging the SalesOrderHeaders entity from the Data Sources window to the WPF designer. To create data-bound controls that display the order records 1. In Solution Explorer, double-click MainWindow.xaml. The window opens in the WPF designer.

2. Edit the XAML so the Height and Width properties are set to 800 3. In the Data Sources window, click the drop-down menu for the SalesOrderHeaders node and select Details. 4. Expand the SalesOrderHeaders node. 5. Click the drop-down menu next to SalesOrderID and select ComboBox. 6. For each of the following child nodes of the SalesOrderHeaders node, click the drop-down menu next the node and select None:
o o o o o o o o o o

RevisionNumber OnlineOrderFlag ShipToAddressID BillToAddressID CreditCardApprovalCode SubTotal TaxAmt Freight rowguid ModifiedDate

This action prevents Visual Studio from creating data-bound controls for these nodes in the next step. For this walkthrough, it is assumed that the end user does not need to see this data. 7. From the Data Sources window, drag the SalesOrderHeaders node to the window in the WPF Designer. Visual Studio generates XAML that creates a set of controls that are bound to data in the SalesOrderHeaders entity, and code that loads the data. For more information about the generated XAML and code, see Binding WPF Controls to Data in Visual Studio. 8. In the designer, click the combo box next to the Sales Order ID label. 9. In the Properties window, select the check box next to the IsReadOnly property.

Creating a DataGrid that Displays the Order Details

Create a DataGrid control that displays order details by dragging the SalesOrderDetails entity from the Data Sources window to the WPF designer. To create a DataGrid that displays the order details 1. In the Data Sources window, locate the SalesOrderDetails node that is a child of the SalesOrderHeaders node.

Note There is also a SalesOrderDetails node that is a peer of the SalesOrderHeaders node. Make sure that you select the child node of the SalesOrderHeaders node. 2. Expand the child SalesOrderDetails node. 3. For each of the following child nodes of the SalesOrderDetails node, click the drop-down menu next the node and select None:
o o o o

SalesOrderID SalesOrderDetailID rowguid ModifiedDate

This action prevents Visual Studio from including this data in the DataGrid control you create in the next step. For this walkthrough, it is assumed that the end user does not need to see this data. 4. From the Data Sources window, drag the child SalesOrderDetails node to the window in the WPF Designer. Visual Studio generates XAML to define a new data-bound DataGrid control, and the control appears in the designer. Visual Studio also updates the generated GetSalesOrderHeadersQuery method in the code-behind file to include the data in the SalesOrderDetails entity.

Testing the Application

Build and run the application to verify that it displays the order records. To test the application

1. Press F5. The application builds and runs. Verify the following:
o o

The Sales Order ID combo box displays 71774. This is the first order ID in the entity. For each order you select in the Sales Order ID combo box, detailed order information is displayed in the DataGrid.

2. Close the application.

After completing this walkthrough, learn how to use the Data Sources window in Visual Studio to bind WPF controls to other types of data sources. For more information, see Walkthrough: Binding WPF Controls to a WCF Data Service and Walkthrough: Binding WPF Controls to a Dataset.

How to: Display Related Data in WPF Applications

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

In some applications, you might want to work with data that comes from multiple tables or entities that are related to each other in a parent-child relationship. For example, you might want to display a grid that displays customers from a Customers table. When the user selects a specific customer, another grid displays the orders for that customer from a related Orders table. You can create data-bound controls that display related data by dragging items from the Data Sources window to the WPF Designer. To create controls that display related records 1. On the Data menu, click Show Data Sources to open the Data Sources window. 2. Click Add New Data Source and complete the Data Source Configuration Wizard. 3. Open the WPF designer, and make sure that the designer contains a container that is a valid drop target for the items in the Data Sources window. For more information about valid drop targets, see Binding WPF Controls to Data in Visual Studio. 4. In the Data Sources window, expand the node that represents the parent table or object in the relationship. The parent table or object is on the "one" side of a one-to-many relationship.

5. Drag the parent node (or any individual items in the parent node) from the Data Sources window onto a valid drop target in the designer. Visual Studio generates XAML that creates new data-bound controls for each item that you drag. The XAML also adds a new CollectionViewSource for the parent table or object to the resources of the drop target. For some data sources, Visual Studio also generates code to load the data into the parent table or object. For more information, see Binding WPF Controls to Data in Visual Studio. 6. In the Data Sources window, locate the related child table or object. Related child tables and objects appear as expandable nodes at the bottom of the parent node's list of data. 7. Drag the child node (or any individual items in the child node) from the Data Sources window onto a valid drop target in the designer. Visual Studio generates XAML that creates new data-bound controls for each of the items you drag. The XAML also adds a new CollectionViewSource for the child table or object to the resources of the drop target. This new CollectionViewSource is bound to the property of the parent table or object that you just dragged to the designer. For some data sources, Visual Studio also generates code to load the data into the child table or object. The following figure demonstrates the related Orders table of the Customers table in a dataset in the Data Sources window.

See Also

Tasks
How to: Bind WPF Controls to Data in Visual Studio How to: Create Lookup Tables in WPF Applications Walkthrough: Displaying Related Data in a WPF Application

Concepts
Binding WPF Controls to Data in Visual Studio How to: Bind WPF Controls to Data in Visual Studio

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

You can create data-bound WPF controls by using the Data Sources window. First, add a data source to the Data Sources window. Then, drag items from the Data Sources window to the WPF Designer.
Adding a Data Source to the Data Sources Window

Before you can create data-bound controls, you must first add a data source to the Data Sources window. To add a data source to the Data Sources window 1. On the Data menu, click Show Data Sources to open the Data Sources window. 2. Click Add New Data Source and complete the Data Source Configuration Wizard. 3. Perform one of the following tasks to create data-bound controls: o Creating a control that is bound to a single field of data. o Creating a control that is bound to multiple fields of data. o Creating a set of controls that are bound to multiple fields of data. o Binding data to existing controls in the designer.

Creating a Control That is Bound to a Single Field of Data

After you add a data source to the Data Sources window, you can create a new data-bound control that displays a single field of data, such as a ComboBox or TextBox. To create a control that is bound to a single field of data 1. In the Data Sources window, expand an item that represents a table or an object. Locate the child item that represents the column or property that you want to bind to. For a visual example, see Data Sources Window. 2. Optionally, select the control to create. Each item in the Data Sources window has a default control that is created when you drag the item to the designer. The default control depends on the underlying data type of the item. To choose a different control, click the drop-down arrow next to the item and select a control. For more information, see How to: Set the Control to be Created when Dragging from the Data Sources Window.

3. Drag the item to a valid container in the designer, such as a Grid. For more information about valid containers, see Binding WPF Controls to Data in Visual Studio. Visual Studio creates the new data-bound control and an appropriately titled Label in the container. Visual Studio also generates XAML and code to bind the control to the data. For more information, see Binding WPF Controls to Data in Visual Studio.
Creating a Control That is Bound to Multiple Fields of Data

After you add a data source to the Data Sources window, you can create a new data-bound control that displays multiple fields of data, such as a DataGrid or ListView. To create a control that is bound to multiple fields of data 1. In the Data Sources window, select an item that represents a table or object. For a visual example, see Data Sources Window. 2. Optionally, select the control to create. By default, each item in the Data Sources window that represents a data table or object is set to create a DataGrid (if your project targets .NET Framework 4) or ListView (for earlier versions of the .NET Framework). To select a different control, click the drop-down arrow next to the item and select a control. For more information, see How to: Set the Control to be Created when Dragging from the Data Sources Window.

Note

If you do not want to display a specific column or property, expand the item to display its children. Click the drop-down arrow next to the column or property that you do not want to display, and then click None. 3. Drag the item to a valid container in the designer, such as a Grid. For more information about valid containers, see Binding WPF Controls to Data in Visual Studio. Visual Studio creates the new data-bound control in the container. Visual Studio also generates XAML and code to bind the control to the data. For more information, see Binding WPF Controls to Data in Visual Studio.

Creating a Set of Controls That are Bound to Multiple Fields of Data

After you add a data source to the Data Sources window, you can bind a data table or object to a set of controls. A different control is created for each column or property in the table or object. To create a set of controls that are bound to multiple fields of data 1. In the Data Sources window, select an item that represents a table or object. For a visual example, see Data Sources Window. 2. Click the drop-down arrow next to the item and select Details.

Note

If you do not want to display a specific column or property, expand the item to display its children. Click the drop-down arrow next to the column or property that you do not want to display, and then click None. 3. Drag the item to a valid container in the designer, such as a Grid. For more information about valid containers, see Binding WPF Controls to Data in Visual Studio. Visual Studio creates the new data-bound controls in the container. Each control is bound to a different column or property, and each control is accompanied by an appropriately titled Label control. Visual Studio also generates XAML and code to bind the controls to the data. For more information, see Binding WPF Controls to Data in Visual Studio.

Binding Data to Existing Controls in the Designer

After you add a data source to the Data Sources window, you can add a data binding to an existing control in the desgner. To bind data to an existing control in the designer 1. In the Data Sources window, use one of the following procedures: o To add a data binding to an existing control that displays multiple fields of data, such as a DataGrid or ListView, select the item that represents the table or object that you want to bind to the control. o To add a data binding to an existing control that displays a single field of data, such as a ComboBox or TextBox, expand the item that represents the table or object that contains the data, and then select the item that represents the data that you want to bind to the control. 2. Drag the selected item from the Data Sources window onto an existing control in the designer. The control must be a valid drop target. For more information, see Binding WPF Controls to Data in Visual Studio.

Visual Studio generates XAML and code to bind the control to the data. For more information, see Binding WPF Controls to Data in Visual Studio.

Note

If the control is already bound to data, the data binding for the control is reset to the item that was dragged onto the control most recently.
See Also

Tasks
Walkthrough: Binding WPF Controls to an Entity Data Model

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

In this walkthrough, you will create a WPF application that contains data-bound controls. The controls are bound to customer records that are encapsulated in an Entity Data Model. You will also add buttons that customers can use to navigate through customer records and save changes to records. This walkthrough illustrates the following tasks:

Creating a WPF application and an Entity Data Model that is generated from data in the AdventureWorksLT sample database. Creating a set of data-bound controls by dragging an entity from the Data Sources window to a window in the WPF designer. Creating buttons that navigate forward and backward through customer records. Creating a button that saves changes in the controls to the Entity Data Model and the underlying data source.

Note

Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more information, see Visual Studio Settings.

Prerequisites

You need the following components to complete this walkthrough:


Visual Studio Access to a running instance of SQL Server or SQL Server Express that has the AdventureWorksLT sample database attached to it. You can download the AdventureWorksLT database from the CodePlex Web site.

Prior knowledge of the following concepts is also helpful, but not required to complete the walkthrough:

Entity Data Models and the ADO.NET Entity Framework. For more information, see Introducing the Entity Framework. Working with the WPF designer. For more information, see WPF and Silverlight Designer Overview. WPF data binding. For more information, see Data Binding Overview.
Creating the Project

Create a new WPF project to display the customer records. To create the project 1. 2. 3. 4. 5. Start Visual Studio. On the File menu, point to New, and then click Project. Expand Visual Basic or Visual C#, and then select Windows. Select the WPF Application project template. In the Name box, type AdventureWorksCustomerEditor and then click OK. Visual Studio creates the AdventureWorksCustomerEditor project.

Creating an Entity Data Model for the Application

Before you can create data-bound controls, you must define a data model for your application and add it to the Data Sources window. In this walkthrough, you create an Entity Data Model.

To create an Entity Data Model 1. On the Data menu, click Add New Data Source to open the Data Source Configuration Wizard. 2. On the Choose a Data Source Type page, click Database, and then click Next. 3. On the Choose a Database Model page, click Entity Data Model, and then click Next. 4. On the Choose Model Contents page, click Generate from database, and then click Next. 5. On the Choose Your Data Connection page, do one of the following: o If a data connection to the AdventureWorksLT sample database is available in the drop-down list, select it. -oro

Click New Connection and create a connection to the AdventureWorksLT database.

Make sure that the Save entity connection settings in App.Config as option is selected, and then click Next. 6. On the Choose Your Database Objects page, expand Tables, and then select the Customer table. 7. Click Finish. The Model1.edmx file opens in the designer. 8. Build the project.

Defining the User Interface of the Window

Add buttons to the window by modifying the XAML in the WPF Designer. To define the user interface of the window 1. In Solution Explorer, double-click MainWindow.xaml. The window opens in the WPF Designer. 2. In the XAML view of the designer, add the following code between the <Grid> tags:
Copy to Clipboard
<Grid.RowDefinitions> <RowDefinition Height="75" />

<RowDefinition Height="425" /> </Grid.RowDefinitions> <Button HorizontalAlignment="Left" Margin="22,20,0,24" Name="backButton" Width="75">&lt;</Button> <Button HorizontalAlignment="Left" Margin="116,20,0,24" Name="nextButton" Width="75">&gt;</Button> <Button HorizontalAlignment="Right" Margin="0,21,46,24" Name="saveButton" Width="110">Save changes</Button>

3.

Build the project.

Creating Data-Bound Controls

Create controls that display customer records by dragging objects from the Data Sources window to the WPF Designer. To create data-bound controls 1. On the Data menu, click Show Data Sources. 2. In the Data Sources window, click the drop-down menu for the Customers node and select Details. 3. Expand the Customers node. 4. For this example some fields will not be displayed so click the drop-down menu next to the following nodes and select None: o NameStyle o PasswordHash o PasswordSalt o rowGuid o ModifiedDate 5. From the Data Sources window, drag the Customers node to the area under the buttons. 6. In the designer, click the text box next to the Customer ID label. 7. In the Properties window, select the check box next to the IsReadOnly property. 8. Build the project.

Navigating Customer Records

Add code that enables users to scroll through customer records by using the < and > buttons.

To enable users to navigate customer records 1. In the designer, double-click the < button. Visual Studio opens the code-behind file and creates a new backButton_Click event handler for the Click event. 2. Modify the Window_Loaded event handler so the CustomersViewSource and AdventureWorksLTEntities are outside of the method and accessible to the entire form. Only declare these global to the form, assign them within the Window_Loaded event handler similar to the following:
JavaScript C# C++ F# JScript VB Copy to Clipboard
private System.Windows.Data.CollectionViewSource customersViewSource; private AdventureWorksCustomerEditor.AdventureWorksLTEntities adventureWorksLTEntities; private void Window_Loaded(object sender, RoutedEventArgs e) { adventureWorksLTEntities = new AdventureWorksCustomerEditor.AdventureWorksLTEntities(); // Load data into Customers. You can modify this code as needed. customersViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("customer sViewSource"))); System.Data.Objects.ObjectQuery<AdventureWorksCustomerEditor.Customer> customersQuery = this.GetCustomersQuery(adventureWorksLTEntities); customersViewSource.Source = customersQuery.Execute(System.Data.Objects.MergeOption.AppendOnly); }

3.

Add the following code to the backButton_Click event handler:

JavaScript C# C++ F# JScript VB Copy to Clipboard


if (customersViewSource.View.CurrentPosition > 0) customersViewSource.View.MoveCurrentToPrevious();

4.

Return to the designer, and double-click the > button. Visual Studio opens the code-behind file and creates a new nextButton_Click event handler for the Click event. 5. Add the following code to the nextButton _Click event handler:
JavaScript C# C++ F# JScript VB Copy to Clipboard
if (customersViewSource.View.CurrentPosition < ((CollectionView)customersViewSource.View).Count - 1) customersViewSource.View.MoveCurrentToNext();

Checkpoint

Build and run your project to make sure that the code compiles, and that you can navigate customer records. To test the application

Press F5. The application builds and runs. Verify the following:
o o

Customer data is displayed. You can click the > or < buttons to navigate customer records.

Saving Changes to Customer Records

Add code that enables users to save changes to customer records by using the Save changes button. To add the ability to save changes to customer records 1. In the designer, double-click the Save changes button. Visual Studio opens the code-behind file and creates a new saveButton_Click event handler. 2. Add the following code to the saveButton_Click event handler:
JavaScript C# C++ F# JScript VB Copy to Clipboard

adventureWorksLTEntities.SaveChanges();

Testing the Application

Build and run the application to verify that it displays the customer records and enables you to save changes to them. To test the application 1. 2. 3. 4. 5. Press F5. Edit one of the customer records and then click Save changes. Close the application, and then start the application again by pressing F5. Navigate to the customer record you changed, and verify that the change has persisted. Close the application.

Next Steps

After completing this walkthrough, you can perform the following related tasks:

Learn how to use the Data Sources window in Visual Studio to bind WPF controls to other types of data sources. For more information, see Walkthrough: Binding WPF Controls to a WCF Data Service and Walkthrough: Binding WPF Controls to a Dataset. Learn how to use the Data Sources window in Visual Studio to display related data (that is, data in a parent-child relationship) in WPF controls. For more information, see Walkthrough: Displaying Related Data in a WPF Application.

See Also

Walkthrough: Binding WPF Controls to a WCF Data Service

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

In this walkthrough, you will create a WPF application that contains data-bound controls. The controls are bound to customer records that are encapsulated in a WCF Data Service. You will also add buttons that customers can use to view and update records. This walkthrough illustrates the following tasks:

Creating an Entity Data Model that is generated from data in the AdventureWorksLT sample database. Creating a WCF Data Service that exposes the data in the Entity Data Model to a WPF application. Creating a set of data-bound controls by dragging items from the Data Sources window to the WPF designer. Creating buttons that navigate forward and backward through customer records. Creating a button that saves changes to data in the controls to the WCF Data Service and the underlying data source.

Note

Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more information, see Visual Studio Settings.
Prerequisites

You need the following components to complete this walkthrough:


Visual Studio Access to a running instance of SQL Server or SQL Server Express that has the AdventureWorksLT sample database attached to it. You can download the AdventureWorksLT database from the CodePlex Web site.

Prior knowledge of the following concepts is also helpful, but not required to complete the walkthrough:

WCF Data Services. For more information, see ADO.NET Data Services Framework Overview. Data models in WCF Data Services. Entity Data Models and the ADO.NET Entity Framework. For more information, see Introducing the Entity Framework. Working with the WPF designer. For more information, see WPF and Silverlight Designer Overview.

WPF data binding. For more information, see Data Binding Overview.

Creating the Service Project

Start this walkthrough by creating a project for a WCF Data Service. To create the service project 1. 2. 3. 4. 5. Start Visual Studio. On the File menu, point to New, and then click Project. Expand Visual C# or Visual Basic, and then select Web. Select the ASP.NET Web Application project template. In the Name box, type AdventureWorksService and click OK. Visual Studio creates the AdventureWorksService project. 6. In Solution Explorer, right-click Default.aspx and select Delete. This file is not necessary in this walkthrough.

Creating an Entity Data Model for the Service

To expose data to an application by using a WCF Data Service, you must define a data model for the service. The WCF Data Service supports two types of data models: Entity Data Models and custom data models that are defined by using common language runtime (CLR) objects that implement the IQueryable< T> interface. In this walkthrough, you create an Entity Data Model for the data model. To create an Entity Data Model 1. On the Project menu, click Add New Item. 2. In the Installed Templates list, click Data, and then select the ADO.NET Entity Data Model project item. 3. Change the name to AdventureWorksModel.edmx, and click Add. The Entity Data Model Wizard opens. 4. On the Choose Model Contents page, click Generate from database, and click Next. 5. On the Choose Your Data Connection page, select one of the following options: o If a data connection to the AdventureWorksLT sample database is available in the drop-down list, select it.

-orClick New Connection and create a connection to the AdventureWorksLT database. 6. On the Choose Your Data Connection page, make sure that the Save entity connection settings in App.Config as option is selected and then click Next. 7. On the Choose Your Database Objects page, expand Tables, and then select the SalesOrderHeader table. 8. Click Finish.
Creating the Service
o

Create a WCF Data Service to expose the data in the Entity Data Model to a WPF application. To create the service 1. On the Project menu, select Add New Item. 2. In the Installed Templates list, click Web, and then select the WCF Data Service project item. 3. In the Name box, type AdventureWorksService.svc and click Add. Visual Studio adds the AdventureWorksService.svc to the project.

Configuring the Service

You must configure the service to operate on the Entity Data Model that you created. To configure the service 1. In the AdventureWorks.svc code file, replace the AdventureWorksService class declaration with the following code.
JavaScript C# C++ F#

JScript VB Copy to Clipboard


public class AdventureWorksService : DataService<AdventureWorksLTEntities> { // This method is called only once to initialize service-wide policies. public static void InitializeService(IDataServiceConfiguration config) { config.SetEntitySetAccessRule("SalesOrderHeaders", EntitySetRights.All); } }

This code updates the AdventureWorksService class so that it derives from a DataService< T> that operates on theAdventureWorksLTEntities object context class in your Entity Data Model. It also updates the InitializeService method to allow clients of the service full read/write access to the SalesOrderHeader entity. 2. Build the project, and verify that it builds without errors.

Creating the WPF Client Application

To display the data from the WCF Data Service, create a new WPF application with a data source that is based on the service. Later in this walkthrough, you will add data-bound controls to the application. To create the WPF client application 1. 2. 3. 4. In Solution Explorer, right-click the solution node, click Add, and select New Project. In the New Project dialog, expand Visual C# or Visual Basic, and then select Windows. Select the WPF Application project template. In the Name box, type AdventureWorksSalesEditor and click OK. Visual Studio adds the AdventureWorksSalesEditor project to the solution. 5. On the Data menu, click Show Data Sources. The Data Sources window opens.

6. In the Data Sources window, click Add New Data Source. The Data Source Configuration Wizard opens. 7. In the Choose a Data Source Type page of the wizard, select Service and then click Next. 8. In the Add Service Reference dialog box, click Discover. Visual Studio searches the current solution for available services, and adds AdventureWorksService.svc to the list of available services in the Services box. 9. In the Namespace box, type AdventureWorksService. 10. In the Services box, click AdventureWorksService.svc and then click OK. Visual Studio downloads the service information and then returns to the Data Source Configuration Wizard. 11. In the Add Service Reference page, click Finish. Visual Studio adds nodes that represent the data returned by the service to the Data Sources window.
Defining the User Interface of the Window

Add several buttons to the window by modifying the XAML in the WPF designer. Later in this walkthrough, you will add code that enables users to view and update sales records by using these buttons. To create the window layout 1. In Solution Explorer, double-click MainWindow.xaml. The window opens in the WPF designer. 2. In the XAML view of the designer, add the following code between the <Grid> tags:
Copy to Clipboard
<Grid.RowDefinitions> <RowDefinition Height="75" /> <RowDefinition Height="525" /> </Grid.RowDefinitions> <Button HorizontalAlignment="Left" Margin="22,20,0,24" Name="backButton" Width="75">&lt;</Button>

<Button HorizontalAlignment="Left" Margin="116,20,0,24" Name="nextButton" Width="75">&gt;</Button> <Button HorizontalAlignment="Right" Margin="0,21,46,24" Name="saveButton" Width="110">Save changes</Button>

3.

Build the project.


Creating the Data-bound Controls

Create controls that display customer records by dragging the SalesOrderHeaders node from the Data Sources window to the designer. To create the data-bound controls 1. In the Data Sources window, click the drop-down menu for the SalesOrderHeaders node and select Details. 2. Expand the SalesOrderHeaders node. 3. For this example some fields will not be displayed so click the drop-down menu next to the following nodes and select None: o CreditCardApprovalCode o ModifiedDate o OnlineOrderFlag o RevisionNumber o rowguid This action prevents Visual Studio from creating data-bound controls for these nodes in the next step. For this walkthrough, it is assumed that the end user does not need to see this data. 4. From the Data Sources window, drag the SalesOrderHeaders node to the grid row under the row that contains the buttons. Visual Studio generates XAML and code that creates a set of controls that are bound to data in the Product table. For more information about the generated XAML and code, see Binding WPF Controls to Data in Visual Studio. 5. In the designer, click the text box next to the Customer ID label. 6. In the Properties window, select the check box next to the IsReadOnly property. 7. Set the IsReadOnly property for each of the following text boxes: o Purchase Order Number o Sales Order ID o Sales Order Number

Load the Data from the Service

Use the service proxy object to load sales data from the service, and then assign the returned data to the data source for the CollectionViewSource in the WPF window. To load the data from the service 1. In the designer, double-click the text that reads: MainWindow to create the Window_Loaded event handler. 2. Replace the event handler with the following code. Make sure that you replace the localhost address in this code with the local host address on your development computer.
JavaScript C# C++ F# JScript VB Copy to Clipboard
private AdventureWorksService.AdventureWorksLTEntities dataServiceClient; private System.Data.Services.Client.DataServiceQuery<AdventureWorksService.Sale sOrderHeader> salesQuery; private CollectionViewSource ordersViewSource; private void Window_Loaded(object sender, RoutedEventArgs e) { // TODO: Modify the port number in the following URI as required. dataServiceClient = new AdventureWorksService.AdventureWorksLTEntities( new Uri("http://localhost:45899/AdventureWorksService.svc")); salesQuery = dataServiceClient.SalesOrderHeaders; ordersViewSource = ((CollectionViewSource)(this.FindResource("salesOrderHeadersViewSource" ))); ordersViewSource.Source = salesQuery.Execute(); ordersViewSource.View.MoveCurrentToFirst();

Navigating Sales Records

Add code that enables users to scroll through sales records by using the < and > buttons. To enable users to navigate sales records 1. In the designer, double-click the < button on the window surface. Visual Studio opens the code-behind file and creates a new backButton_Click event handler for the Click event. 2. Add the following code to the generated backButton_Click event handler:
JavaScript C# C++ F# JScript VB Copy to Clipboard
if (ordersViewSource.View.CurrentPosition > 0) ordersViewSource.View.MoveCurrentToPrevious();

3.

Return to the designer, and double-click the > button. Visual Studio opens the code-behind file and creates a new nextButton_Click event handler for the Click event. 4. Add the following code to the generated nextButton_Click event handler:
JavaScript C#

C++ F# JScript VB Copy to Clipboard


if (ordersViewSource.View.CurrentPosition < ((CollectionView)ordersViewSource.View).Count - 1) { ordersViewSource.View.MoveCurrentToNext(); }

Saving Changes to Sales Records

Add code that enables users to both view and save changes to sales records by using the Save changes button. To add the ability to save changes to sales records 1. In the designer, double-click the Save Changes button. Visual Studio opens the code-behind file and creates a new saveButton_Click event handler for the Click event. 2. Add the following code to the saveButton_Click event handler.
JavaScript C# C++ F# JScript VB Copy to Clipboard

AdventureWorksService.SalesOrderHeader currentOrder = (AdventureWorksService.SalesOrderHeader)ordersViewSource.View.CurrentIt em; dataServiceClient.UpdateObject(currentOrder); dataServiceClient.SaveChanges();

Testing the Application

Build and run the application to verify that you can view and update customer records. To test the application 1. On Build menu, click Build Solution. Verify that the solution builds without errors. 2. Press CTRL+F5. Visual Studio starts the AdventureWorksService project without debugging it. 3. In Solution Explorer, right-click the AdventureWorksSalesEditor project. 4. On the context menu, under Debug, click Start new instance. The application runs. Verify the following: The text boxes display different fields of data from the first sales record, which has the sales order ID 71774. o You can click the > or < buttons to navigate through other sales records. In one of the sales records, type some text in the Comment box, and then click Save changes. Close the application, and then start the application again from Visual Studio. Navigate to the sales record that you changed, and verify that the change persists after you close and reopen the application. Close the application.
o

5. 6. 7. 8.

Next Steps

After completing this walkthrough, you can perform the following related tasks:

Learn how to use the Data Sources window in Visual Studio to bind WPF controls to other types of data sources. For more information, see Walkthrough: Binding WPF Controls to an Entity Data Model and Walkthrough: Binding WPF Controls to a Dataset. Learn how to use the Data Sources window in Visual Studio to display related data (that is, data in a parent-child relationship) in WPF controls. For more information, see Walkthrough: Displaying Related Data in a WPF Application.

See Also

How to: Create Lookup Tables in WPF Applications

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

You can create a lookup table by dragging the main node of a parent table or object in the Data Sources window onto a control that is already bound to a column or property in a related child table. The term lookup table (sometimes called a lookup binding) describes a control that displays information from one data table based on the value of a foreign-key field in another table. For example, consider a table of Orders in a sales database. Each record in the Orders table includes a CustomerID that indicates which customer placed the order. The CustomerID is a foreign key that points to a customer record in the Customers table. When you display a list of orders from the Orders table, you may want to display the actual customer name instead of the CustomerID. Because the customer name is in the Customers table, you need to create a lookup table to display the customer name. The lookup table uses the CustomerID value in the Orders record to navigate the relationship and return the user-friendly customer name. To create a lookup table 1. Add one of the following types of data sources with related data to your project: o Dataset or Entity Data Model. For more information, see How to: Connect to Data in a Database. o WCF Data Service, WCF service or Web service. For more information, see How to: Connect to Data in a Service. o Objects. For more information, see How to: Connect to Data in Objects.

Note

Before you can create a lookup table, two related tables or objects must exist as a data source for the project. 2. Open the WPF Designer and make sure that the designer contains a container that is a valid drop target for items in the Data Sources window. For more information about valid drop targets, see Binding WPF Controls to Data in Visual Studio.

3. On the Data menu, click Show Data Sources to open the Data Sources window. 4. Expand the nodes in the Data Sources window until you can see the parent table or object and the related child table or object.

Note

The related child table or object is the node that appears as an expandable child node under the parent table or object. 5. Click the drop-down menu for the child node and select Details. 6. Expand the child node. 7. Under the child node, click the drop-down menu for the item that relates the child and parent data (in the example given above, this would be the CustomerID node). Select one of the following types of controls that support lookup binding: o ComboBox o ListBox o ListView

Note

If the ListBox or ListView control does not appear in the list, you can add these controls to the list. For information, see How to: Set the Control to be Created when Dragging from the Data Sources Window.
o

Any custom control that derives from Selector.

Note

For information about how to add custom controls to the list of controls you can select for items in the Data Sources window, see How to: Add Custom Controls to the Data Sources Window. 8. Drag the child node from the Data Sources window onto a container in the WPF designer (in the example given above, the child node would be the Orders node). Visual Studio generates XAML that creates new data-bound controls for each of the items that you drag. The XAML also adds a new CollectionViewSource for the child table or object to the resources of the drop target. For some data sources, Visual Studio also generates code to load data into the table or object. For more information, see Binding WPF Controls to Data in Visual Studio.

9. Drag the parent node from the Data Sources window onto the lookup binding control that you created earlier (in the example given above, the parent node would be the Customers node). Visual Studio sets some properties on the control to configure the lookup binding. The following table lists the properties that Visual Studio modifies. If necessary, you can change these properties in the XAML or in the Properties window. Explanation of setting This property specifies the collection or binding that is used to get the data that is displayed in the control. Visual Studio sets this ItemsSource property to the CollectionViewSource for the parent data you dragged to the control. This property specifies the path of the data item that is displayed in the control. Visual Studio sets this property to the first column or property in the parent data, after the primary key, that has a string DisplayMemberPath data type. If you want to display a different column or property in the parent data, change this property to the path of a different property. Visual Studio binds this property to the column or property of the SelectedValue child data that you dragged to the designer. This is the foreign key to the parent data. Visual Studio sets this property to the path of the column or SelectedValuePath property of the child data that is the foreign key to the parent data. Property

: Displaying Related Data in a WPF Application

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

In this walkthrough, you will create a WPF application that displays data from database tables that have a parent/child relationship. The data is encapsulated in entities in an Entity Data Model. The parent entity contains overview information for a set of orders. Each property of this entity is bound to a different control in the application. The child entity contains details for each order. This set of data is bound to a DataGrid control. This walkthrough illustrates the following tasks:

Creating a WPF application and an Entity Data Model that is generated from data in the AdventureWorksLT sample database.

Creating a set of data-bound controls that display overview information for a set of orders. You create the controls by dragging a parent entity from the Data Sources window to the WPF Designer. Creating a DataGrid control that displays related details for each selected order. You create the controls by dragging a child entity from the Data Sources window to a window in the WPF designer.

Note

Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more information, see Visual Studio Settings.
Prerequisites

You need the following components to complete this walkthrough:


Visual Studio. Access to a running instance of SQL Server or SQL Server Express that has the AdventureWorksLT sample database attached to it. You can download the AdventureWorksLT database from the CodePlex Web site.

Prior knowledge of the following concepts is also helpful, but not required to complete the walkthrough:

Entity Data Models and the ADO.NET Entity Framework. For more information, see Introducing the Entity Framework. Working with the WPF Designer. For more information, see WPF and Silverlight Designer Overview. WPF data binding. For more information, see Data Binding Overview.

Creating the Project

Create a new WPF project to display the order records. To create a new WPF project 1. Start Visual Studio.

2. On the File menu, point to New, and then click Project. 3. Expand Visual C# or Visual Basic, and then select Windows. 4. Make sure that .NET Framework 4 is selected in the combo box at the top of the dialog box. The DataGrid control that you use in this walkthrough is available only in the .NET Framework 4. 5. Select the WPF Application project template. 6. In the Name box, type AdventureWorksOrdersViewer. 7. Click OK. Visual Studio creates the AdventureWorksOrdersViewer project.
Creating an Entity Data Model for the Application

Before you can create data-bound controls, you must define a data model for your application and add it to the Data Sources window. In this walkthrough, the data model is an Entity Data Model. To create an Entity Data Model 1. On the Data menu, click Add New Data Source to open the Data Source Configuration Wizard. 2. On the Choose a Data Source Type page, click Database, and then click Next. 3. On the Choose a Database Model page, click Entity Data Model, and then click Next. 4. On the Choose Model Contents page, click Generate from database, and then click Next. 5. On the Choose Your Data Connection page, do one of the following: o If a data connection to the AdventureWorksLT sample database is available in the drop-down list, select it. -oro

Click New Connection and create a connection to the AdventureWorksLT database.

Make sure that the Save entity connection settings in App.Config as option is selected, and then click Next. 6. On the Choose Your Database Objects page, expand Tables, and then select the following tables: o SalesOrderDetail o SalesOrderHeader 7. Click Finish. 8. Build the project.

Creating Data-Bound Controls that Display the Orders

Create controls that display order records by dragging the SalesOrderHeaders entity from the Data Sources window to the WPF designer. To create data-bound controls that display the order records 1. In Solution Explorer, double-click MainWindow.xaml. The window opens in the WPF designer. 2. Edit the XAML so the Height and Width properties are set to 800 3. In the Data Sources window, click the drop-down menu for the SalesOrderHeaders node and select Details. 4. Expand the SalesOrderHeaders node. 5. Click the drop-down menu next to SalesOrderID and select ComboBox. 6. For each of the following child nodes of the SalesOrderHeaders node, click the dropdown menu next the node and select None: o RevisionNumber o OnlineOrderFlag o ShipToAddressID o BillToAddressID o CreditCardApprovalCode o SubTotal o TaxAmt o Freight o rowguid o ModifiedDate This action prevents Visual Studio from creating data-bound controls for these nodes in the next step. For this walkthrough, it is assumed that the end user does not need to see this data. 7. From the Data Sources window, drag the SalesOrderHeaders node to the window in the WPF Designer. Visual Studio generates XAML that creates a set of controls that are bound to data in the SalesOrderHeaders entity, and code that loads the data. For more information about the generated XAML and code, see Binding WPF Controls to Data in Visual Studio. 8. In the designer, click the combo box next to the Sales Order ID label. 9. In the Properties window, select the check box next to the IsReadOnly property.

Creating a DataGrid that Displays the Order Details

Create a DataGrid control that displays order details by dragging the SalesOrderDetails entity from the Data Sources window to the WPF designer. To create a DataGrid that displays the order details 1. In the Data Sources window, locate the SalesOrderDetails node that is a child of the SalesOrderHeaders node.

Note

There is also a SalesOrderDetails node that is a peer of the SalesOrderHeaders node. Make sure that you select the child node of the SalesOrderHeaders node. 2. Expand the child SalesOrderDetails node. 3. For each of the following child nodes of the SalesOrderDetails node, click the drop-down menu next the node and select None: o SalesOrderID o SalesOrderDetailID o rowguid o ModifiedDate This action prevents Visual Studio from including this data in the DataGrid control you create in the next step. For this walkthrough, it is assumed that the end user does not need to see this data. 4. From the Data Sources window, drag the child SalesOrderDetails node to the window in the WPF Designer. Visual Studio generates XAML to define a new data-bound DataGrid control, and the control appears in the designer. Visual Studio also updates the generated GetSalesOrderHeadersQuery method in the code-behind file to include the data in the SalesOrderDetails entity.
Testing the Application

Build and run the application to verify that it displays the order records.

To test the application 1. Press F5. The application builds and runs. Verify the following: The Sales Order ID combo box displays 71774. This is the first order ID in the entity. o For each order you select in the Sales Order ID combo box, detailed order information is displayed in the DataGrid. 2. Close the application.
Next Steps
o

After completing this walkthrough, learn how to use the Data Sources window in Visual Studio to bind WPF controls to other types of data sources. For more information, see Walkthrough: Binding WPF Controls to a WCF Data Service and Walkthrough: Binding WPF Controls to a Dataset.

See Also

Tasks
How to: Display Related Data in WPF Applications

Concepts
Binding WPF Controls to Data in Visual Studio

Customizing the Appearance of an Existing Control by Using a ControlTemplate Send Feedback on this topic to Microsoft. View this topic online in your default browser.

A ControlTemplate specifies the visual structure and visual behavior of a control. You can customize the appearance of a control by giving it a new ControlTemplate. When you create a ControlTemplate, you replace the appearance of an existing control without changing its functionality. For example, you can make the buttons in your application round rather than the default square shape, but the button will still raise the Click event.

This topic explains the various parts of a ControlTemplate, demonstrates creating a simple ControlTemplate for a Button, and explains how to understand the control contract of a control so you can customize its appearance. Because you create a ControlTemplate in XAML, you can change a control's appearance without writing any code. The examples in this topic show the XAML that is used to customize the appearance of a Button. For the complete example discussed in this topic, see Walkthrough: Customizing the Appearance of a Button by Using a ControlTemplate. You can also use a designer such as Microsoft Expression Blend 2 Service Pack 1 to accomplish the same thing. For more information about using Expression Blend 2 SP1, see Create a Reusable Template for a System Control.

Click the following link to see the ControlTemplate example that is used in this topic. Run this sample This topic contains the following sections.

Prerequisites When You Should Create a ControlTemplate How to Define the ControlTemplate in XAML Changing the Visual Structure of a Control Changing the Appearance of a Control Depending on Its State Specifying the Behavior of a Control When It Transitions Between States Customizing Other Controls by Understanding the Control Contract Related Topics Prerequisites

This topic assumes that you understand creating and using controls and styles as discussed in Getting Started with Controls and the basics of control customization as explained in Control Customization.

Note: The concepts discussed in this topic apply to elements that inherit from the Control class, except for the UserControl. You cannot apply a ControlTemplate to a UserControl. When You Should Create a ControlTemplate

Controls have many properties, such as Background, Foreground, and FontFamily, that you can set to specify different aspects of the control's appearance, but the changes that you can make by

setting these properties are limited. For example, you can set the Foreground property to blue and FontStyle to italic on a CheckBox. Without the ability to create a new ControlTemplate for controls, all controls in every Silverlight-based application would have the same general appearance, which would limit the ability to create an application with a custom look and feel. By default, every CheckBox has similar characteristics. For example, the content of the CheckBox is always to the right of the selection indicator, and the check mark is always used to indicate that the CheckBox is selected. You create a ControlTemplate when you want to customize the control's appearance beyond what setting the other properties on the control will do. In the example of the CheckBox, suppose that you want the content of the check box to be above the selection indicator and an X to indicate that the CheckBox is selected. You specify this is the ControlTemplate of the CheckBox. Click the following link to see a CheckBox that uses a default ControlTemplate and CheckBox that uses a custom ControlTemplate to place the content of the CheckBox above the selection indicator and display an X when the CheckBox is selected. Run this sample The ControlTemplate for the CheckBox in this sample is relatively complex, so this topic uses a simpler example of creating a ControlTemplate for a Button. How to Define the ControlTemplate in XAML

The Template property specifies the ControlTemplate of a control. Like many properties, the Template property can be set in the following ways:

Locally set Template to a ControlTemplate that is defined inline. Locally set Template to a reference to a ControlTemplate that is defined as a resource. Set Template and define a ControlTemplate in a Style.

The following example demonstrates setting the Template property locally and defining the ControlTemplate inline. XAML Copy to Clipboard
<Button Content="Button1"> <Button.Template> <ControlTemplate TargetType="Button"> <!--Define the ControlTemplate here.--> </ControlTemplate>

</Button.Template> </Button>

The following example demonstrates defining the ControlTemplate as a resource and setting the Template to a reference to the resource. XAML Copy to Clipboard
<StackPanel> <StackPanel.Resources> <ControlTemplate TargetType="Button" x:Key="newTemplate"> <!--Define the ControlTemplate here.--> </ControlTemplate> </StackPanel.Resources> <Button Template="{StaticResource newTemplate}" Content="Button1"/> </StackPanel>

The following example demonstrates setting the Template property and defining the ControlTemplate in a Style. XAML Copy to Clipboard
<StackPanel> <StackPanel.Resources> <Style TargetType="Button" x:Key="newTemplate"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <!--Define the ControlTemplate here.--> </ControlTemplate> </Setter.Value> </Setter> </Style> </StackPanel.Resources> <Button Style="{StaticResource newTemplate}" Content="Button1"/> </StackPanel>

Although all three of these methods are valid ways to define a ControlTemplate, it is probably most common to see the Template property set in a Style. When you see a ControlTemplate is set in a Style, realize that the style just sets the Template property, just as it does for any other property. Changing the Visual Structure of a Control

In Silverlight, a control is often a composite FrameworkElement objects. When you create a ControlTemplate, you combine FrameworkElement objects to build a single control. A ControlTemplate must have only one FrameworkElement as its root element. The root element usually contains other FrameworkElement objects. The combination of objects is makes up the control's visual structure. The following example creates a custom ControlTemplate for the Button. The ControlTemplate creates the visual structure of the Button. This example does not change the button's appearance when you point to it or click it. Changing the button's appearance when it is in a different state is discussed later in this topic. In this example, the visual structure is made up of the following parts:

A Border called RootElement that serves as the template's root FrameworkElement. A Grid that is a child of RootElement. A ContentPresenter that displays the button's content. The ContentPresenter enables any type of object to be displayed.

XAML Copy to Clipboard


<ControlTemplate TargetType="Button"> <Border x:Name="RootElement"> <!--Create the SolidColorBrush for the Background as an object elemment and give it a name so it can be referred to elsewhere in the control template.--> <Border.Background> <SolidColorBrush x:Name="BorderBrush" Color="Black"/> </Border.Background> <!--Create a border that has a different color by adding smaller grid. The background of this grid is specificied by the button's Background property.--> <Grid Margin="4" Background="{TemplateBinding Background}"> <!--Use a ContentPresenter to display the Content of the Button.--> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4" /> </Grid> </Border> </ControlTemplate>

Preserving the Functionality of a Control's Properties by Using TemplateBinding


When you create a new ControlTemplate, you still might want to use the public properties to change the control's appearance. The TemplateBinding markup extension binds a property of an element that is in the ControlTemplate to a public property that is defined by the control. The preceding example uses the TemplateBinding markup extension to bind properties of elements that are in the ControlTemplate to public properties that are defined by the button. For example, the Border has its Background property set to {TemplateBinding Background}. Because Background is template bound, you can create multiple buttons that use the same ControlTemplate and set the Background to different values on each button. If Background was not template bound in the ControlTemplate, setting the Background of a button would have no impact on the button's appearance. The Control class defines several properties that can be used by the control template to have an effect on the control when they are set. How the ControlTemplate uses the property depends on the property. The ControlTemplate must use the property in one of the following ways:

An element in the ControlTemplate template binds to the property. An element in the ControlTemplate inherits the property from a parent FrameworkElement.

The following table lists the visual properties inherited by a control from the Control class. It also indicates whether the default control template of a control uses the inherited property value or if it is template bound. Property Usage method Background Template binding BorderThickness Template binding BorderBrush Template binding FontFamily Property inheritance or template binding FontSize Property inheritance or template binding FontStretch Property inheritance or template binding FontWeight Property inheritance or template binding Foreground Property inheritance or template binding HorizontalContentAlignment Template binding Padding Template binding VerticalContentAlignment Template binding The table above lists only the visual properties inherited from the Control class. Apart from the properties listed above, a control may also inherit the DataContext, Language, and TextDecorations properties from the parent framework element. Also, if the ContentPresenter is in the ControlTemplate of a ContentControl, the ContentPresenter will automatically bind to the ContentTemplate and Content properties.

Likewise, an ItemsPresenter that is in the ControlTemplate of an ItemsControl will automatically bind to the Items and ItemsPresenter properties. The following example creates two buttons that use the ControlTemplate defined in the preceding example. The example sets the Background, Foreground, and FontSize properties on each button. Setting the Background property has an effect because it is template bound in the ControlTemplate. Even though the Foreground and FontSize properties are not template bound, setting them has an effect because their values are inherited. Run this sample XAML Copy to Clipboard
<StackPanel> <Button Style="{StaticResource newTemplate}" Background="Navy" Foreground="White" FontSize="14" Content="Button1"/> <Button Style="{StaticResource newTemplate}" Background="Purple" Foreground="White" FontSize="14" Content="Button2" Click="Button_Click"/> </StackPanel>

Changing the Appearance of a Control Depending on Its State

The difference between a button with its default appearance and the button in the preceding example is that the default button subtly changes when it is in different states. For example, the default button's appearance changes when the button is pressed, or when the mouse pointer is over the button. Although the ControlTemplate does not change the functionality of a control, it does change the control's visual behavior. A visual behavior describes the control appearance when it is in a certain state. To understand the difference between the functionality and visual behavior of a control, consider the button example. The button's functionality is to raise the Click event when it is clicked, but the button's visual behavior is to change its appearance when it is pointed to or pressed. You use VisualState objects to specify the appearance of a control when it is in a certain state. A VisualState contains a Storyboard that changes the appearance of the elements that are in the ControlTemplate. You do not have to write any code to make this occur because the control's logic changes state by using the VisualStateManager. When the control enters the state that is specified by the VisualState. Name property, the storyboard begins. When the control exits the state, the Storyboard stops. The following example shows the VisualState that changes the appearance of a Button when the mouse pointer is over it. The Name of the VisualState matches the name specified by the TemplateVisualStateAttribute on the Button class. The Storyboard changes the button's border color by changing the color of the BorderBrush. If you refer to the ControlTemplate example at

the beginning of this topic, you will recall that BorderBrush is the name of the SolidColorBrush that is assigned to the Background of the Border. XAML Copy to Clipboard
<!--Change the border of the button to red when the mouse is over the button.--> <VisualState x:Name="MouseOver"> <Storyboard> <ColorAnimation Storyboard.TargetName="BorderBrush" Storyboard.TargetProperty="Color" To="Red" /> </Storyboard> </VisualState>

The control is responsible for defining the states as part of its control contract, which is discussed in detail in Customizing Other Controls by Understanding the Control Contract later in this topic. The states of a control are specified by the TemplateVisualStateAttribute, which is placed on the control's class definition. A TemplateVisualStateAttribute specifies the name of the state and the name of the state group that the state belongs to. The following example shows the states that are specified for the Button. JavaScript C# C++ F# JScript VB Copy to Clipboard
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")] [TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates")] [TemplateVisualState(Name = "Pressed", GroupName = "CommonStates")] [TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")] [TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")] [TemplateVisualState(Name = "Focused", GroupName = "FocusStates")] public class Button : ButtonBase { }

The TemplateVisualStateAttribute. GroupName property specifies which group a state belongs to. In the preceding example, the Button defines two state groups: the CommonStates group contains the Normal, MouseOver, Pressed, and Disabled states. The FocusStates group contains the Focused and Unfocused states. States in the same state group are mutually exclusive. The control is always in exactly one state per group. For example, a Button can have focus even when the mouse pointer is not over it, so a Button in the Focused state can be in the MouseOver, Pressed, or Normal state. You add VisualState objects to VisualStateGroup objects. You add VisualStateGroup objects to the VisualStateManager.VisualStateGroups attached property, which you set on the root FrameworkElement of the ControlTemplate. The following example defines the VisualState

objects for the Normal, MouseOver, and Pressed states, which are all in the CommonStates group. The Disabled state and the states in the FocusStates group are omitted to keep the example short, but they are included in the entire example in Walkthrough: Customizing the Appearance of a Button by Using a ControlTemplate. Run this sample XAML Copy to Clipboard
<ControlTemplate TargetType="Button"> <Border x:Name="RootElement"> <VisualStateManager.VisualStateGroups> <!--Define the states for the common states. The states in the VisualStateGroup are mutually exclusive to each other.--> <VisualStateGroup x:Name="CommonStates"> <!--The Normal state is the state the button is in when it is not in another state from this VisualStateGroup.--> <VisualState x:Name="Normal" /> <!--Change the SolidColorBrush, BorderBrush, to red when the mouse is over the button.--> <VisualState x:Name="MouseOver"> <Storyboard> <ColorAnimation Storyboard.TargetName="BorderBrush" Storyboard.TargetProperty="Color" To="Red" /> </Storyboard> </VisualState> <!--Change the SolidColorBrush, BorderBrush, to Transparent when the button is pressed.--> <VisualState x:Name="Pressed"> <Storyboard > <ColorAnimation Storyboard.TargetName="BorderBrush" Storyboard.TargetProperty="Color" To="Transparent"/> </Storyboard> </VisualState> <!--The Disabled state is omitted for brevity.--> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Border.Background> <SolidColorBrush x:Name="BorderBrush" Color="Black"/> </Border.Background> <Grid Background="{TemplateBinding Background}" Margin="4">

<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4" /> </Grid> </Border> </ControlTemplate>

Specifying the Behavior of a Control When It Transitions Between States

If you run the preceding sample, you will notice that the appearance of a button changes when you point to it. The appearance of the button also changes when you click it, but unless you keep the button pressed for a full second, you do not see the effect. By default, an animation takes one second to occur. Because users are likely to click and release a button in much less time, the visual feedback will not be effective if you leave the ControlTemplate in its default state. You can specify the amount of time that it takes an animation to occur to smoothly transition a control from one state to another by adding VisualTransition objects to the ControlTemplate. When you create a VisualTransition, you specify one or more of the following:

The time it takes for a transition between states to occur. Additional changes in the control's appearance that occur at the time of the transition. Which states the VisualTransition is applied to.

Specifying the Duration of a Transition


You can specify how long a transition takes by setting the GeneratedDuration property. The preceding example has a VisualState that specifies that the button's border becomes transparent when the button is pressed, but the animation takes too long to be noticeable if the button is quickly pressed and released. You can use a VisualTransition to specify the amount of time it takes the control to transition into the pressed state. The following example specifies that the control takes one hundredth of a second to go into the pressed state. XAML Copy to Clipboard
<!--Take one hundredth of a second to transition to the Pressed state.--> <VisualTransition To="Pressed" GeneratedDuration="0:0:0.01" />

Specifying Changes to the Control's Appearance During a Transition


The VisualTransition contains a Storyboard that begins when the control transitions between states. For example, you can specify that a certain animation occurs when the control transitions from the MouseOver state to the Normal State. The following example creates a

VisualTransition that specifies that when the user moves the mouse pointer away from the button, the button's border changes to blue, then to yellow, then to black in 1.5 seconds. XAML Copy to Clipboard
<!--Take one and a half seconds to transition from the MouseOver state to the Normal state. Have the SolidColorBrush, BorderBrush, fade to blue, then to yellow, and then to black in that time.--> <VisualTransition From="MouseOver" To="Normal" GeneratedDuration="0:0:1.5"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Color" Storyboard.TargetName="BorderBrush" FillBehavior="HoldEnd" > <ColorAnimationUsingKeyFrames.KeyFrames> <LinearColorKeyFrame Value="Blue" KeyTime="0:0:0.5" /> <LinearColorKeyFrame Value="Yellow" KeyTime="0:0:1" /> <LinearColorKeyFrame Value="Black" KeyTime="0:0:1.5" /> </ColorAnimationUsingKeyFrames.KeyFrames> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualTransition>

Specifying When a VisualTransition Is Applied


In the preceding example, the VisualTransition is applied when the control goes from the MouseOver state to the Normal state; in the example before that, the VisualTransition is applied when the control goes into the Pressed state. A VisualTransition can be restricted to apply to only certain states, or it can be applied any time the control transitions between states. You restrict when a VisualTransition is applied by setting the To and From properties. The following table describes the levels of restriction from most restrictive to least restrictive. Type of restriction From a specified state to another specified state From any state to a specified state From a specified state to any state From any state to any other state Value of From The name of a VisualState Not set The name of a VisualState Not set Value of To The name of a VisualState The name of a VisualState Not set Not set

You can have multiple VisualTransition objects in a VisualStateGroup that refer to the same state, but they will be used in the order that the table above specifies. In the following example, there are two VisualTransition objects. When the control transitions from the Pressed state to the MouseOver state, the VisualTransition that has both From and To set is used. When the control transitions from a state that is not Pressed to the MouseOver state, the other state is used. XAML Copy to Clipboard
<!--Take one half second to trasition to the MouseOver state.--> <VisualTransition To="MouseOver" GeneratedDuration="0:0:0.5" /> <!--Take one hundredth of a second to transition from the Pressed state to the MouseOver state.--> <VisualTransition From="Pressed" To="MouseOver" GeneratedDuration="0:0:0.01" />

The VisualStateGroup has a Transitions property that contains the VisualTransition objects that apply to the VisualState objects in the VisualStateGroup. As the ControlTemplate author, you are free to include any VisualTransition you want. However, if the To and From properties are set to state names that are not in the VisualStateGroup, the VisualTransition is ignored. The following example shows the VisualStateGroup for the CommonStates. The example defines a VisualTransition for each of the button's following transitions.

To the Pressed state. To the MouseOver state. From the Pressed state to the MouseOver state. From the MouseOver state to the Normal state. Run this sample

XAML Copy to Clipboard


<VisualStateGroup x:Name="CommonStates"> <!--Define the VisualTransitions that can be used when the control transitions between VisualStates that are defined in the VisualStatGroup.--> <VisualStateGroup.Transitions> <!--Take one hundredth of a second to transition to the Pressed state.--> <VisualTransition To="Pressed" GeneratedDuration="0:0:0.01" /> <!--Take one half second to trasition to the MouseOver state.--> <VisualTransition To="MouseOver" GeneratedDuration="0:0:0.5" />

<!--Take one hundredth of a second to transition from the Pressed state to the MouseOver state.--> <VisualTransition From="Pressed" To="MouseOver" GeneratedDuration="0:0:0.01" /> <!--Take one and a half seconds to transition from the MouseOver state to the Normal state. Have the SolidColorBrush, BorderBrush, fade to blue, then to yellow, and then to black in that time.--> <VisualTransition From="MouseOver" To="Normal" GeneratedDuration="0:0:1.5"> <Storyboard> <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Color" Storyboard.TargetName="BorderBrush" FillBehavior="HoldEnd" > <ColorAnimationUsingKeyFrames.KeyFrames> <LinearColorKeyFrame Value="Blue" KeyTime="0:0:0.5" /> <LinearColorKeyFrame Value="Yellow" KeyTime="0:0:1" /> <LinearColorKeyFrame Value="Black" KeyTime="0:0:1.5" /> </ColorAnimationUsingKeyFrames.KeyFrames> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualTransition> </VisualStateGroup.Transitions> <!--The remainder of the VisualStateGroup is the same as the previous example.--> <VisualState x:Name="Normal" /> <VisualState x:Name="MouseOver"> <Storyboard> <ColorAnimation Storyboard.TargetName="BorderBrush" Storyboard.TargetProperty="Color" To="Red" /> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard > <ColorAnimation Storyboard.TargetName="BorderBrush" Storyboard.TargetProperty="Color" To="Transparent"/> </Storyboard> </VisualState> <!--The Disabled state is omitted for brevity.--> </VisualStateGroup>

Customizing Other Controls by Understanding the Control Contract

A control that uses a ControlTemplate to specify its visual structure (by using FrameworkElement objects) and visual behavior (by using VisualState objects) uses the parts control model. Many of the controls that ship with Silverlight and third-party controls use this model. The parts that a ControlTemplate author needs to be aware of are communicated through the control contract. When you understand the parts of a control contract, you can customize the appearance of any control that uses the parts control model. A control contract has three elements:

The visual elements that the control's logic uses. The states of the control and the group each state belongs to. The public properties that visually affect the control.

Visual Elements in the Control Contract


Sometimes a control's logic interacts with a FrameworkElement that is in the ControlTemplate. For example, the control might handle an event of one of its elements. When a control expects to find a particular FrameworkElement in the ControlTemplate, it must convey that information to the ControlTemplate author. The control uses the TemplatePartAttribute to convey the type of element that is expected, and what the name of the element should be. The Button does not have FrameworkElement parts in its control contract, but other controls, such as the ComboBox, do. The following example shows the TemplatePartAttribute objects that are specified on the ComboBox class. The logic of ComboBox expects to find a Popup named Popup and a ContentPresenter named ContentPresenter in its ControlTemplate. JavaScript C# C++ F# JScript VB Copy to Clipboard
[TemplatePartAttribute(Name = "ContentPresenter", Type = typeof(ContentPresenter))] [TemplatePartAttribute(Name = "Popup", Type = typeof(Popup))] public class ComboBox : ItemsControl { }

The following example shows a simplified ControlTemplate for the ComboBox that includes the elements that are specified by the TemplatePartAttribute objects on the ComboBox class.

XAML Copy to Clipboard


<ControlTemplate TargetType="ComboBox"> <Grid> <Border x:Name="ContentPresenterBorder"> <Grid> <ToggleButton x:Name="DropDownToggle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="-1" HorizontalContentAlignment="Right"> <Path x:Name="BtnArrow" Height="4" Width="8" Stretch="Uniform" Margin="0,0,6,0" Fill="Black" Data="F1 M 300,-190L 310,-190L 305,-183L 301,-190 Z " /> </ToggleButton> <ContentPresenter x:Name="ContentPresenter" Margin="6,2,25,2"> <TextBlock Text=" " /> </ContentPresenter> </Grid> </Border> <Popup x:Name="Popup"> <Border x:Name="PopupBorder" HorizontalAlignment="Stretch" Height="Auto" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Black" Background="White" CornerRadius="3"> <ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1"> <ItemsPresenter/> </ScrollViewer> </Border> </Popup> </Grid> </ControlTemplate>

States in the Control Contract


The states of a control are also a part of the control contract. The example of creating a ControlTemplate for a Button shows how to specify the appearance of a Button depending on its states. As described in Changing the Appearance of a Control Depending on Its State earlier in this topic, the states of a control are specified by the TemplateVisualStateAttribute. You create a VisualState for each specified state and put all VisualState objects that share a GroupName in a VisualStateGroup.

Properties in the Control Contract


The public properties that visually affect the control are also included in the control contract. You can set these properties to change the appearance of the control without creating a new ControlTemplate. You can also use the TemplateBinding markup extension to bind properties of elements that are in the ControlTemplate to public properties that are defined by the Button. For controls that ship with Silverlight 5, you can find the visual element and states that are included in the control contract by looking at the control's reference topic. For example, the syntax section on the ComboBox class reference shows the TemplatePartAttribute and the

TemplateVisualStateAttribute that the ComboBox specifies. Although your application should run without throwing an exception if you do not include an expected FrameworkElement or VisualState, the control may not behave as expected. Any public property that affects the control visually is also a part of the control contract. The following example summarizes the control contract for the button. JavaScript C# C++ F# JScript VB Copy to Clipboard
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")] [TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates")] [TemplateVisualState(Name = "Pressed", GroupName = "CommonStates")] [TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")] [TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")] [TemplateVisualState(Name = "Focused", GroupName = "FocusStates")] public class Button : ButtonBase { public static readonly DependencyProperty BackgroundProperty; public static readonly DependencyProperty BorderBrushProperty; public static readonly DependencyProperty BorderThicknessProperty; public static readonly DependencyProperty ContentProperty; public static readonly DependencyProperty ContentTemplateProperty; public static readonly DependencyProperty FontFamilyProperty; public static readonly DependencyProperty FontSizeProperty; public static readonly DependencyProperty FontStretchProperty; public static readonly DependencyProperty FontStyleProperty; public static readonly DependencyProperty FontWeightProperty; public static readonly DependencyProperty ForegroundProperty; public static readonly DependencyProperty HorizontalContentAlignmentProperty; public static readonly DependencyProperty PaddingProperty; public static readonly DependencyProperty TextAlignmentProperty; public static readonly DependencyProperty TextDecorationsProperty; public static readonly DependencyProperty TextWrappingProperty; public static readonly DependencyProperty VerticalContentAlignmentProperty; public public public public public public public public public public public public Brush Background { get; set; } Brush BorderBrush { get; set; } Thickness BorderThickness { get; set; } object Content { get; set; } DataTemplate ContentTemplate { get; set; } FontFamily FontFamily { get; set; } double FontSize { get; set; } FontStretch FontStretch { get; set; } FontStyle FontStyle { get; set; } FontWeight FontWeight { get; set; } Brush Foreground { get; set; } HorizontalAlignment HorizontalContentAlignment { get; set; }

public public public public public }

Thickness Padding { get; set; } TextAlignment TextAlignment { get; set; } TextDecorationCollection TextDecorations { get; set; } TextWrapping TextWrapping { get; set; } VerticalAlignment VerticalContentAlignment { get; set; }

When creating a ControlTemplate, it is often easiest to begin with an existing ControlTemplate and making changes to it. You can do one of the following to change an existing ControlTemplate:

Use a designer such as Microsoft Expression Blend, which provides a graphical user interface for creating control templates. For more information, see Create a Reusable Template for a System Control. Get the default ControlTemplate and edit it. To see the default templates for controls that ship with Silverlight, see Control Styles and Templates.

To successfully create a ControlTemplate, you must understand the control's control contract. When you understand the parts of a control contract, you can create a new ControlTemplate for existing controls and create an application that has a unique look and feel. See Also

Concepts
Viewbox Class

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

Defines a content decorator that can stretch and scale a single child to fill the available space.
Inheritance Hierarchy

System. Object System.Windows. DependencyObject System.Windows. UIElement System.Windows. FrameworkElement System.Windows.Controls. Viewbox

Namespace: System.Windows.Controls Assembly:System.Windows (in System.Windows.dll)

Syntax

JavaScript C# C++ F# JScript VB Copy to Clipboard


[ContentPropertyAttribute("Child", true)] public sealed class Viewbox : FrameworkElement

XAML Copy to Clipboard


<ViewBox .../> -or<ViewBox ...> child </ViewBox>

XAML Values
child

A single object element of a type that derives from UIElement, which is contained by this Viewbox. See Child. The Viewbox type exposes the following members.
Constructors

Show:

Inherited

Protected

Name

Description

Viewbox Initializes a new instance of the Viewbox class. Top

Properties

Show:

Inherited Name

Protected Description Gets the rendered height of a FrameworkElement. (Inherited from FrameworkElement.)

ActualHeight

ActualWidth

Gets the rendered width of a FrameworkElement. (Inherited from FrameworkElement.) Gets or sets a value that determines whether this UIElement can be a drop target for purposes of Silverlight drag-and-drop operations. (Inherited from UIElement.) Gets or sets a value that indicates that rendered content should be cached when possible. (Inherited from UIElement.)

AllowDrop

CacheMode

Child

Gets or sets the single child element of a Viewbox element.

Clip

Gets or sets the Geometry used to define the outline of the contents of a UIElement. (Inherited from UIElement.)

Cursor

Gets or sets the cursor image that displays while the mouse pointer is over a FrameworkElement. (Inherited from FrameworkElement.)

DataContext

Gets or sets the data context for a FrameworkElement when it participates in data binding. (Inherited from FrameworkElement.)

DesiredSize

Gets the size that this UIElement computed during the measure pass of the layout process. (Inherited from UIElement.)

Dispatcher

Gets the Dispatcher this object is associated with. (Inherited from DependencyObject.) Gets or sets the pixel shader effect to use for rendering this UIElement. (Inherited from UIElement.) Gets or sets the direction that text and other user interface elements flow within any parent element that controls their layout. (Inherited from FrameworkElement.) Gets or sets the suggested height of a FrameworkElement. (Inherited from FrameworkElement.) Gets or sets the horizontal alignment characteristics that are applied to a FrameworkElement when it is composed in a layout parent, such as a panel or items control. (Inherited from FrameworkElement.) Gets or sets whether the contained area of this UIElement can return true values for hit testing. (Inherited from UIElement.)

Effect

FlowDirection

Height

HorizontalAlignment

IsHitTestVisible

Language

Gets or sets localization/globalization language information that applies to a FrameworkElement. (Inherited from FrameworkElement.)

Margin

Gets or sets the outer margin of a FrameworkElement. (Inherited from FrameworkElement.)

MaxHeight

Gets or sets the maximum height constraint of a FrameworkElement. (Inherited from FrameworkElement.)

MaxWidth

Gets or sets the maximum width constraint of a FrameworkElement. (Inherited from FrameworkElement.)

MinHeight

Gets or sets the minimum height constraint of a FrameworkElement. (Inherited from FrameworkElement.)

MinWidth

Gets or sets the minimum width constraint of a FrameworkElement. (Inherited from FrameworkElement.) Gets or sets the identifying name of the object. When a XAML processor creates the object tree from XAML markup, run-time code can refer to the XAML-declared object by this name. (Inherited from FrameworkElement.) Gets or sets the degree of the object's opacity. (Inherited from UIElement.)

Name

Opacity

OpacityMask

Gets or sets the brush used to alter the opacity of regions of this object. (Inherited from UIElement.)

Parent

Gets the parent object of this FrameworkElement in the object tree. (Inherited from FrameworkElement.)

Projection

Gets or sets the perspective projection (3-D effect) to apply when rendering this UIElement. (Inherited from UIElement.)

RenderSize

Gets the final render size of a UIElement. (Inherited from UIElement.)

RenderTransform

Gets or sets transform information that affects the rendering position of a UIElement. (Inherited from UIElement.)

Gets or sets the origin point of any possible render transform declared RenderTransformOrigin by RenderTransform, relative to the bounds of the UIElement. (Inherited from UIElement.) Gets the locally defined resource dictionary. In XAML, you can establish resource items as child object elements of a frameworkElement.Resources property element, through XAML implicit collection syntax. (Inherited from FrameworkElement.) Gets or sets the Stretch mode, which determines how content fits into the available space.

Resources

Stretch

StretchDirection

Gets or sets the StretchDirection, which determines how scaling is applied to the contents of a Viewbox.

Style

Gets or sets an instance Style that is applied for this object during rendering. (Inherited from FrameworkElement.)

Tag

Gets or sets an arbitrary object value that can be used to store custom information about this object. (Inherited from FrameworkElement.)

Triggers

Gets the collection of triggers for animations that are defined for a FrameworkElement. (Inherited from FrameworkElement.) Gets or sets a value that determines whether rendering for the object and its visual subtree should use rounding behavior that aligns rendering to whole pixels. (Inherited from UIElement.) Gets or sets the vertical alignment characteristics that are applied to a FrameworkElement when it is composed in a parent object such as a panel or items control. (Inherited from FrameworkElement.) Gets or sets the visibility of a UIElement. A UIElement that is not visible does not render and does not communicate its desired size to layout. (Inherited from UIElement.)

UseLayoutRounding

VerticalAlignment

Visibility

Width

Gets or sets the width of a FrameworkElement. (Inherited from FrameworkElement.)

Top

Methods

Show:

Inherited Name

Protected Description Adds a routed event handler for a specified routed event, adding the handler to the handler collection on the current element. Specify handledEventsToo as true to have the provided handler be invoked for routed event that had already been marked as handled by another element along the event route. (Inherited from UIElement.) Positions child objects and determines a size for a UIElement. Parent objects that implement custom layout for their child elements should call this method from their layout override implementations to form a recursive layout update. (Inherited from UIElement.) Provides the behavior for the Arrange pass of Silverlight layout. Classes can override this method to define their own Arrange pass behavior. (Inherited from FrameworkElement.)

AddHandler

Arrange

ArrangeOverride

CaptureMouse

Sets mouse capture to a UIElement. (Inherited from UIElement.)

CheckAccess

Determines whether the calling thread has access to this object. (Inherited from DependencyObject.)

ClearValue

Clears the local value of a dependency property. (Inherited from DependencyObject.)

Equals(Object)

Determines whether the specified Object is equal to the current Object. (Inherited from Object.) Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Retrieves an object that has the specified identifier name. (Inherited from FrameworkElement.)

Finalize

FindName

Returns any base value established for a Silverlight dependency GetAnimationBaseValue property, which would apply in cases where an animation is not active. (Inherited from DependencyObject.) Retrieves the BindingExpression for a dependency property where a binding is established. (Inherited from FrameworkElement.)

GetBindingExpression

GetHashCode

Serves as a hash function for a particular type. (Inherited from Object.)

GetType

Gets the Type of the current instance. (Inherited from Object.)

GetValue

Returns the current effective value of a dependency property from a DependencyObject. (Inherited from DependencyObject.) Invalidates the arrange state (layout) for a UIElement. After the invalidation, the UIElement will have its layout updated, which will occur asynchronously. (Inherited from UIElement.) Invalidates the measurement state (layout) for a UIElement. (Inherited from UIElement.) Updates the DesiredSize of a UIElement. Typically, objects that implement custom layout for their layout children call this method

InvalidateArrange

InvalidateMeasure

Measure

from their own MeasureOverride implementations to form a recursive layout update. (Inherited from UIElement.) Provides the behavior for the Measure pass of Silverlight layout. Classes can override this method to define their own Measure pass behavior. (Inherited from FrameworkElement.)

MeasureOverride

MemberwiseClone

Creates a shallow copy of the current Object. (Inherited from Object.)

OnApplyTemplate

When overridden in a derived class, is invoked whenever application code or internal processes (such as a rebuilding layout pass) call ApplyTemplate. In simplest terms, this means the method is called just before a UI element displays in an application. For more information, see Remarks. (Inherited from FrameworkElement.)

When implemented in a derived class, returns class-specific OnCreateAutomationPeer AutomationPeer implementations for the Silverlight automation infrastructure. (Inherited from UIElement.) Returns the local value of a dependency property, if a local value is set. (Inherited from DependencyObject.)

ReadLocalValue

ReleaseMouseCapture

Removes mouse capture from a UIElement. After this call, typically no object holds mouse capture. (Inherited from UIElement.)

RemoveHandler

Removes the specified routed event handler from this UIElement. (Inherited from UIElement.) Attaches a binding to a FrameworkElement, using the provided binding object, and returns a BindingExpressionBase for possible later use. (Inherited from FrameworkElement.) Sets the local value of a dependency property on a DependencyObject. (Inherited from DependencyObject.)

SetBinding

SetValue

ToString

Returns a string that represents the current object. (Inherited from Object.) Returns a transform object that can be used to transform coordinates from the UIElement to the specified object. (Inherited from UIElement.) Ensures that all positions of child objects of a UIElement are properly updated for layout. (Inherited from UIElement.)

TransformToVisual

UpdateLayout

Top

Events

Show:

Inherited Name

Protected Description Occurs when a data validation error is reported by a binding source. (Inherited from FrameworkElement.) Occurs when the data context for this element changes. (Inherited from FrameworkElement.) Occurs when a DoubleTap gesture is committed while over this UIElement. (Inherited from UIElement.) Occurs when the input system reports an underlying drag event with this element as the target. (Inherited from UIElement.) Occurs when the input system reports an underlying drag event with this element as the origin. (Inherited from UIElement.) Occurs when the input system reports an underlying drag event with this element as the potential drop target. (Inherited from UIElement.)

BindingValidationError

DataContextChanged

DoubleTap

DragEnter

DragLeave

DragOver

Drop

Occurs when the input system reports an underlying drop event with this element as the drop target. (Inherited from UIElement.)

GotFocus

Occurs when a UIElement receives focus. (Inherited from UIElement.)

Hold

Occurs when a Hold gesture is committed while over this UIElement. (Inherited from UIElement.)

KeyDown

Occurs when a keyboard key is pressed while the UIElement has focus. (Inherited from UIElement.)

KeyUp

Occurs when a keyboard key is released while the UIElement has focus. (Inherited from UIElement.)

LayoutUpdated

Occurs when the layout of the Silverlight visual tree changes. (Inherited from FrameworkElement.)

Loaded

Occurs when a FrameworkElement has been constructed and added to the object tree. (Inherited from FrameworkElement.)

LostFocus

Occurs when a UIElement loses focus. (Inherited from UIElement.)

LostMouseCapture

Occurs when the UIElement loses mouse capture. (Inherited from UIElement.)

ManipulationCompleted

Occurs when a manipulation and inertia on the UIElement is complete. (Inherited from UIElement.)

ManipulationDelta

Occurs when the input device changes position during a manipulation. (Inherited from UIElement.)

ManipulationStarted

Occurs when an input device begins a manipulation on the UIElement. (Inherited from UIElement.) Occurs when a button is pressed on a remote control. (Inherited from UIElement.) Occurs when the mouse (or a stylus) enters the bounding area of a UIElement. (Inherited from UIElement.)

MediaCommand

MouseEnter

MouseLeave

Occurs when the mouse (or the stylus) leaves the bounding area of a UIElement. (Inherited from UIElement.)

Occurs when the left mouse button is pressed (or when the tip of the MouseLeftButtonDown stylus touches the tablet) while the mouse pointer is over a UIElement. (Inherited from UIElement.) Occurs when the left mouse button is released (or the tip of the stylus is removed from the tablet) while the mouse (or the stylus) is over a UIElement (or while a UIElement holds mouse capture). (Inherited from UIElement.) Occurs when the coordinate position of the mouse (or stylus) changes while over a UIElement (or while a UIElement holds mouse capture). (Inherited from UIElement.) Occurs when the right mouse button is pressed while the mouse pointer is over a UIElement. (Inherited from UIElement.) Occurs when the right mouse button is released while the mouse pointer is over a UIElement. However, this event will only be raised if a caller marks the preceding MouseRightButtonDown event as handled; see Remarks. (Inherited from UIElement.) Occurs when the user rotates the mouse wheel while the mouse pointer is over a UIElement, or the UIElement has focus. (Inherited from UIElement.) Occurs when either the ActualHeight or the ActualWidth properties change value on a FrameworkElement. (Inherited from

MouseLeftButtonUp

MouseMove

MouseRightButtonDown

MouseRightButtonUp

MouseWheel

SizeChanged

FrameworkElement.)

Tap

Occurs when a Tap gesture is committed while over this UIElement. (Inherited from UIElement.)

TextInput

Occurs when a UI element gets text in a device-independent manner. (Inherited from UIElement.)

TextInputStart

Occurs when a UI element initially gets text in a device-independent manner. (Inherited from UIElement.)

TextInputUpdate

Occurs when text continues to be composed via an input method editor (IME). (Inherited from UIElement.)

Unloaded

Occurs when this object is no longer connected to the main object tree. (Inherited from FrameworkElement.)

Top

Fields

Show:

Inherited

Protected Name Description

StretchDirectionProperty Identifies the StretchDirection dependency property. StretchProperty Top Identifies the Stretch dependency property.

Remarks

A Viewbox control takes one child element and stretches it or scales it to fit the size of the Viewbox. You can control the stretch or scale levels by using the Stretch, StretchDirection, HorizontalAlignment, and VerticalAlignment properties. You typically use a Viewbox for 2D graphic images. You typically do not use a Viewbox for ordinary controls. Viewbox is a sealed class. Content Model: The content property of a Viewbox is Child. A Viewbox can have only one Child. If you add an additional Child, an ArgumentException will be thrown at run time.

Examples

The following example shows what happens when you change the StretchDirection and Stretch properties of a Viewbox. The example includes three Viewbox controls that have different sizes. The same image is displayed in the Viewbox controls so that you can compare the differences. You can manipulate the stretching and scaling of the image by clicking the buttons that correspond to the values for the Stretch and StretchDirection enumerations.
XAML Copy to Clipboard
<Grid Height="600" Width="600"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="auto" /> <RowDefinition /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Grid.Column="0" Margin="5,5,5,5" Orientation="Vertical"> <TextBlock Text="Stretch" FontWeight="Bold" FontSize="12" /> <Button Name="btn1" Click="stretchNone" Content="None" /> <Button Name="btn2" Click="stretchFill" Content="Fill" /> <Button Name="btn3" Click="stretchUni" Content="Uniform" /> <Button Name="btn4" Click="stretchUniFill" Content="UniformToFill" /> </StackPanel>

<StackPanel Grid.Row="0" Grid.Column="1" Margin="5,5,5,5" Orientation="Vertical"> <TextBlock Text="StretchDirection" FontWeight="Bold" FontSize="12" /> <Button Name="btn5" Click="sdUpOnly" Content="UpOnly" /> <Button Name="btn6" Click="sdDownOnly" Content="DownOnly" /> <Button Name="btn7" Click="sdBoth" Content="Both" /> </StackPanel> <StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5,5" Orientation="Vertical"> <TextBlock Name="txt1" FontSize="12" FontWeight="Bold" /> <TextBlock Name="txt2" FontSize="12" FontWeight="Bold" /> </StackPanel> <StackPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5,5" Orientation="Horizontal"> <Viewbox MaxWidth="100" MaxHeight="100" Name="vb1"> <Image Source="flower.jpg"/> </controls:Viewbox> <controls:Viewbox MaxWidth="200" MaxHeight="200" Name="vb2"> <Image Source="flower.jpg"/> </Viewbox> <Viewbox MaxWidth="300" MaxHeight="300" Name="vb3"> <Image Source="flower.jpg"/> </Viewbox> </StackPanel> </Grid>

The following shows the code for the button click handlers.
JavaScript C# C++ F# JScript VB Copy to Clipboard
//Setting the Stretch property to None private void stretchNone(object sender, RoutedEventArgs e) { vb1.Stretch = Stretch.None; vb2.Stretch = Stretch.None; vb3.Stretch = Stretch.None; txt1.Text = "Stretch is now set to None."; }

//Setting the Stretch property to Fill private void stretchFill(object sender, RoutedEventArgs e) { vb1.Stretch = Stretch.Fill; vb2.Stretch = Stretch.Fill; vb3.Stretch = Stretch.Fill; txt1.Text = "Stretch is now set to Fill."; } //Setting the Stretch property to Uniform private void stretchUni(object sender, RoutedEventArgs e) { vb1.Stretch = Stretch.Uniform; vb2.Stretch = Stretch.Uniform; vb3.Stretch = Stretch.Uniform; txt1.Text = "Stretch is now set to Uniform."; } //Setting the Stretch property to UniformToFill private void stretchUniFill(object sender, RoutedEventArgs e) { vb1.Stretch = Stretch.UniformToFill; vb2.Stretch = Stretch.UniformToFill; vb3.Stretch = Stretch.UniformToFill; txt1.Text = "Stretch is now set to UniformToFill."; } //Setting the StretchDirection property to UpOnly private void sdUpOnly(object sender, RoutedEventArgs e) { vb1.StretchDirection = StretchDirection.UpOnly; vb2.StretchDirection = StretchDirection.UpOnly; vb3.StretchDirection = StretchDirection.UpOnly; txt2.Text = "StretchDirection is now UpOnly."; } //Setting the StretchDirection property to DownOnly private void sdDownOnly(object sender, RoutedEventArgs e) { vb1.StretchDirection = StretchDirection.DownOnly; vb2.StretchDirection = StretchDirection.DownOnly; vb3.StretchDirection = StretchDirection.DownOnly; txt2.Text = "StretchDirection is now DownOnly."; } //Setting the StretchDirection property to Both private void sdBoth(object sender, RoutedEventArgs e) { vb1.StretchDirection = StretchDirection.Both; vb2.StretchDirection = StretchDirection.Both; vb3.StretchDirection = StretchDirection.Both; txt2.Text = "StretchDirection is now Both."; }

Version Information

Silverlight Architecture Send Feedback on this topic to Microsoft. View this topic online in your default browser.

This topic describes the essential architecture and components of Microsoft Silverlight. Silverlight is not only an appealing canvas for displaying rich and interactive Web and media content to end users. It is also a powerful yet lightweight platform for developing portable, crossplatform, networked applications that integrate data and services from many sources. Furthermore, Silverlight enables you to build user interfaces that will significantly enhance the typical end user experience compared with traditional Web applications. While Silverlight as a client-side runtime environment seems simple and compact in size, the Silverlight development platform integrates a number of features and complex technologies, making them accessible for developers. To create effective Silverlight-based applications, developers need a working knowledge of the platform architecture.

Note: Silverlight supports two programming models: the JavaScript API for Silverlight and the managed API for Silverlight. The managed API is based on a subset of the .NET Framework. Many of the features in this article are supported only by the managed API. For more information, see Application and Programming Models. This topic contains the following sections.

The Silverlight Platform Core Presentation Components The .NET Framework for Silverlight Additional Silverlight Programming Features Related Technologies and Tools Related Topics The Silverlight Platform

The Silverlight platform as a whole consists of two major parts, plus an installer and update component, as described in the following table. Component Core presentation framework Description Components and services oriented toward the UI and user interaction, including user input, lightweight UI controls for use in Web applications, media playback, digital rights management, data binding, and presentation features, including vector graphics, text, animation, and images. Also includes the

Extensible Application Markup Language (XAML) for specifying layout. A subset of the .NET Framework that contains components and libraries, including data integration, extensible Windows controls, networking, base class libraries, garbage collection, and the common language runtime (CLR). .NET Some parts of the .NET Framework for Silverlight are deployed with your Framework for application. These "Silverlight Libraries" are assemblies not included in the Silverlight Silverlight runtime and are instead shipped in the Silverlight SDK. When Silverlight Libraries are used in your application, they are packaged up with your application and downloaded to the browser. These include new UI controls, XLINQ, Syndication (RSS/Atom), XML serialization, and the dynamic language runtime (DLR). An installation and update control that simplifies the process of installing the Installer and application for first-time users, and subsequently provides low-impact, updater automatic updates. The following illustration shows these components of the Silverlight architecture, along with related components and services. Silverlight architecture

There is a particular value in the combined set of tools, technologies, and services included in the Silverlight platform: They make it easier for developers to create rich, interactive, and networked applications. Although it is certainly possible to build such applications using today's Web tools and technologies, developers are hindered by many technical difficulties, including incompatible platforms, disparate file formats and protocols, and various Web browsers that render pages and handle scripts differently. A rich Web application that runs perfectly on one system and browser may work very differently on another system or browser, or may fail altogether. Using today's large array of tools, protocols, and technologies, it is a massive and often cost-prohibitive effort to build an application that can simultaneously provide the following advantages:

Ability to create the same user experience across browsers and platforms, so that the application looks and performs the same everywhere. Integration of data and services from multiple networked locations into one application using familiar .NET Framework classes and functionality. A media-rich, compelling, and accessible user interface (UI). Silverlight makes it easier for developers to build such applications, because it overcomes many of the incompatibilities of current technologies, and provides within one platform the tools to create rich, cross-platform, integrated applications. Core Presentation Components

The core presentation features of the Silverlight platform, shown in the previous section and illustration, are described in the following table. Feature Input UI rendering Media Description Handles inputs from hardware devices such as the keyboard and mouse, drawing, or other input devices. Renders vector and bitmap graphics, animations, and text.

Features playback and management of various types of audio and video files, such as .WMP and .MP3 files. Deep Zoom Enables you to zoom in on and pan around high resolution images. Controls Supports extensible controls that are customizable through styling and templating. Layout Enables dynamic positioning of UI elements. Data Enables linking of data objects and UI elements. binding DRM Enables digital rights management of media assets. XAML Provides a parser for XAML markup. Developers can interact with this presentation framework by using XAML to specify presentation details. XAML is the primary point of interaction between the .NET Framework and the presentation layer. Developers can programmatically manipulate the presentation layer using managed code. The .NET Framework for Silverlight

The following table describes a partial list of the .NET Framework for Silverlight features shown in the previous illustration. Feature Data Description Supports Language-Integrated Query (LINQ) and LINQ to XML features, which ease the process of integrating and working with data from disparate sources. Also supports the use of XML and serialization classes for handling data. A set of .NET Framework libraries that provide essential programming functions, such as string handling, regular expressions, input and output, reflection, collections, and globalization. Provides features to simplify access to remote services and data. This includes a browser object, HTTP request and response object, support for cross-domain HTTP requests, support for RSS/Atom syndication feeds, and support for JSON, POX, and SOAP services. Provides memory management, garbage collection, type safety

Base class library Window Communication Foundation (WCF) CLR (common

language runtime) WPF (Windows Presentation Foundation) controls DLR (dynamic language runtime)

checking, and exception handling. Provides a rich set of controls, including Button, CheckBox, HyperlinkButton, ListBox, RadioButton, and ScrollViewer. Supports the dynamic compilation and execution of scripting languages such as JavaScript and IronPython to program Silverlight-based applications. Includes a pluggable model for adding support for other languages for use with Silverlight.

The .NET Framework for Silverlight is a subset of the full .NET Framework. It provides the essentials of robust, object-oriented application development for application types (such as Internet applications) for which this support has not traditionally been available. Developers can interact with the .NET Framework for Silverlight layer by writing managed code using C# and Visual Basic. .NET Framework developers can also access the presentation layer by authoring in Visual Studio or Microsoft Expression Blend. Additional Silverlight Programming Features

Silverlight provides several additional features that help developers create rich and interactive applications, including those described in the following table. Feature Isolated storage Asynchronous programming File management HTMLmanaged code interaction Serialization Packaging Description Provides safe access from the Silverlight client to the local computer's file system. Enables local storage and caching of data isolated to a particular user. A background worker thread carries out programming tasks while the application is freed up for user interaction. Provides a safe File Open dialog box, to ease the process of creating safe file uploads. Enables .NET Framework programmers to directly manipulate UI elements in the HTML DOM of a Web page. Web developers can also use JavaScript to call directly into managed code and access scriptable objects, properties, events, and methods. Provides support for serialization of CLR types to JSON and XML. Provides the Application class and build tools to create .xap packages. The .xap package contains the application and entry point for the Silverlight plug-in control to run. XmlReader and XmlWriter classes simplify working with XML data from Web services. The XLinq feature enables developers to query XML data directly within .NET Framework programming languages.

XML libraries

Related Technologies and Tools

The following Microsoft applications include special features for Silverlight development:

Microsoft Expression Blend. This tool can be used to create and modify the presentation layer of an application by manipulating the XAML canvas and controls, working with graphics, and programming the presentation layer with a dynamic language such as JavaScript. Visual Studio. Visual Studio 2010 provides visual design support for creating Silverlight applications. You can build user interfaces for your applications by dragging controls from the Toolbox and setting properties in the Properties window. You can also edit XAML directly in the XAML view. For more information, see Silverlight Tools and Silverlight Designer for Visual Studio 2010.

Because Silverlight-based applications are executed in a run-time environment on the client machine, no particular application is required to be installed on the server. However, developers may find that their ability to create rich applications that integrate services and data from multiple sources on the server is enhanced by integrating the following types of services and server-side applications into their Silverlight-based applications:

ASP.NET AJAX. This includes a set of controls, services, and libraries for creating rich and interactive Web-based applications. Microsoft Windows Communication Foundation (WCF) services. Internet servers, including Microsoft Internet Information Services (IIS), and the Apache Web server. Internet-based applications and services, including Microsoft ASP.NET, PHP, Windows Streaming Media services, Windows Live services, and other open Web services. See Also

Silverlight Architecture Send Feedback on this topic to Microsoft. View this topic online in your default browser.

This topic describes the essential architecture and components of Microsoft Silverlight. Silverlight is not only an appealing canvas for displaying rich and interactive Web and media content to end users. It is also a powerful yet lightweight platform for developing portable, crossplatform, networked applications that integrate data and services from many sources. Furthermore, Silverlight enables you to build user interfaces that will significantly enhance the typical end user experience compared with traditional Web applications.

While Silverlight as a client-side runtime environment seems simple and compact in size, the Silverlight development platform integrates a number of features and complex technologies, making them accessible for developers. To create effective Silverlight-based applications, developers need a working knowledge of the platform architecture.

Note: Silverlight supports two programming models: the JavaScript API for Silverlight and the managed API for Silverlight. The managed API is based on a subset of the .NET Framework. Many of the features in this article are supported only by the managed API. For more information, see Application and Programming Models. This topic contains the following sections.

The Silverlight Platform Core Presentation Components The .NET Framework for Silverlight Additional Silverlight Programming Features Related Technologies and Tools Related Topics The Silverlight Platform

The Silverlight platform as a whole consists of two major parts, plus an installer and update component, as described in the following table. Component Core presentation framework Description Components and services oriented toward the UI and user interaction, including user input, lightweight UI controls for use in Web applications, media playback, digital rights management, data binding, and presentation features, including vector graphics, text, animation, and images. Also includes the Extensible Application Markup Language (XAML) for specifying layout. A subset of the .NET Framework that contains components and libraries, including data integration, extensible Windows controls, networking, base class libraries, garbage collection, and the common language runtime (CLR).

.NET Some parts of the .NET Framework for Silverlight are deployed with your Framework for application. These "Silverlight Libraries" are assemblies not included in the Silverlight Silverlight runtime and are instead shipped in the Silverlight SDK. When Silverlight Libraries are used in your application, they are packaged up with your application and downloaded to the browser. These include new UI controls, XLINQ, Syndication (RSS/Atom), XML serialization, and the dynamic language runtime (DLR).

Installer and updater

An installation and update control that simplifies the process of installing the application for first-time users, and subsequently provides low-impact, automatic updates.

The following illustration shows these components of the Silverlight architecture, along with related components and services. Silverlight architecture

There is a particular value in the combined set of tools, technologies, and services included in the Silverlight platform: They make it easier for developers to create rich, interactive, and networked applications. Although it is certainly possible to build such applications using today's Web tools and technologies, developers are hindered by many technical difficulties, including incompatible platforms, disparate file formats and protocols, and various Web browsers that render pages and handle scripts differently. A rich Web application that runs perfectly on one system and browser may work very differently on another system or browser, or may fail altogether. Using today's large array of tools, protocols, and technologies, it is a massive and often cost-prohibitive effort to build an application that can simultaneously provide the following advantages:

Ability to create the same user experience across browsers and platforms, so that the application looks and performs the same everywhere. Integration of data and services from multiple networked locations into one application using familiar .NET Framework classes and functionality. A media-rich, compelling, and accessible user interface (UI). Silverlight makes it easier for developers to build such applications, because it overcomes many of the incompatibilities of current technologies, and provides within one platform the tools to create rich, cross-platform, integrated applications. Core Presentation Components

The core presentation features of the Silverlight platform, shown in the previous section and illustration, are described in the following table. Feature Input UI rendering Media Description Handles inputs from hardware devices such as the keyboard and mouse, drawing, or other input devices. Renders vector and bitmap graphics, animations, and text. Features playback and management of various types of audio and video files, such as .WMP and .MP3 files.

Deep Zoom Controls Layout Data binding DRM XAML

Enables you to zoom in on and pan around high resolution images. Supports extensible controls that are customizable through styling and templating. Enables dynamic positioning of UI elements. Enables linking of data objects and UI elements. Enables digital rights management of media assets. Provides a parser for XAML markup.

Developers can interact with this presentation framework by using XAML to specify presentation details. XAML is the primary point of interaction between the .NET Framework and the presentation layer. Developers can programmatically manipulate the presentation layer using managed code. The .NET Framework for Silverlight

The following table describes a partial list of the .NET Framework for Silverlight features shown in the previous illustration. Feature Data Description Supports Language-Integrated Query (LINQ) and LINQ to XML features, which ease the process of integrating and working with data from disparate sources. Also supports the use of XML and serialization classes for handling data. A set of .NET Framework libraries that provide essential programming functions, such as string handling, regular expressions, input and output, reflection, collections, and globalization. Provides features to simplify access to remote services and data. This includes a browser object, HTTP request and response object, support for cross-domain HTTP requests, support for RSS/Atom syndication feeds, and support for JSON, POX, and SOAP services. Provides memory management, garbage collection, type safety checking, and exception handling. Provides a rich set of controls, including Button, CheckBox, HyperlinkButton, ListBox, RadioButton, and ScrollViewer. Supports the dynamic compilation and execution of scripting languages such as JavaScript and IronPython to program Silverlight-based applications. Includes a pluggable model for adding support for other languages for use with Silverlight.

Base class library Window Communication Foundation (WCF) CLR (common language runtime) WPF (Windows Presentation Foundation) controls DLR (dynamic language runtime)

The .NET Framework for Silverlight is a subset of the full .NET Framework. It provides the essentials of robust, object-oriented application development for application types (such as Internet applications) for which this support has not traditionally been available. Developers can interact with the .NET Framework for Silverlight layer by writing managed code using C# and Visual Basic. .NET Framework developers can also access the presentation layer by authoring in Visual Studio or Microsoft Expression Blend. Additional Silverlight Programming Features

Silverlight provides several additional features that help developers create rich and interactive applications, including those described in the following table. Feature Isolated storage Asynchronous programming File management HTMLmanaged code interaction Serialization Packaging Description Provides safe access from the Silverlight client to the local computer's file system. Enables local storage and caching of data isolated to a particular user. A background worker thread carries out programming tasks while the application is freed up for user interaction. Provides a safe File Open dialog box, to ease the process of creating safe file uploads. Enables .NET Framework programmers to directly manipulate UI elements in the HTML DOM of a Web page. Web developers can also use JavaScript to call directly into managed code and access scriptable objects, properties, events, and methods. Provides support for serialization of CLR types to JSON and XML. Provides the Application class and build tools to create .xap packages. The .xap package contains the application and entry point for the Silverlight plug-in control to run. XmlReader and XmlWriter classes simplify working with XML data from Web services. The XLinq feature enables developers to query XML data directly within .NET Framework programming languages.

XML libraries

Related Technologies and Tools

The following Microsoft applications include special features for Silverlight development:

Microsoft Expression Blend. This tool can be used to create and modify the presentation layer of an application by manipulating the XAML canvas and controls, working with graphics, and programming the presentation layer with a dynamic language such as JavaScript.

Visual Studio. Visual Studio 2010 provides visual design support for creating Silverlight applications. You can build user interfaces for your applications by dragging controls from the Toolbox and setting properties in the Properties window. You can also edit XAML directly in the XAML view. For more information, see Silverlight Tools and Silverlight Designer for Visual Studio 2010.

Because Silverlight-based applications are executed in a run-time environment on the client machine, no particular application is required to be installed on the server. However, developers may find that their ability to create rich applications that integrate services and data from multiple sources on the server is enhanced by integrating the following types of services and server-side applications into their Silverlight-based applications:

ASP.NET AJAX. This includes a set of controls, services, and libraries for creating rich and interactive Web-based applications. Microsoft Windows Communication Foundation (WCF) services. Internet servers, including Microsoft Internet Information Services (IIS), and the Apache Web server. Internet-based applications and services, including Microsoft ASP.NET, PHP, Windows Streaming Media services, Windows Live services, and other open Web services. See Also

Silverlight Overview Send Feedback on this topic to Microsoft. View this topic online in your default browser.

Microsoft Silverlight is a cross-browser, cross-platform implementation of the .NET Framework for building and delivering the next generation of media experiences and rich interactive applications (RIA) for the Web. You can also create Silverlight applications that run outside of the browser on your desktop. Finally, you use the Silverlight framework to create applications for Windows Phone. Silverlight uses the Extensible Application Markup Language (XAML) to ease UI development (e.g. controls, animations, graphics, layout, etc.) while using managed code or dynamic languages for application logic. This topic contains the following sections.

What Is Silverlight? What Features Are in Silverlight? Running Silverlight Applications Creating Silverlight Applications In This Section Related Topics

What Is Silverlight?

Silverlight enables you to create a state-of-the-art application that has the following features:

It is a cross-browser, cross-platform technology. It runs in all popular Web browsers, including Microsoft Internet Explorer, Mozilla Firefox, and Apple Safari, Google Chrome, and on Microsoft Windows and Apple Mac OS X. It enables you to create Windows Phone applications. To learn more about creating Windows Phone applications with Silverlight, see Windows Phone Development. It is supported by a small download that installs in seconds. It streams video and audio. It scales video quality to everything from mobile devices to desktop browsers to 720p HDTV video modes. It includes compelling graphics that users can manipulatedrag, turn, and zoom directly in the browser. It reads data and updates the display, but it doesn't interrupt the user by refreshing the whole page. The application can run in the Web browser or you can configure it so users can run it on their computer (out-of-browser). In addition, you can use your knowledge of the Silverlight framework to create Windows Phone applications.

Silverlight application with rich graphics and user interaction

You can create Silverlight applications in a variety of ways. You can use Silverlight markup to create media and graphics, and manipulate them with dynamic languages and managed code. Silverlight also enables you to use professional-quality tools like Visual Studio for coding and Microsoft Expression Blend for layout and graphic design. What Features Are in Silverlight?

Silverlight combines multiple technologies into a single development platform that enables you to select the right tools and the right programming language for your needs. Silverlight offers the following features:

WPF and XAML. Silverlight includes a subset of the Windows Presentation Foundation (WPF) technology, which greatly extends the elements in the browser for creating UI. Silverlight lets you create immersive graphics, animation, media, and other rich client features, extending browser-based UI beyond what is available with HTML alone. XAML provides a declarative markup syntax for creating elements. For more

information, see Layout, Input, and Printing, Graphics, Animation, and Media, and Controls. Extensions to JavaScript. Silverlight provides extensions to the universal browser scripting language that provide control over the browser UI, including the ability to work with WPF elements. For more information, see JavaScript API for Silverlight. Cross-browser, cross-platform support. Silverlight runs the same on all popular browsers (and on popular platforms). You can design and develop your application without having to worry about which browser or platform your users have. For more information, see Supported Operating Systems and Browsers. Integration with existing applications. Silverlight integrates seamlessly with your existing JavaScript and ASP.NET AJAX code to complement functionality you have already created. For more information, see Integrating Silverlight with a Web Page. Access to the .NET Framework programming model. You can create Silverlight applications using dynamic languages such as IronPython as well as languages such as C# and Visual Basic. For more information, see Managed API for Silverlight Tools Support. You can use development tools, such as Visual Studio and Expression Blend, to quickly create Silverlight applications. For more information, see Silverlight Designer for Visual Studio 2010 and Expression Blend. Networking support. Silverlight includes support for HTTP over TCP. You can connect to WCF, SOAP, or ASP.NET AJAX services and receive XML, JSON, or RSS data. For more information, see Networking and Web Services. In addition, you can build multicast clients with Silverlight. For more information, see Working with Multicast. LINQ. Silverlight includes language-integrated query (LINQ), which enables you to program data access using intuitive native syntax and strongly typed objects in .NET Framework languages. For more information, see XML Data.

For more details on Silverlight features, see Silverlight Architecture. Running Silverlight Applications

To run a Silverlight web application, users require a small plug-in in their browser. The plug-in is free. If users do not already have the plug-in, they are automatically prompted to install it. The download and installation take seconds and require no interaction from the user except permission to install. Silverlight makes sure that you can run your applications in all modern browsers, without having to create browser-specific code. Silverlight applications can run in the browser or outside the browser. For more information, see Out-of-Browser Support. Creating Silverlight Applications

You can create Silverlight applications using any .NET Framework-supported language (including Visual Basic, C#, and JavaScript). Visual Studio and Expression Blend provide support for developing Silverlight applications. You can create Web pages that use both HTML and WPF elements with Silverlight. Like HTML, XAML enables you to create UI for your Webbased application with declarative syntax, with the difference that XAML provides significantly more powerful elements. For more information, see Getting Started with Silverlight. In This Section Silverlight Feature Introduction History Listed by Version Introduces some of the new features in Silverlight 5. Silverlight Roadmap Provides an introduction to the Silverlight features to help get you started developing Silverlight applications. Silverlight Architecture Describes the architecture of the Silverlight platform, the components of Silverlight, programming features, and related technologies and tools. Supported Operating Systems and Browsers Lists the operating systems and browsers that are supported by Silverlight. About the Silverlight Documentation Explains how to use this documentation. Silverlight Versions and Version Compatibility Describes how to ensure your application will work in different version of Silverlight. Common Language Runtime Describes the features of the managed execution environment (common language runtime) available in Silverlight. WPF Compatibility Provides information for WPF developers on some of the key differences between Silverlight and WPF.

Silverlight Differences on Windows and Macintosh Describes differences in behavior of .NET Framework class library types and methods on a computer running Windows compared to a Macintosh computer. Application and Programming Models Send Feedback on this topic to Microsoft. View this topic online in your default browser.

Most Silverlight-based applications are written in managed code and make use of the Silverlight application model. However, you have the option of using a simplified programming model instead. Silverlight provides the following two distinct models for application development:

The managed API for Silverlight, which uses code running on the common language runtime (CLR) for Silverlight. You can use the managed API with compiled languages such as Visual Basic and C# or dynamic languages such as IronPython and IronRuby. For more information about dynamic languages, see Silverlight Dynamic Languages SDK. The JavaScript API for Silverlight, which uses JavaScript code interpreted by the browser.

These programming models are distinct because you cannot use them both at the same time within a single instance of the Silverlight plug-in. However, you can implement a splash screen that uses the JavaScript API and then transitions to the managed API when your application has loaded. The managed API provides significantly more functionality than the JavaScript API, and is the subject of most of the Silverlight documentation. Applications that use the managed API have access to a lightweight version of the .NET Framework. The JavaScript API, however, has access only to the Silverlight presentation core and the browser JavaScript engine. For more information about the functionality provided by the .NET Framework and the Silverlight presentation core, see Silverlight Architecture. Managed Programming and the Application Model

The managed API enables you to bundle managed assemblies and resource files into application package (.xap) files. The Silverlight plug-in is responsible for loading an application package and extracting its contents.

An application package must contain an assembly with a class derived from Application. The Application class encapsulates the interaction between your application and the Silverlight plugin. For example, it enables you to display a user interface within the host Web page. Additionally, it provides application lifetime events and resource management. The Silverlight documentation uses the term application model to refer to application packaging and the common functionality encapsulated by the Application class. The application model helps you to develop both simple applications and complex, extensible applications that can share resources across a network. For more information, see Application Model. The application model topics provide guidance on designing applications to enable several common scenarios, such as on-demand resource loading, download progress indication, and navigation. The Managed API

You can use XAML markup to encapsulate your user interface (UI) designs in both the managed API and the JavaScript API. With the managed API, however, you can factor your application code into multiple XAML files and accompanying code-behind files. When the Silverlight plug-in loads XAML files, it creates an object tree that your code-behind can manipulate. Your managed application code can also manipulate the HTML Document Object Model (DOM) through the HTML Bridge. For information about how managed code interacts with XAML and HTML, see Managed API for Silverlight. The JavaScript API

The JavaScript API is the model that was available in Silverlight 1.0, and is retained for backward compatibility and to enable particular scenarios. In the JavaScript API, the Silverlight plug-in loads a single XAML page instead of an application package. This XAML can include URI references to server-side resources, such as images and videos. The Silverlight plug-in uses the XAML to create an object tree that you can programmatically manipulate using JavaScript in the host HTML page. The JavaScript API does not provide an application model that is capable of supporting complex applications with internal navigation. However, it does enable scenarios for which the managed API is too cumbersome, such as splash screens. You can also implement basic navigation by loading new XAML pages into the Silverlight plug-in or by loading new Web pages into the browser.

For more information, see JavaScript API for Silverlight. JavaScript and the HTML DOM

Both the managed API and JavaScript API enable you to use JavaScript in the host HTML page to integrate Silverlight with the HTML Document Object Model (DOM). In the JavaScript API, you must implement most of your application functionality using browserinterpreted JavaScript, which can interact directly with the DOM. In the managed API, your JavaScript and DOM code interacts with the Silverlight plug-in and the application model by using the HTML Bridge. For more information, see Silverlight Programming Models, XAML, and the HTML DOM and HTML Bridge: Interaction Between HTML and Managed Code. Using Multiple Silverlight Plug-ins in a Web Page

One reason to use the HTML Bridge feature is to create Web pages that integrate Silverlight with other HTML-based content. You can also use the HTML DOM to integrate multiple Silverlightbased applications in a single page. However, in this case, Silverlight provides built-in support for communicating between multiple Silverlight plug-ins, called local messaging. Local messaging enables you to send messages from one Silverlight-based application to another one running on the same computer. This enables you to create Silverlight content that spans multiple plug-ins, such as an animation that crosses from a banner to a sidebar. For more information, see Communication Between Local Silverlight-Based Applications. Using Silverlight Outside the Browser

Silverlight provides built-in support for running managed applications outside the browser. After you configure an application for out-of-browser support, users can install it from its host Web page. After installation, users can run the application without a browser or even a network connection. You can configure applications for out-of-browser support without modifying any application code. Alternately, you can implement additional support for out-of-browser mode, such as offline caching and automatic updates. For more information, see Out-of-Browser Support. In Silverlight 4 and later, you can configure out-of-browser applications to require elevated trust. These trusted applications can bypass some of the restrictions of the Silverlight security sandbox and integrate with native functionality. In Silverlight 5 and later, system administrators can also

enable trusted applications to run inside the browser. For more information, see Trusted Applications. You can also use the Silverlight plug-in in other environments. However, in this case, there is no built-in support. The easiest way to integrate Silverlight with another technology is to host the Silverlight plug-in within a browser control. You can then host the browser control within the other technology. More complex hosting options involve the use of unmanaged code and COM interfaces. If you need the functionality of Silverlight in a desktop application, you should consider using Windows Presentation Foundation (WPF). For more information about using Silverlight in other environments, see Alternative Hosting. See Also

The examples in this section use the generic List< T> class, which enables you to work with a strongly typed list of objects. The following example creates a list of strings and then iterates through the strings by using a For EachNext (Visual Basic) or foreach (C#) statement. JavaScript C# C++ F# JScript VB Copy to Clipboard
// Create a list of strings. var salmons = new List<string>(); salmons.Add("chinook"); salmons.Add("coho"); salmons.Add("pink"); salmons.Add("sockeye"); // Iterate through the list. foreach (var salmon in salmons) { Console.Write(salmon + " "); } // Output: chinook coho pink sockeye

If the contents of a collection are known in advance, you can use a collection initializer to initialize the collection. For more information, see Collection Initializers (Visual Basic) or Object and Collection Initializers (C# Programming Guide). The following example is the same as the previous example, except a collection initializer is used to add elements to the collection.

JavaScript C# C++ F# JScript VB Copy to Clipboard


// Create a list of strings by using a // collection initializer. var salmons = new List<string> { "chinook", "coho", "pink", "sockeye" }; // Iterate through the list. foreach (var salmon in salmons) { Console.Write(salmon + " "); } // Output: chinook coho pink sockeye

You can use a ForNext (Visual Basic) or for (C#) statement instead of a For Each statement to iterate through a collection. You accomplish this by accessing the collection elements by the index position. The index of the elements starts at 0 and ends at the element count minus 1. The following example iterates through the elements of a collection by using ForNext instead of For Each. JavaScript C# C++ F# JScript VB Copy to Clipboard
// Create a list of strings by using a // collection initializer. var salmons = new List<string> { "chinook", "coho", "pink", "sockeye" }; for (var index = 0; index < salmons.Count; index++) { Console.Write(salmons[index] + " "); } // Output: chinook coho pink sockeye

The following example removes an element from the collection by specifying the object to remove. JavaScript C# C++ F# JScript

VB Copy to Clipboard
// Create a list of strings by using a // collection initializer. var salmons = new List<string> { "chinook", "coho", "pink", "sockeye" }; // Remove an element from the list by specifying // the object. salmons.Remove("coho"); // Iterate through the list. foreach (var salmon in salmons) { Console.Write(salmon + " "); } // Output: chinook pink sockeye

The following example removes elements from a generic list. Instead of a For Each statement, a ForNext (Visual Basic) or for (C#) statement that iterates in descending order is used. This is because the RemoveAt method causes elements after a removed element to have a lower index value. JavaScript C# C++ F# JScript VB Copy to Clipboard
var numbers = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // Remove odd numbers. for (var index = numbers.Count - 1; index >= 0; index--) { if (numbers[index] % 2 == 1) { // Remove the element by specifying // the zero-based index in the list. numbers.RemoveAt(index); } } // Iterate through the list. // A lambda expression is placed in the ForEach method // of the List(T) object. numbers.ForEach( number => Console.Write(number + " ")); // Output: 0 2 4 6 8

For the type of elements in the List< T> , you can also define your own class. In the following example, theGalaxy class that is used by the List< T> is defined in the code.

JavaScript C# C++ F# JScript VB Copy to Clipboard


private void IterateThroughList() { var theGalaxies = new List<Galaxy> { new Galaxy() { Name="Tadpole", MegaLightYears=400}, new Galaxy() { Name="Pinwheel", MegaLightYears=25}, new Galaxy() { Name="Milky Way", MegaLightYears=0}, new Galaxy() { Name="Andromeda", MegaLightYears=3} }; foreach (Galaxy theGalaxy in theGalaxies) { Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears); } // Output: // Tadpole 400 // Pinwheel 25 // Milky Way 0 // Andromeda 3 } public class Galaxy { public string Name { get; set; } public int MegaLightYears { get; set; } }

Kinds of Collections

Many common collections are provided by the .NET Framework. Each type of collection is designed for a specific purpose. The following groups of collection classes are described in this section:

System.Collections.Generic classes System.Collections.Concurrent classes System.Collections classes Visual Basic Collection class System.Collections.Generic Classes

You can create a generic collection by using one of the classes in the System.Collections.Generic namespace. A generic collection is useful when every item in the collection has the same data type. A generic collection enforces strong typing by allowing only the desired data type to be added. The following table lists some of the frequently used classes of the System.Collections.Generic namespace: Class Dictionary< TKey, TValue> List< T> Queue< T> SortedList< TKey, TValue> Stack< T> Description Represents a collection of key/value pairs that are organized based on the key. Represents a list of objects that can be accessed by index. Provides methods to search, sort, and modify lists. Represents a first in, first out (FIFO) collection of objects. Represents a collection of key/value pairs that are sorted by key based on the associated IComparer< T> implementation. Represents a last in, first out (LIFO) collection of objects.

For additional information, see Commonly Used Collection Types, Selecting a Collection Class, and System.Collections.Generic. System.Collections.Concurrent Classes

In the .NET Framework 4, the collections in the System.Collections.Concurrent namespace provide efficient thread-safe operations for accessing collection items from multiple threads. The classes in the System.Collections.Concurrent namespace should be used instead of the corresponding types in the System.Collections.Generic and System.Collections namespaces whenever multiple threads are accessing the collection concurrently. For more information, see Thread-Safe Collections and System.Collections.Concurrent. Some classes included in the System.Collections.Concurrent namespace are BlockingCollection< T> , ConcurrentDictionary< TKey, TValue> , ConcurrentQueue< T> , and ConcurrentStack< T> . System.Collections Classes

The classes in the System.Collections namespace do not store elements as specifically typed objects, but as objects of type Object.

Whenever possible, you should use the generic collections in the System.Collections.Generic namespace or the System.Collections.Concurrent namespace instead of the legacy types in the System.Collections namespace. The following table lists some of the frequently used classes in the System.Collections namespace: Class Description ArrayList Represents an array of objects whose size is dynamically increased as required. Represents a collection of key/value pairs that are organized based on the hash code of Hashtable the key. Queue Represents a first in, first out (FIFO) collection of objects. Stack Represents a last in, first out (LIFO) collection of objects. The System.Collections.Specialized namespace provides specialized and strongly typed collection classes, such as string-only collections and linked-list and hybrid dictionaries. Visual Basic Collection Class

You can use the Visual Basic Collection class to access a collection item by using either a numeric index or a String key. You can add items to a collection object either with or without specifying a key. If you add an item without a key, you must use its numeric index to access it. The Visual Basic Collection class stores all its elements as type Object, so you can add an item of any data type. There is no safeguard against inappropriate data types being added. When you use the Visual Basic Collection class, the first item in a collection has an index of 1. This differs from the .NET Framework collection classes, for which the starting index is 0. Whenever possible, you should use the generic collections in the System.Collections.Generic namespace or the System.Collections.Concurrent namespace instead of the Visual Basic Collection class. For more information, see Collection. Implementing a Collection of Key/Value Pairs

The Dictionary< TKey, TValue> generic collection enables you to access to elements in a collection by using the key of each element. Each addition to the dictionary consists of a value and its associated key. Retrieving a value by using its key is fast because theDictionary class is implemented as a hash table.

The following example creates a Dictionary collection and iterates through the dictionary by using a For Each statement. JavaScript C# C++ F# JScript VB Copy to Clipboard
private void IterateThruDictionary() { Dictionary<string, Element> elements = BuildDictionary(); foreach (KeyValuePair<string, Element> kvp in elements) { Element theElement = kvp.Value; Console.WriteLine("key: " + kvp.Key); Console.WriteLine("values: " + theElement.Symbol + " " + theElement.Name + " " + theElement.AtomicNumber); } } private Dictionary<string, Element> BuildDictionary() { var elements = new Dictionary<string, Element>(); AddToDictionary(elements, AddToDictionary(elements, AddToDictionary(elements, AddToDictionary(elements, return elements; } private void AddToDictionary(Dictionary<string, Element> elements, string symbol, string name, int atomicNumber) { Element theElement = new Element(); theElement.Symbol = symbol; theElement.Name = name; theElement.AtomicNumber = atomicNumber; elements.Add(key: theElement.Symbol, value: theElement); } public class Element { public string Symbol { get; set; } public string Name { get; set; } public int AtomicNumber { get; set; } } "K", "Potassium", 19); "Ca", "Calcium", 20); "Sc", "Scandium", 21); "Ti", "Titanium", 22);

To instead use a collection initializer to build the Dictionary collection, you can replace the BuildDictionary and AddToDictionary methods with the following method. JavaScript C# C++ F# JScript VB Copy to Clipboard
private Dictionary<string, Element> BuildDictionary2() { return new Dictionary<string, Element> { {"K", new Element() { Symbol="K", Name="Potassium", AtomicNumber=19}}, {"Ca", new Element() { Symbol="Ca", Name="Calcium", AtomicNumber=20}}, {"Sc", new Element() { Symbol="Sc", Name="Scandium", AtomicNumber=21}}, {"Ti", new Element() { Symbol="Ti", Name="Titanium", AtomicNumber=22}} }; }

The following example uses the ContainsKey method and the Item property of Dictionary to quickly find an item by key. The Item property enables you to access an item in the elements collection by using the elements(symbol) code in Visual Basic, or elements[symbol] in C#. JavaScript C# C++ F# JScript VB Copy to Clipboard
private void FindInDictionary(string symbol) { Dictionary<string, Element> elements = BuildDictionary(); if (elements.ContainsKey(symbol) == false) { Console.WriteLine(symbol + " not found"); } else { Element theElement = elements[symbol]; Console.WriteLine("found: " + theElement.Name); } }

The following example instead uses the TryGetValue method quickly find an item by key. JavaScript C# C++ F# JScript VB Copy to Clipboard
private void FindInDictionary2(string symbol) { Dictionary<string, Element> elements = BuildDictionary(); Element theElement = null; if (elements.TryGetValue(symbol, out theElement) == false) Console.WriteLine(symbol + " not found"); else Console.WriteLine("found: " + theElement.Name); }

Using LINQ to Access a Collection

LINQ (Language-Integrated Query) can be used to access collections. LINQ queries provide filtering, ordering, and grouping capabilities. For more information, see Getting Started with LINQ in Visual Basic or Getting Started with LINQ in C#. The following example runs a LINQ query against a generic List. The LINQ query returns a different collection that contains the results. JavaScript C# C++ F# JScript VB Copy to Clipboard
private void ShowLINQ() { List<Element> elements = BuildList(); // LINQ Query. var subset = from theElement in elements where theElement.AtomicNumber < 22 orderby theElement.Name select theElement; foreach (Element theElement in subset) { Console.WriteLine(theElement.Name + " " + theElement.AtomicNumber); }

// Output: // Calcium 20 // Potassium 19 // Scandium 21 } private List<Element> BuildList() { return new List<Element> { { new Element() { Symbol="K", Name="Potassium", AtomicNumber=19}}, { new Element() { Symbol="Ca", Name="Calcium", AtomicNumber=20}}, { new Element() { Symbol="Sc", Name="Scandium", AtomicNumber=21}}, { new Element() { Symbol="Ti", Name="Titanium", AtomicNumber=22}} }; } public class Element { public string Symbol { get; set; } public string Name { get; set; } public int AtomicNumber { get; set; } }

Sorting a Collection

The following example illustrates a procedure for sorting a collection. The example sorts instances of the Car class that are stored in a List< T> . TheCar class implements the IComparable< T> interface, which requires that the CompareTo method be implemented. Each call to the CompareTo method makes a single comparison that is used for sorting. Userwritten code in the CompareTo method returns a value for each comparison of the current object with another object. The value returned is less than zero if the current object is less than the other object, greater than zero if the current object is greater than the other object, and zero if they are equal. This enables you to define in code the criteria for greater than, less than, and equal. In the ListCars method, the cars.Sort() statement sorts the list. This call to the Sort method of the List< T> causes theCompareTo method to be called automatically for the Car objects in the List. JavaScript C# C++ F# JScript VB Copy to Clipboard
private void ListCars()

{ var cars = new List<Car> { { new Car() { Name = { new Car() { Name = { new Car() { Name = { new Car() { Name = { new Car() { Name = { new Car() { Name = { new Car() { Name = }; "car1", "car2", "car3", "car4", "car5", "car6", "car7", Color Color Color Color Color Color Color = = = = = = = "blue", Speed = 20}}, "red", Speed = 50}}, "green", Speed = 10}}, "blue", Speed = 50}}, "blue", Speed = 30}}, "red", Speed = 60}}, "green", Speed = 50}}

// Sort the cars by color alphabetically, and then by speed // in descending order. cars.Sort(); // View all of the cars. foreach (Car thisCar in cars) { Console.Write(thisCar.Color.PadRight(5) + " "); Console.Write(thisCar.Speed.ToString() + " "); Console.Write(thisCar.Name); Console.WriteLine(); } // Output: // blue 50 car4 // blue 30 car5 // blue 20 car1 // green 50 car7 // green 10 car3 // red 60 car6 // red 50 car2 } public class Car : IComparable<Car> { public string Name { get; set; } public int Speed { get; set; } public string Color { get; set; } public int CompareTo(Car other) { // A call to this method makes a single comparison that is // used for sorting. // Determine the relative order of the objects being compared. // Sort by color alphabetically, and then by speed in // descending order. // Compare the colors. int compare; compare = String.Compare(this.Color, other.Color, true); // If the colors are the same, compare the speeds. if (compare == 0) {

compare = this.Speed.CompareTo(other.Speed); // Use descending order for speed. compare = -compare; } return compare; } }

Defining a Custom Collection

You can define a collection by implementing the IEnumerable< T> or IEnumerable interface. For additional information, see Enumerating a Collection and How to: Access a Collection Class with foreach (C# Programming Guide). Although you can define a custom collection, it is usually better to instead use the collections that are included in the .NET Framework, which are described in Kinds of Collections earlier in this topic. The following example defines a custom collection class named AllColors. This class implements the IEnumerable interface, which requires that the GetEnumerator method be implemented. The GetEnumerator method returns an instance of the ColorEnumerator class. ColorEnumerator implements the IEnumerator interface, which requires that the Current property, MoveNext method, and Reset method be implemented. JavaScript C# C++ F# JScript VB Copy to Clipboard
private void ListColors() { var colors = new AllColors(); foreach (Color theColor in colors) { Console.Write(theColor.Name + " "); } Console.WriteLine(); // Output: red blue green } // Collection class. public class AllColors : System.Collections.IEnumerable

{ Color[] { new new new }; _colors = Color() { Name = "red" }, Color() { Name = "blue" }, Color() { Name = "green" }

public System.Collections.IEnumerator GetEnumerator() { return new ColorEnumerator(_colors); // Instead of creating a custom enumerator, you could // use the GetEnumerator of the array. //return _colors.GetEnumerator(); } // Custom enumerator. private class ColorEnumerator : System.Collections.IEnumerator { private Color[] _colors; private int _position = -1; public ColorEnumerator(Color[] colors) { _colors = colors; } object System.Collections.IEnumerator.Current { get { return _colors[_position]; } } bool System.Collections.IEnumerator.MoveNext() { _position++; return (_position < _colors.Length); } void System.Collections.IEnumerator.Reset() { _position = -1; } } } // Element class. public class Color { public string Name { get; set; } }

Iterators

An iterator is used to perform a custom iteration over a collection. An iterator can be a method or a get accessor. An iterator uses a Yield (Visual Basic) or yield return (C#) statement to return each element of the collection one at a time. You call an iterator by using a For EachNext (Visual Basic) or foreach (C#) statement. Each iteration of the For Each loop calls the iterator. When a Yield or yield return statement is reached in the iterator, an expression is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator is called. For more information, see Iterators (C# and Visual Basic). The following example uses an iterator method. The iterator method has a Yield or yield return statement that is inside a ForNext (Visual Basic) or for (C#) loop. In the ListEvenNumbers method, each iteration of the For Each statement body creates a call to the iterator method, which proceeds to the next Yield or yield return statement. JavaScript C# C++ F# JScript VB Copy to Clipboard
private void ListEvenNumbers() { foreach (int number in EvenSequence(5, 18)) { Console.Write(number.ToString() + " "); } Console.WriteLine(); // Output: 6 8 10 12 14 16 18 } private static IEnumerable<int> EvenSequence( int firstNumber, int lastNumber) { // Yield even numbers in the range. for (var number = firstNumber; number <= lastNumber; number++) { if (number % 2 == 0) { yield return number; } } }

How to: Access a Collection Class with foreach (C# Programming Guide)

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

The following code example illustrates how to write a non-generic collection class that can be used with foreach. The example defines a string tokenizer class.

Note This example represents recommended practice only when you cannot use a generic collection class. For an example of how to implement a type-safe generic collection class that supports IEnumerable< T> , see Iterators (C# and Visual Basic). In the example, the following code segment uses the Tokens class to break the sentence "This is a sample sentence." into tokens by using ' ' and '-' as separators. The code then displays those tokens by using a foreach statement. JavaScript C# C++ F# JScript VB Copy to Clipboard
Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'}); // Display the tokens. foreach (string item in f) { System.Console.WriteLine(item); }

Example

Internally, the Tokens class uses an array to store the tokens. Because arrays implement IEnumerator and IEnumerable, the code example could have used the array's enumeration methods ( GetEnumerator, MoveNext, Reset, and Current) instead of defining them in the Tokens class. The method definitions are included in the example to clarify how they are defined and what each does. JavaScript C# C++ F# JScript VB

Copy to Clipboard
using System.Collections; // Declare the Tokens class. The class implements the IEnumerable interface. public class Tokens : IEnumerable { private string[] elements; Tokens(string source, char[] delimiters) { // The constructor parses the string argument into tokens. elements = source.Split(delimiters); } // The IEnumerable interface requires implementation of method GetEnumerator. public IEnumerator GetEnumerator() { return new TokenEnumerator(this); } // Declare an inner class that implements the IEnumerator interface. private class TokenEnumerator : IEnumerator { private int position = -1; private Tokens t; public TokenEnumerator(Tokens t) { this.t = t; } // The IEnumerator interface requires a MoveNext method. public bool MoveNext() { if (position < t.elements.Length - 1) { position++; return true; } else { return false; } } // The IEnumerator interface requires a Reset method. public void Reset() { position = -1; } // The IEnumerator interface requires a Current method. public object Current {

get { return t.elements[position]; } } } // Test the Tokens class. static void Main() { // Create a Tokens instance. Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'}); // Display the tokens. foreach (string item in f) { System.Console.WriteLine(item); } } } /* Output: This is a sample sentence. */

In C#, it is not necessary for a collection class to implement IEnumerable and IEnumerator to be compatible with foreach. If the class has the required GetEnumerator, MoveNext, Reset, and Current members, it will work with foreach. Omitting the interfaces has the advantage of enabling you to define a return type for Current that is more specific than Object. This provides type safety. For example, change the following lines in the previous example. JavaScript C# C++ F# JScript VB Copy to Clipboard
// Change the Tokens class so that it no longer implements IEnumerable. public class Tokens { // . . . // Change the return type for the GetEnumerator method. public TokenEnumerator GetEnumerator() { }

// Change TokenEnumerator so that it no longer implements IEnumerator. public class TokenEnumerator { // . . . // Change the return type of method Current to string. public string Current { } } }

Because Current returns a string, the compiler can detect when an incompatible type is used in a foreach statement, as shown in the following code. JavaScript C# C++ F# JScript VB Copy to Clipboard
// Error: Cannot convert type string to int. foreach (int item in f)

The disadvantage of omitting IEnumerable and IEnumerator is that the collection class is no longer interoperable with the foreach statements, or equivalent statements, of other common language runtime languages. See Also Arrays (C# Programming Guide) Send Feedback on this topic to Microsoft. View this topic online in your default browser.

An array is a data structure that contains several variables of the same type. An array is declared with a type: type[] arrayName; The following examples create single-dimensional, multidimensional, and jagged arrays: JavaScript C# C++ F# JScript

VB Copy to Clipboard
class TestArraysClass { static void Main() { // Declare a single-dimensional array int[] array1 = new int[5]; // Declare and set array element values int[] array2 = new int[] { 1, 3, 5, 7, 9 }; // Alternative syntax int[] array3 = { 1, 2, 3, 4, 5, 6 }; // Declare a two dimensional array int[,] multiDimensionalArray1 = new int[2, 3]; // Declare and set array element values int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } }; // Declare a jagged array int[][] jaggedArray = new int[6][]; // Set the values of the first array in the jagged array structure jaggedArray[0] = new int[4] { 1, 2, 3, 4 }; } }

Array Overview

An array has the following properties:


An array can be Single-Dimensional, Multidimensional or Jagged. The default value of numeric array elements are set to zero, and reference elements are set to null. A jagged array is an array of arrays, and therefore its elements are reference types and are initialized to null. Arrays are zero indexed: an array with n elements is indexed from 0 to n-1. Array elements can be of any type, including an array type. Array types are reference types derived from the abstract base type Array. Since this type implements IEnumerable and IEnumerable< T> , you can useforeach iteration on all arrays in C#. Related Sections

Arrays as Objects (C# Programming Guide) Using foreach with Arrays (C# Programming Guide)

Passing Arrays as Arguments (C# Programming Guide) Passing Arrays Using ref and out (C# Programming Guide) More About Variables in C# Language Specification Beginning Visual C# 2010

For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage. See Also
Arrays as Objects (C# Programming Guide)

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

In C#, arrays are actually objects, and not just addressable regions of contiguous memory as in C and C++. Array is the abstract base type of all array types. You can use the properties, and other class members, that Array has. An example of this would be using the Length property to get the length of an array. The following code assigns the length of the numbers array, which is 5, to a variable called lengthOfNumbers:
JavaScript C# C++ F# JScript VB Copy to Clipboard
int[] numbers = { 1, 2, 3, 4, 5 }; int lengthOfNumbers = numbers.Length;

The Array class provides many other useful methods and properties for sorting, searching, and copying arrays.

Example

This example uses the Rank property to display the number of dimensions of an array.
JavaScript C# C++ F# JScript VB Copy to Clipboard
class TestArraysClass { static void Main() { // Declare and initialize an array: int[,] theArray = new int[5, 10]; System.Console.WriteLine("The array has {0} dimensions.", theArray.Rank); } } // Output: The array has 2 dimensions.

See Also

Reference
Multidimensional Arrays (C# Programming Guide)

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

Arrays can have more than one dimension. For example, the following declaration creates a twodimensional array of four rows and two columns.
JavaScript

C# C++ F# JScript VB Copy to Clipboard


int[,] array = new int[4, 2];

The following declaration creates an array of three dimensions, 4, 2, and 3.


JavaScript C# C++ F# JScript VB Copy to Clipboard
int[, ,] array1 = new int[4, 2, 3];

Array Initialization

You can initialize the array upon declaration, as is shown in the following example.
JavaScript C# C++ F# JScript VB

Copy to Clipboard
// Two-dimensional array. int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // The same array with dimensions specified. int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // A similar array with string elements. string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" }, { "five", "six" } }; // Three-dimensional array. int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } }; // The same array with dimensions specified. int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } }; // Accessing array elements. System.Console.WriteLine(array2D[0, 0]); System.Console.WriteLine(array2D[0, 1]); System.Console.WriteLine(array2D[1, 0]); System.Console.WriteLine(array2D[1, 1]); System.Console.WriteLine(array2D[3, 0]); System.Console.WriteLine(array2Db[1, 0]); System.Console.WriteLine(array3Da[1, 0, 1]); System.Console.WriteLine(array3D[1, 1, 2]); // // // // // // // // // Output: 1 2 3 4 7 three 8 12

You also can initialize the array without specifying the rank.
JavaScript C# C++ F# JScript VB Copy to Clipboard

int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

If you choose to declare an array variable without initialization, you must use the new operator to assign an array to the variable. The use of new is shown in the following example.
JavaScript C# C++ F# JScript VB Copy to Clipboard
int[,] array5; array5 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; //array5 = {{1,2}, {3,4}, {5,6}, {7,8}}; // Error // OK

The following example assigns a value to a particular array element.


JavaScript C# C++ F# JScript VB Copy to Clipboard
array5[2, 1] = 25;

Similarly, the following example gets the value of a particular array element and assigns it to variable elementValue.
JavaScript C# C++

F# JScript VB Copy to Clipboard


int elementValue = array5[2, 1];

The following code example initializes the array elements to default values (except for jagged arrays).
JavaScript C# C++ F# JScript VB Copy to Clipboard
int[,] array6 = new int[10, 10];

See Also

Reference Classes and Structs (C# Programming Guide) Send Feedback on this topic to Microsoft. View this topic online in your default browser.

Classes and structs are two of the basic constructs of the common type system in the .NET Framework. Each is essentially a data structure that encapsulates a set of data and behaviors that belong together as a logical unit. The data and behaviors are the members of the class or struct, and they include its methods, properties, and events, and so on, as listed later in this topic. A class or struct declaration is like a blueprint that is used to create instances or objects at run time. If you define a class or struct called Person, Person is the name of the type. If you declare

and initialize a variable p of type Person, p is said to be an object or instance of Person. Multiple instances of the same Person type can be created, and each instance can have different values in its properties and fields. A class is a reference type. When an object of the class is created, the variable to which the object is assigned holds only a reference to that memory. When the object reference is assigned to a new variable, the new variable refers to the original object. Changes made through one variable are reflected in the other variable because they both refer to the same data. A struct is a value type. When a struct is created, the variable to which the struct is assigned holds the struct's actual data. When the struct is assigned to a new variable, it is copied. The new variable and the original variable therefore contain two separate copies of the same data. Changes made to one copy do not affect the other copy. In general, classes are used to model more complex behavior, or data that is intended to be modified after a class object is created. Structs are best suited for small data structures that contain primarily data that is not intended to be modified after the struct is created. For more information, see Classes (C# Programming Guide), Objects (C# Programming Guide), and Structs (C# Programming Guide). Example

In the following example, MyCustomClass is defined with three members at the top level of the ProgrammingGuide namespace. An instance (object) of MyCustomClass is created in the Main method in the Program class, and the objects methods and properties are accessed by using dot notation. JavaScript C# C++ F# JScript VB Copy to Clipboard
namespace ProgrammingGuide { // Class definition. public class MyCustomClass { // Class members: // Property. public int Number { get; set; } // Method. public int Multiply(int num) {

return num * Number; } // Instance Constructor. public MyCustomClass() { Number = 0; } } // Another class definition. This one contains // the Main method, the entry point for the program. class Program { static void Main(string[] args) { // Create an object of type MyCustomClass. MyCustomClass myClass = new MyCustomClass(); // Set the value of a public property. myClass.Number = 27; // Call a public method. int result = myClass.Multiply(4); } } }

Encapsulation

Encapsulation is sometimes referred to as the first pillar or principle of object-oriented programming. According to the principle of encapsulation, a class or struct can specify how accessible each of its members is to code outside of the class or struct. Methods and variables that are not intended to be used from outside of the class or assembly can be hidden to limit the potential for coding errors or malicious exploits. For more information about classes, see Classes (C# Programming Guide) and Objects (C# Programming Guide). Members

All methods, fields, constants, properties, and events must be declared within a type; these are called the members of the class or struct. In C#, there are no global variables or methods as there are in some other languages. Even a program's entry point, the Main method, must be declared within a class or struct. The following list includes all the various kinds of members that may be declared in a class or struct.

Fields Constants

Properties Methods Constructors Destructors Events Indexers Operators Nested Types Accessibility

Some methods and properties are meant to be called or accessed from code outside your class or struct, known as client code. Other methods and properties might be only for use in the class or struct itself. It is important to limit the accessibility of your code so that only the intended client code can reach it. You specify how accessible your types and their members are to client code by using the access modifiers public, protected, internal, protected internal, and private. The default accessibility is private. For more information, see Access Modifiers (C# Programming Guide). Inheritance

Classes (but not structs) support the concept of inheritance. A class that derives from another class (the base class) automatically contains all the public, protected, and internal members of the base class except its constructors and destructors. For more information, see Inheritance (C# Programming Guide) and Polymorphism (C# Programming Guide). Classes may be declared as abstract, which means that one or more of their methods have no implementation. Although abstract classes cannot be instantiated directly, they can serve as base classes for other classes that provide the missing implementation. Classes can also be declared as sealed to prevent other classes from inheriting from them. For more information, see Abstract and Sealed Classes and Class Members (C# Programming Guide). Interfaces

Classes and structs can inherit multiple interfaces. To inherit from an interface means that the type implements all the methods defined in the interface. For more information, see Interfaces (C# Programming Guide). Generic Types

Classes and structs can be defined with one or more type parameters. Client code supplies the type when it creates an instance of the type. For example The List< T> class in the System.Collections.Generic namespace is defined with one type parameter. Client code creates an instance of a List<string> or List<int> to specify the type that the list will hold. For more information, see Generics (C# Programming Guide). Static Types

Classes (but not structs) can be declared as static. A static class can contain only static members and cannot be instantiated with the new keyword. One copy of the class is loaded into memory when the program loads, and its members are accessed through the class name. Both classes and structs can contain static members. For more information, see Static Classes and Static Class Members (C# Programming Guide). Nested Types

A class or struct can be nested within another class or struct. For more information, see Nested Types. Partial Types

You can define part of a class, struct or method in one code file and another part in a separate code file. For more information, see Partial Classes and Methods. Object Initializers

You can instantiate and initialize class or struct objects, and collections of objects, without explicitly calling their constructor. For more information, see Object and Collection Initializers (C# Programming Guide). Anonymous Types

In situations where it is not convenient or necessary to create a named class, for example when you are populating a list with data structures that you do not have to persist or pass to another method, you use anonymous types. For more information, see Anonymous Types (C# Programming Guide).

Extension Methods

You can "extend" a class without creating a derived class by creating a separate type whose methods can be called as if they belonged to the original type. For more information, see Extension Methods (C# Programming Guide). Implicitly Typed Local Variables

Within a class or struct method, you can use implicit typing to instruct the compiler to determine the correct type at compile time. For more information, see Implicitly Typed Local Variables (C# Programming Guide). C# Language Specification

For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage. See Also

Concepts Implicitly Typed Local Variables (C# Programming Guide) Send Feedback on this topic to Microsoft. View this topic online in your default browser.

Local variables can be given an inferred "type" of var instead of an explicit type. The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement. The inferred type may be a built-in type, an anonymous type, a user-defined type, or a type defined in the .NET Framework class library. For more information about how to initialize arrays with var, see Implicitly Typed Arrays (C# Programming Guide). The following examples show various ways in which local variables can be declared with var: JavaScript C# C++

F# JScript VB Copy to Clipboard


// i is compiled as an int var i = 5; // s is compiled as a string var s = "Hello"; // a is compiled as int[] var a = new[] { 0, 1, 2 }; // expr is compiled as IEnumerable<Customer> // or perhaps IQueryable<Customer> var expr = from c in customers where c.City == "London" select c; // anon is compiled as an anonymous type var anon = new { Name = "Terry", Age = 34 }; // list is compiled as List<int> var list = new List<int>();

It is important to understand that the var keyword does not mean "variant" and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type. The var keyword may be used in the following contexts:

On local variables (variables declared at method scope) as shown in the previous example. In a for initialization statement. Copy to Clipboard
for(var x = 1; x < 10; x++)

In a foreach initialization statement. Copy to Clipboard


foreach(var item in list){...}

In a using statement. Copy to Clipboard


using (var file = new StreamReader("C:\\myfile.txt")) {...}

For more information, see How to: Use Implicitly Typed Local Variables and Arrays in a Query Expression (C# Programming Guide). var and Anonymous Types

In many cases the use of var is optional and is just a syntactic convenience. However, when a variable is initialized with an anonymous type you must declare the variable as var if you need to access the properties of the object at a later point. This is a common scenario in LINQ query expressions. For more information, see Anonymous Types (C# Programming Guide). From the perspective of your source code, an anonymous type has no name. Therefore, if a query variable has been initialized with var, then the only way to access the properties in the returned sequence of objects is to use var as the type of the iteration variable in the foreach statement. JavaScript C# C++ F# JScript VB Copy to Clipboard
class ImplicitlyTypedLocals2 { static void Main() { string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" }; // If a query produces a sequence of anonymous types, // then use var in the foreach statement to access the properties. var upperLowerWords = from w in words select new { Upper = w.ToUpper(), Lower = w.ToLower() }; // Execute the query foreach (var ul in upperLowerWords) { Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower); } } } /* Outputs: Uppercase: APPLE, Lowercase: apple

Uppercase: BLUEBERRY, Lowercase: blueberry Uppercase: CHERRY, Lowercase: cherry */

Remarks

The following restrictions apply to implicitly-typed variable declarations:

var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function. var cannot be used on fields at class scope. Variables declared by using var cannot be used in the initialization expression. In other words, this expression is legal: int i = (i = 20); but this expression produces a compiletime error: var i = (i = 20); Multiple implicitly-typed variables cannot be initialized in the same statement. If a type named var is in scope, then the var keyword will resolve to that type name and will not be treated as part of an implicitly typed local variable declaration.

You may find that var can also be useful with query expressions in which the exact constructed type of the query variable is difficult to determine. This can occur with grouping and ordering operations. The var keyword can also be useful when the specific type of the variable is tedious to type on the keyboard, or is obvious, or does not add to the readability of the code. One example where var is helpful in this manner is with nested generic types such as those used with group operations. In the following query, the type of the query variable is IEnumerable<IGrouping<string, Student>>. As long as you and others who must maintain your code understand this, there is no problem with using implicit typing for convenience and brevity. JavaScript C# C++ F# JScript VB Copy to Clipboard
// Same as previous example except we use the entire last name as a key. // Query variable is an IEnumerable<IGrouping<string, Student>> var studentQuery3 = from student in students group student by student.Last;

However, the use of var does have at least the potential to make your code more difficult to understand for other developers. For that reason, the C# documentation generally uses var only when it is required.

See Also LINQ Query Expressions (C# Programming Guide) Send Feedback on this topic to Microsoft. View this topic online in your default browser.

Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language (also in Visual Basic and potentially any other .NET language). With LINQ, a query is now a first-class language construct, just like classes, methods, events and so on. For a developer who writes queries, the most visible "language-integrated" part of LINQ is the query expression. Query expressions are written in a declarative query syntax introduced in C# 3.0. By using query syntax, you can perform even complex filtering, ordering, and grouping operations on data sources with a minimum of code. You use the same basic query expression patterns to query and transform data in SQL databases, ADO.NET Datasets, XML documents and streams, and .NET collections. The following example shows the complete query operation. The complete operation includes creating a data source, defining the query expression, and executing the query in a foreach statement. JavaScript C# C++ F# JScript VB Copy to Clipboard
class LINQQueryExpressions { static void Main() { // Specify the data source. int[] scores = new int[] { 97, 92, 81, 60 }; // Define the query expression. IEnumerable<int> scoreQuery = from score in scores where score > 80 select score; // Execute the query. foreach (int i in scoreQuery) {

Console.Write(i + " "); } } } // Output: 97 92 81

For more information about the basics of LINQ in C#, see Getting Started with LINQ in C#. Query Expression Overview

Query expressions can be used to query and to transform data from any LINQ-enabled data source. For example, a single query can retrieve data from a SQL database, and produce an XML stream as output. Query expressions are easy to master because they use many familiar C# language constructs. For more information, see Getting Started with LINQ in C#. The variables in a query expression are all strongly typed, although in many cases you do not have to provide the type explicitly because the compiler can infer it. For more information, see Type Relationships in LINQ Query Operations (C#). A query is not executed until you iterate over the query variable in a foreach statement. For more information, see Introduction to LINQ Queries (C#). At compile time, query expressions are converted to Standard Query Operator method calls according to the rules set forth in the C# specification. Any query that can be expressed by using query syntax can also be expressed by using method syntax. However, in most cases query syntax is more readable and concise. For more information, see C# Language Specification and Standard Query Operators Overview. As a rule when you write LINQ queries, we recommend that you use query syntax whenever possible and method syntax whenever necessary. There is no semantic or performance difference between the two different forms. Query expressions are often more readable than equivalent expressions written in method syntax. Some query operations, such as Count or Max, have no equivalent query expression clause and must therefore be expressed as a method call. Method syntax can be combined with query syntax in various ways. For more information, see LINQ Query Syntax versus Method Syntax (C#). Query expressions can be compiled to expression trees or to delegates, depending on the type that the query is applied to. IEnumerable< T> queries are compiled to delegates. IQueryable and IQueryable< T> queries are compiled to expression trees. For more information, see Expression Trees (C# and Visual Basic).

The following table lists topics that provide additional information about queries and code examples for common tasks. Topic Query Expression Basics (C# Programming Guide) How to: Write LINQ Queries in C# Description Introduces fundamental query concepts and provides examples of C# query syntax. Provides examples of several basic types of query

expressions. How to: Handle Exceptions in Query How and when to move potential exception-throwing Expressions (C# Programming Guide) code outside a query expression. How to: Populate Object Collections How to use the select statement to merge data from from Multiple Sources (LINQ) different sources into a new type. How to: Group Query Results (C# Shows different ways to use the group clause. Programming Guide) How to: Create a Nested Group (C# Shows how to create nested groups. Programming Guide) How to: Perform a Subquery on a Shows how to use a sub-expression in a query as a data Grouping Operation (C# Programming source for a new query. Guide) Shows how to implement a thread-safe standard query How to: Group Results by Contiguous operator that can perform grouping operations on Keys (C# Programming Guide) streaming data sources. How to: Dynamically Specify Predicate Shows how to supply an arbitrary number of values to Filters at Runtime (C# Programming use in equality comparisons in a where clause. Guide) How to: Store the Results of a Query in Illustrates how to materialize and store query results Memory (C# Programming Guide) without necessarily using a foreach loop. How to: Return a Query from a Method Shows how to return query variables from methods, and (C# Programming Guide) how to pass them to methods as input parameters. How to: Perform Custom Join Shows how to perform join operations based on any Operations (C# Programming Guide) kind of predicate function. How to: Join by Using Composite Keys Shows how to join two sources based on more than one (C# Programming Guide) matching key. How to: Order the Results of a Join Shows how to order a sequence that is produced by a Clause (C# Programming Guide) join operation. How to: Perform Inner Joins (C# Shows how to perform an inner join in LINQ. Programming Guide) How to: Perform Grouped Joins (C# Shows how to produce a grouped join in LINQ. Programming Guide) How to: Perform Left Outer Joins (C# Shows how to produce a left outer join in LINQ. Programming Guide) How to: Handle Null Values in Query Shows how to handle null values in LINQ queries. Expressions (C# Programming Guide) See Also

Tasks

Walkthrough: Writing Queries in C# (LINQ)

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

This walkthrough demonstrates the C# language features that are used to write LINQ query expressions. After completing this walkthrough you will be ready to move on to the samples and documentation for the specific LINQ provider you are interested in, such as LINQ to SQL, LINQ to DataSets, or LINQ to XML.

Prerequisites

This walkthrough requires features that are introduced in Visual Studio 2008. For a video version of this topic, see Video How to: Writing Queries in C# (LINQ).

Create a C# Project

To create a project 1. Start Visual Studio. 2. On the menu bar, choose File, New, Project. The New Project dialog box opens. 3. Expand Installed, expand Templates, expand Visual C#, and then choose Console Application. 4. In the Name text box, enter a different name or accept the default name, and then choose the OK button. The new project appears in Solution Explorer. 5. Notice that your project has a reference to System.Core.dll and a using directive for the System.Linq namespace.

Create an in-Memory Data Source

The data source for the queries is a simple list of Student objects. Each Student record has a first name, last name, and an array of integers that represents their test scores in the class. Copy this code into your project. Note the following characteristics:

The Student class consists of auto-implemented properties. Each student in the list is initialized with an object initializer. The list itself is initialized with a collection initializer.

This whole data structure will be initialized and instantiated without explicit calls to any constructor or explicit member access. For more information about these new features, see AutoImplemented Properties (C# Programming Guide) and Object and Collection Initializers (C# Programming Guide). To add the data source

Add the Student class and the initialized list of students to the Program class in your project.
JavaScript C# C++ F# JScript VB Copy to Clipboard
public class Student { public string First { get; set; } public string Last { get; set; } public int ID { get; set; } public List<int> Scores; } // Create a data source by using a collection initializer. static List<Student> students = new List<Student> { new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 92, 81, 60}},

new Student List<int> {75, new Student List<int> {88, new Student List<int> {97, new Student List<int> {35, new Student List<int> {99, new Student List<int> {93, new Student List<int> {92, new Student List<int> {68, new Student List<int> {99, new Student List<int> {96, new Student List<int> {94, };

{First="Claire", Last="ODonnell", ID=112, Scores= new 84, 91, 39}}, {First="Sven", Last="Mortensen", ID=113, Scores= new 94, 65, 91}}, {First="Cesar", Last="Garcia", ID=114, Scores= new 89, 85, 82}}, {First="Debra", Last="Garcia", ID=115, Scores= new 72, 91, 70}}, {First="Fadi", Last="Fakhouri", ID=116, Scores= new 86, 90, 94}}, {First="Hanying", Last="Feng", ID=117, Scores= new 92, 80, 87}}, {First="Hugo", Last="Garcia", ID=118, Scores= new 90, 83, 78}}, {First="Lance", Last="Tucker", ID=119, Scores= new 79, 88, 92}}, {First="Terry", Last="Adams", ID=120, Scores= new 82, 81, 79}}, {First="Eugene", Last="Zabokritski", ID=121, Scores= new 85, 91, 60}}, {First="Michael", Last="Tucker", ID=122, Scores= new 92, 91, 91} }

To add a new Student to the Students list

Add a new Student to the Students list and use a name and test scores of your choice. Try typing all the new student information in order to better learn the syntax for the object initializer.

Create the Query

To create a simple query

In the application's Main method, create a simple query that, when it is executed, will produce a list of all students whose score on the first test was greater than 90. Note that because the whole Student object is selected, the type of the query is IEnumerable<Student>. Although the code could also use implicit typing by using the var keyword, explicit typing is used to clearly illustrate results. (For more information about var, see Implicitly Typed Local Variables (C# Programming Guide).) Note also that the query's range variable, student, serves as a reference to each Student in the source, providing member access for each object.

JavaScript C# C++

F# JScript VB Copy to Clipboard


// Create the query. // The first line could also be written as "var studentQuery =" IEnumerable<Student> studentQuery = from student in students where student.Scores[0] > 90 select student;

Execute the Query

To execute the query 1. Now write the foreach loop that will cause the query to execute. Note the following about the code: o Each element in the returned sequence is accessed through the iteration variable in the foreach loop. o The type of this variable is Student, and the type of the query variable is compatible, IEnumerable<Student>. 2. After you have added this code, build and run the application by pressing Ctrl + F5 to see the results in the Console window.
JavaScript C# C++ F# JScript VB Copy to Clipboard
// Execute the query. // var could be used here also. foreach (Student student in studentQuery) { Console.WriteLine("{0}, {1}", student.Last, student.First); }

To add another filter condition

You can combine multiple Boolean conditions in the where clause in order to further refine a query. The following code adds a condition so that the query returns those students whose first score was over 90 and whose last score was less than 80. The where clause should resemble the following code.
Copy to Clipboard
where student.Scores[0] > 90 && student.Scores[3] < 80

For more information, see where clause (C# Reference).


Modify the Query

To order the results 1. It will be easier to scan the results if they are in some kind of order. You can order the returned sequence by any accessible field in the source elements. For example, the following orderby clause orders the results in alphabetical order from A to Z according to the last name of each student. Add the following orderby clause to your query, right after the where statement and before the select statement:
Copy to Clipboard
orderby student.Last ascending

2.

Now change the orderby clause so that it orders the results in reverse order according to the score on the first test, from the highest score to the lowest score.
Copy to Clipboard
orderby student.Scores[0] descending

3.

Change the WriteLine format string so that you can see the scores:
Copy to Clipboard
Console.WriteLine("{0}, {1} {2}", student.Last, student.First, student.Scores[0]);

For more information, see orderby clause (C# Reference). To group the results 1. Grouping is a powerful capability in query expressions. A query with a group clause produces a sequence of groups, and each group itself contains a Key and a sequence that consists of all the members of that group. The following new query groups the students by using the first letter of their last name as the key.
JavaScript C# C++ F# JScript VB Copy to Clipboard
// studentQuery2 is an IEnumerable<IGrouping<char, Student>> var studentQuery2 = from student in students group student by student.Last[0];

2.

Note that the type of the query has now changed. It now produces a sequence of groups that have a char type as a key, and a sequence of Student objects. Because the type of the query has changed, the following code changes the foreach execution loop also:
JavaScript C# C++ F# JScript VB

Copy to Clipboard
// studentGroup is a IGrouping<char, Student> foreach (var studentGroup in studentQuery2) { Console.WriteLine(studentGroup.Key); foreach (Student student in studentGroup) { Console.WriteLine(" {0}, {1}", student.Last, student.First); } }

3.

Press Ctrl + F5 to run the application and view the results in the Console window. For more information, see group clause (C# Reference). To make the variables implicitly typed

Explicitly coding IEnumerables of IGroupings can quickly become tedious. You can write the same query and foreach loop much more conveniently by using var. The var keyword does not change the types of your objects; it just instructs the compiler to infer the types. Change the type of studentQuery and the iteration variable groupto var and rerun the query. Note that in the inner foreach loop, the iteration variable is still typed as Student, and the query works just as before. Change the s iteration variable to var and run the query again. You see that you get exactly the same results.
JavaScript C# C++ F# JScript VB Copy to Clipboard
var studentQuery3 = from student in students group student by student.Last[0]; foreach (var groupOfStudents in studentQuery3)

{ Console.WriteLine(groupOfStudents.Key); foreach (var student in groupOfStudents) { Console.WriteLine(" {0}, {1}", student.Last, student.First); } }

For more information about var, see Implicitly Typed Local Variables (C# Programming Guide). To order the groups by their key value

When you run the previous query, you notice that the groups are not in alphabetical order. To change this, you must provide an orderby clause after the group clause. But to use an orderby clause, you first need an identifier that serves as a reference to the groups created by the group clause. You provide the identifier by using the into keyword, as follows:
JavaScript C# C++ F# JScript VB Copy to Clipboard
var studentQuery4 = from student in students group student by student.Last[0] into studentGroup orderby studentGroup.Key select studentGroup; foreach (var groupOfStudents in studentQuery4) { Console.WriteLine(groupOfStudents.Key); foreach (var student in groupOfStudents) { Console.WriteLine(" {0}, {1}", student.Last, student.First); } }

When you run this query, you will see the groups are now sorted in alphabetical order. To introduce an identifier by using let

You can use the let keyword to introduce an identifier for any expression result in the query expression. This identifier can be a convenience, as in the following example, or it can enhance performance by storing the results of an expression so that it does not have to be calculated multiple times.
JavaScript C# C++ F# JScript VB Copy to Clipboard
// studentQuery5 is an IEnumerable<string> // This query returns those students whose // first test score was higher than their // average score. var studentQuery5 = from student in students let totalScore = student.Scores[0] + student.Scores[1] + student.Scores[2] + student.Scores[3] where totalScore / 4 < student.Scores[0] select student.Last + " " + student.First; foreach (string s in studentQuery5) { Console.WriteLine(s); }

For more information, see let clause (C# Reference). To use method syntax in a query expression

As described in Query Syntax and Method Syntax in LINQ (C#), some query operations can only be expressed by using method syntax. The following code calculates the total score for each Student in the source sequence, and then calls the Average() method on the results of that query to calculate the average score of the class. Note the placement of parentheses around the query expression.

JavaScript C# C++ F# JScript VB Copy to Clipboard


var studentQuery6 = from student in students let totalScore = student.Scores[0] + student.Scores[1] + student.Scores[2] + student.Scores[3] select totalScore; double averageScore = studentQuery6.Average(); Console.WriteLine("Class average score = {0}", averageScore);

To transform or project in the select clause 1. It is very common for a query to produce a sequence whose elements differ from the elements in the source sequences. Delete or comment out your previous query and execution loop, and replace it with the following code. Note that the query returns a sequence of strings (not Students), and this fact is reflected in the foreach loop.
JavaScript C# C++ F# JScript VB Copy to Clipboard
IEnumerable<string> studentQuery7 = from student in students where student.Last == "Garcia"

select student.First; Console.WriteLine("The Garcias in the class are:"); foreach (string s in studentQuery7) { Console.WriteLine(s); }

2.

Code earlier in this walkthrough indicated that the average class score is approximately 334. To produce a sequence of Students whose total score is greater than the class average, together with their Student ID, you can use an anonymous type in the select statement:
JavaScript C# C++ F# JScript VB Copy to Clipboard
var studentQuery8 = from student in students let x = student.Scores[0] + student.Scores[1] + student.Scores[2] + student.Scores[3] where x > averageScore select new { id = student.ID, score = x }; foreach (var item in studentQuery8) { Console.WriteLine("Student ID: {0}, Score: {1}", item.id, item.score); }

Next Steps

After you are familiar with the basic aspects of working with queries in C#, you are ready to read the documentation and samples for the specific type of LINQ provider you are interested in:

LINQ to SQL LINQ to DataSet Walkthrough: Creating LINQ to SQL Classes (O/R Designer) Send Feedback on this topic to Microsoft. View this topic online in your default browser.

The Object Relational Designer (O/R Designer) provides a visual design surface for creating and editing LINQ to SQL classes (entity classes) that are based on objects in a database. By using LINQ to SQL, you can access SQL databases with LINQ technology. For more information, see Language-Integrated Query (LINQ). This walkthrough provides the steps that you must follow to create LINQ to SQL entity classes mapped to the Customers and Orders tables in the Northwind database and display the data on a Windows Form. In addition to the steps for displaying the data from the table, the steps for binding data to a LINQ query are also provided. Finally, the steps for using stored procedures to replace the default LINQ to SQL logic for sending updates from the entity classes to the database are provided. During this walkthrough, you will learn how to perform the following tasks:

Add a LINQ to SQL file to a project. Create new entity classes that are mapped to related tables in the database. Create an object data source that references the entity classes. Create a Windows Form containing controls that are bound to entity classes. Add code to load and save the data between the entity classes and the database. Construct a simple LINQ query and display the results on the form. Add stored procedures to the O/R Designer. Configure an entity class to use stored procedures to perform Inserts, Updates, and Deletes. Prerequisites

To complete this walkthrough, you need the following:

Access to the SQL Server version of the Northwind sample database. For more information, see How to: Install Sample Databases. The UpdateCustomer stored procedure for the Northwind database. For more information, see Walkthrough: Creating Update Stored Procedures for the Northwind Customers Table. Creating the Windows-Based Application

Because you will be working with LINQ to SQL classes and displaying the data on a Windows Form, the first step in this walkthrough is to create a new Windows Forms application. To create the new Windows Application project 1. From the File menu, create a new project. 2. Name the project ORDesignerWalkthrough.

Note: The O/R Designer is supported in Visual Basic and C# projects, so create the new project in one of these languages. 3. Click the Windows Forms Application template and click OK. For more information, see Creating Windows-based Applications. The ORDesignerWalkthrough project is created and added to Solution Explorer. Adding a LINQ to SQL Classes File to the Project (Opening the O/R Designer)

Entity classes are created and stored in LINQ to SQL Classes files (.dbml files). The O/R Designer opens when you open a .dbml file. Add .dbml files to projects by selecting the LINQ to SQL Classes template in the Add New Item dialog box. To add a .dbml file to a project 1. On the Project menu, click Add New Item. 2. Click the LINQ to SQL Classes template and type Northwind.dbml in the Name box. 3. Click Add. An empty LINQ to SQL Classes file (Northwind.dbml) is added to the project, and the O/R Designer opens.

After you add the new LINQ to SQL file to the project, the empty design surface opens, displaying two separate panes. The pane on the left is the entities pane, where entity classes are displayed and configured. The pane on the right is the methods pane that displays the DataContext methods added to the designer. If the methods pane is not visible right click an empty area in the entities pane and click Show Methods Pane. The entire empty surface represents a DataContext ready to be configured. The DataContext name corresponds to the name that you provided for the .dbml file. For this walkthrough, because you named the LINQ to SQL file Northwind.dbml, the DataContext is named NorthwindDataContext. You can verify this by clicking any empty area on the designer and inspecting the Properties window.

Note: The DataContext class contains methods and properties for connecting to a database and manipulating the data in the database (for example, performing Inserts, Updates, and Deletes). For more information, see DataContext Methods (O/R Designer). Creating Customer and Order Entity Classes

Create LINQ to SQL classes that are mapped to database tables by dragging tables from Server Explorer/ Database Explorer onto the O/R Designer. The result is a LINQ to SQL entity class that maps to the table in the database. To add a Customer entity class to the O/R Designer 1. In Server Explorer/ Database Explorer, locate the tables in the SQL Server version of the Northwind sample database. For more information, see How to: Create a Data Connection to the Northwind Database. 2. Drag the Customers node from Server Explorer/ Database Explorer onto the O/R Designer surface. An entity class named Customer is created. It has properties that correspond to the columns in the Customers table. The entity class is named Customer (not Customers) because it represents a single customer from the Customers table.

Note: This renaming behavior is called pluralization. It can be turned on or off in the Options Dialog Box (Visual Studio). For more information, see How to: Turn Pluralization On and Off (O/R Designer). 3. Drag the Orders node from Server Explorer/ Database Explorer onto the O/R Designer surface.

An entity class named Order is created, along with a Customer_Order association (relationship) to the Customer entity class. It has properties that correspond to the columns in the Orders table.

Note: The entity class is named Order because it represents a single order. The parent class ( Customer) has an Orders property that represents the collection of orders for that specific customer. For more information about LINQ to SQL associations, see How to: Create an Association (Relationship) Between LINQ to SQL Classes (O/R Designer). Creating an Object Data Source with the Customer Entity Class

Entity classes, just like other classes that have public properties, can be used as object data sources. They can be added to the Data Sources window and dragged onto forms to create databound controls (controls that are bound to the values in the public properties of the object). Add entity classes to the Data Sources window by running the Data Source Configuration Wizard and clicking Object for the data source in the wizard. To add the Customer as an object data source in the Data Sources window 1. 2. 3. 4. 5. On the Build menu, click Build ORDesignerWalkthrough to build the project. On the Data menu, click Show Data Sources. In the Data Sources window, click Add New Data Source. Click Object on the Choose a Data Source Type page and then click Next. Expand the ORDesignerWalkthrough node (the node with the name of your project) and locate and select the Customer class.

Note: If the Customer class is not available, cancel out of the wizard, build the project, and run the wizard again. 6. Click Finish to create the data source and add the Customer entity class to the Data Sources window. Creating Data-Bound Controls to Display the Data on a Windows Form

Create controls that are bound to entity classes by dragging LINQ to SQL data source items from the Data Sources window onto a Windows Form. To add controls bound to the entity classes

1. Open Form1 in Design view. 2. From the Data Sources window, drag the Customer node onto Form1.

Note: To display the Data Sources window, click Show Data Sources on the Data menu. 3. Drag the Orders node from the Data Sources window onto Form1. Place it under CustomerDataGridView. 4. Open Form1 in code view. 5. Add the following code to the form, global to the form, outside any specific method, but inside the Form1 class: JavaScript C# C++ F# JScript VB Copy to Clipboard
Private NorthwindDataContext1 As New NorthwindDataContext

JavaScript C# C++ F# JScript VB Copy to Clipboard


private NorthwindDataContext northwindDataContext1 = new NorthwindDataContext();

6. Create an event handler for the Form_Load event and add the following code to the handler: JavaScript C# C++ F# JScript VB Copy to Clipboard
CustomerBindingSource.DataSource = NorthwindDataContext1.Customers

JavaScript C# C++ F# JScript VB Copy to Clipboard


customerBindingSource.DataSource = northwindDataContext1.Customers;

Testing the Application

Run the application. At this point the form contains one DataGridView displaying the data from the Customers table and a second DataGridView displaying the data from the selected customer's orders.

Note:

Notice that the save button is disabled. (You will implement save functionality in the next section.) To test the application 1. 2. 3. 4. 5. Press F5. Verify that data appears in the grids. Select a customer. Verify that the orders displayed are for the selected customer. Close the form. (On the Debug menu, click Stop Debugging.)

Implementing Save Functionality

As noted earlier, by default the save button is not enabled, and save functionality is not implemented. Also, code is not automatically added to save changed data to the form when databound controls are created for object data sources. This section explains how to enable the save button and implement save functionality for LINQ to SQL objects. To implement save functionality 1. Open Form1 in Design view. 2. Select the save button on the CustomerBindingNavigator. (The button labeled with a floppy disk icon.) 3. In the Properties window, set the Enabled property to True. 4. Double-click the save button to create an event handler and switch to the Code Editor. 5. Add the following code into the save button event handler: JavaScript C# C++ F# JScript VB Copy to Clipboard
Try NorthwindDataContext1.SubmitChanges() Catch ex As Exception MessageBox.Show(ex.Message)

End Try

JavaScript C# C++ F# JScript VB Copy to Clipboard


try { northwindDataContext1.SubmitChanges(); } catch (Exception ex) { MessageBox.Show(ex.Message); }

Testing the Application

Run the application. The save button should be enabled, and the ability to save data is available. To test the application 1. Press F5. 2. Modify some data in either grid. (Navigate off the edited row in the grid to commit inprocess changes.) 3. Click the save button to save changes back to the database. 4. Close the form. 5. Press F5 and verify that the changes were persisted (or locate the table in the database to verify that the changes were saved). Binding to LINQ Queries

In addition to binding the CustomerBindingSource to the DataContext, you can also bind directly to LINQ queries. For more information about how to create LINQ queries, see Introduction to LINQ Queries.

Adding a Button and TextBox to the Form To learn how to bind controls to LINQ queries, add controls to the form that enable you to enter a query parameter and then run the query. To add controls to the form 1. Open Form1 in Design view. 2. Add a TextBox to the form and set its Name property to CityTextBox. 3. Add a Button to the form and set the following properties: o Name = RunQueryButton
o

Text = Run Query

Data Binding to the LINQ Query Add code to run a LINQ query. The query uses the value typed into CityTextBox as a query parameter. To bind to a LINQ query

Double-click the RunQueryButton and add the following code to the RunQueryButton_click event handler: JavaScript C# C++ F# JScript VB Copy to Clipboard
Dim CustomersQuery = From customers in NorthwindDataContext1.Customers _ Where customers.City = CityTextBox.Text _ Select customers CustomerBindingSource.DataSource = CustomersQuery

JavaScript

C# C++ F# JScript VB Copy to Clipboard


var CustomersQuery = from customers in northwindDataContext1.Customers where customers.City == CityTextBox.Text select customers; customerBindingSource.DataSource = CustomersQuery;

Testing the Application

Run the application. You can now query for customers in a specific city. To test the application 1. 2. 3. 4. Press F5. Type London in the text box. Click the Run Query button. Verify that only customers who have a value of London in their City property are displayed.

Overriding the Default Behavior for Performing Updates (Inserts, Updates, and Deletes)

By default, the logic to perform updates is provided by the LINQ to SQL runtime. The runtime creates default Insert, Update, and Delete statements based on the Select statement that is used to populate your entity class with data. When you do not want to use the default behavior, you can configure the update behavior and designate specific stored procedures for performing the necessary Inserts, Updates, and Deletes required to manipulate the data in your database. You can also do this when the default behavior is not generated, for example, when your entity classes map to joined tables. Additionally, you can override the default update behavior when the database requires table access through stored procedures.

Note: This section requires the availability of the additional InsertCustomer, UpdateCustomer, and

DeleteCustomer stored procedures for the Northwind database. For details about how to create these stored procedures, see Walkthrough: Creating Update Stored Procedures for the Northwind Customers Table. To override the default update behavior 1. Open the LINQ to SQL file in the O/R Designer. (Double-click the Northwind.dbml file in Solution Explorer.) 2. In Server Explorer/ Database Explorer, expand the Northwind databases Stored Procedures node and locate the UpdateCustomers stored procedure. 3. Drag the UpdateCustomers stored procedure onto the O/R Designer. The UpdateCustomers stored procedure is added to the methods pane as a DataContext method. For more information, see DataContext Methods (O/R Designer). 4. Select the Customer entity class in the O/R Designer. 5. In the Properties window, select the command to override. ( Insert, Update, or Delete). For this example, select the Update property. 6. Click the ellipsis next to Use Runtime to open the Configure Behavior dialog box. 7. Select Customize. 8. Select the UpdateCustomers method in the Customize list. 9. Inspect the list of Method Arguments and Class Properties and notice that there are two Method Arguments and two Class Properties for some columns in the table. This facilitates tracking changes and creating statements that check for concurrency violations. 10. Map the original method arguments (Original_ ArgumentName) to the original properties ( PropertyName (Original)). For this walkthrough, you have to map the Original_CustomerID argument to the CustomerID (Original) property.

Note: By default, method arguments will map to class properties when the names match. If property names were changed and no longer match between the table and the entity class, you might have to select the equivalent class property to map to if the designer cannot determine the correct mapping. Additionally, if method arguments do not have valid class properties to map to, you can set the Class Properties value to (None). 11. Click OK. Testing the Application

Run the application again to verify that the UpdateCustomers stored procedure correctly updates the customer record on the database. To test the application

1. 2. 3. 4. 5. 6. 7.

Press F5. Locate the ContactName column in the grid for ALFKI. Change the name from Maria Anders to Anders. Navigate off the row to commit the change. Click the save button. Close the form. Press F5 to run the application again and verify that only Anders appears in the ContactName column for ALFKI.

Next Steps

Depending on your application requirements, there are several steps that you may want to perform after you create LINQ to SQL entity classes. Some enhancements you could make to this application include the following:

Adding more stored procedures to use for the Insert and Delete commands. For more information, see How to: Assign Stored Procedures to Perform Updates, Inserts, and Deletes (O/R Designer). Construct various LINQ queries to return filtered data. For more information, see How to: Query for Information (LINQ to SQL). See Also

How to: Query for Information

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

Queries in LINQ to SQL use the same syntax as queries in LINQ. The only difference is that the objects referenced in LINQ to SQL queries are mapped to elements in a database. For more information, see Introduction to LINQ Queries. LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. Some features of LINQ queries might need special attention in LINQ to SQL applications. For more information, see Query Concepts.

Example

The following query asks for a list of customers from London. In this example, Customers is a table in the Northwind sample database.
JavaScript C# C++ F# JScript VB Copy to Clipboard
Northwnd db = new Northwnd(@"c:\northwnd.mdf"); // Query for customers in London. IQueryable<Customer> custQuery = from cust in db.Customers where cust.City == "London" select cust;

See Also
How to: Validate DBML and External Mapping Files Send Feedback on this topic to Microsoft. View this topic online in your default browser.

External mapping files and .dbml files that you modify must be validated against their respective schema definitions. This topic provides Visual Studio users with the steps to implement the validation process.

To validate a .dbml or XML file


1. On the Visual Studio File menu, point to Open, and then click File. 2. In the Open File dialog box, click the .dbml or XML mapping file that you want to validate. The file opens in the XML Editor. 3. Right-click the window, and then click Properties. 4. In the Properties window, click the ellipsis for the Schemas property.

The XML Schemas dialog box opens. 5. Note the appropriate schema definition for your purpose. o DbmlSchema.xsd is the schema definition for validating a .dbml file. For more information, see Code Generation in LINQ to SQL.
o

LinqToSqlMapping.xsd is the schema definition for validating an external XML mapping file. For more information, see External Mapping.

6. In the Use column of the desired schema definition row, click to open the drop-down box, and then click Use this schema. The schema definition file is now associated with your DBML or XML mapping file. Make sure no other schema definitions are selected. 7. On the View menu, click Error List. Determine whether errors, warnings, or messages have been generated. If not, the XML file is valid against the schema definition.

Alternate Method for Supplying Schema Definition


If for some reason the appropriate .xsd file does not appear in the XML Schemas dialog box, you can download the .xsd file from a Help topic. The following steps help you save the downloaded file in the Unicode format required by the Visual Studio XML Editor. To copy a schema definition file from a Help topic 1. Locate the Help topic that contains the schema definition as described earlier in this topic. o For .dbml files, see Code Generation in LINQ to SQL.
o

For external mapping files, see External Mapping.

2. 3. 4. 5. 6.

Click Copy Code to copy the code file to the Clipboard. Start Notepad to create a new file. Paste the code from the clipboard into Notepad file. On the Notepad File menu, click Save As. In the Encoding box, select Unicode.

Note: This selection guarantees that the Unicode-16 byte-order marker ( FFFE) is prepended to the text file.

7. In the File name box, create a file name with an .xsd extension.

See Also
What's New for Data Application Development in Visual Studio 2012 Send Feedback on this topic to Microsoft. View this topic online in your default browser.

Visual Studio 2012 includes new features for developing applications that access data. SQL Server Object Explorer SQL Server Object Explorer provides a view of your database objects thats similar to SQL Server Management Studio. You can create, edit, rename, and delete SQL Server objects, including tables, stored procedures, and functions. You can edit table data, compare schemas, and execute queries by using contextual menus. You can create objects by using tools that function similarly to those in SQL Server Management Studio. You can open SQL Server Object Explorer from the View menu in Visual Studio. For more information, see Connected Database Development.

You can continue to connect to SQL Server databases from the Data Connections node in Server Explorer. New Table Designer

In the new Table Designer, you can define a table graphically and understand its related objects at a glance. As you change the table definition through a graphical interface, the Script pane updates the tables script definition. As an alternative, you can modify the script directly in the Script pane. You can define the table via the graphical designer, the script, or a combination of the two. To apply the SQL in the Script pane, you choose the new Update button. The new Table Designer appears for a database thats in the SQL Server 2012 format. For more information, see How to: Create Database Objects Using Table Designer.

SQL Server Express LocalDB

The SQL Server Express LocalDB engine is used to access a database file (.mdf) in SQL Server 2012 format. Earlier versions of Visual Studio use the SQL Server Express engine to access a database file (.mdf). SQL Server Express LocalDB is a lightweight version of SQL Server that has many of the programmability features of a SQL Server database. SQL Server Express LocalDB runs in user mode and has a fast, zero-configuration installation. For more information, see Local Data Overview. Database File Conversion

If you have a database file (.mdf) that was created with an earlier version of SQL Server, you must convert it to the SQL Server 2012 format before you can use the file with SQL Server Express LocalDB. Otherwise, a message box prompts you to convert the file. If you convert the file, you will gain the benefits of SQL Server Express LocalDB, but the database will no longer be compatible with earlier versions of SQL Server. If you dont convert the file, you can continue to work with the database in Visual Studio 2012 by accessing the file with a SQL Server Express data source. For more information, see Local Data Overview. See Also
Walkthrough: Creating a SQL Server Compact Database

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

This walkthrough demonstrates how to create a new SQL Server Compact database file that is based on the Customers and Orders tables in the Northwind sample database. This walkthrough illustrates the following tasks:

Creating a new Windows-based application. Creating a new local database file and adding it to a project. Creating database tables and relationships by using the data design tools in Visual Studio.

Prerequisites

In order to complete this walkthrough, you will need:

Access to the Northwind sample database. For more information, see How to: Install Sample Databases.

Creating a Windows-Based Application

Because you will create a database that is based on the empty database template, you need a project in which to create the database.

Note

Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more information, see Visual Studio Settings. To create a new Windows-based application 1. In Visual Studio, on the File menu, point to New and then click Project. 2. Name the project SampleDatabaseWalkthrough. 3. Click Windows Forms Application and then click OK. For more information, see Developing Client Applications. The SampleDatabaseWalkthrough project is created and added to Solution Explorer/Database Explorer.

Creating a New SQL Server Database

To add a new database to the project 1. 2. 3. 4. On the Project menu, click Add New Item. Select Local Database in the list of available templates. Type SampleDatabase in the Name box. Click Add. The Data Source Configuration Wizard opens with the new SampleDatabase.sdf file chosen as the data connection. 5. Click Next. 6. Click Next again to save the connection string to the application configuration file. 7. Click Finish on the Choose Your Database Objects page. (No database objects are available because this is a new database.)

SampleDatabase.sdf and SampleDatabaseDataSet.xsd are added to the project.

Creating New Tables in the Database

To add tables to the database 1. Open Server Explorer/Database Explorer by clicking Server Explorer/Database Explorer on the View menu. 2. Expand the SampleDatabase.sdf node under the Data Connections node. 3. Right-click Tables and then click Create Table. The New Table dialog box opens. 4. Create columns as described in the following table: Column Name Data Type Length Allow Nulls CustomerID nchar 5 No CompanyName nvarchar 40 No ContactName nvarchar 30 Yes ContactTitle nvarchar 30 Yes Address nvarchar 60 Yes City nvarchar 15 Yes Region nvarchar 15 Yes PostalCode nvarchar 10 Yes Country nvarchar 15 Yes Phone nvarchar 24 Yes Fax nvarchar 24 Yes 5. 6. 7. 8. Select the CustomerID column, and then set Primary Key to Yes. Type Customers in the Name box. Click OK. In Server Explorer/Database Explorer, right-click Tables and then click Create Table. The New Table dialog box opens. 9. Create columns as described in the following table: Column Name Data Type Length Allow Nulls OrderID int 4 No CustomerID nchar 5 Yes

EmployeeID int OrderDate datetime RequiredDate datetime ShippedDate datetime ShipVia int Freight money ShipName nvarchar ShipAddress nvarchar ShipCity nvarchar ShipRegion nvarchar ShipPostalCode nvarchar ShipCountry nvarchar

4 8 8 8 4 19 40 60 15 15 10 15

Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes

10. Select the OrderID column, and then set Primary Key to Yes. 11. Type Orders in the Name area. 12. Click OK. To create a relationship between the tables created in the previous procedure 1. 2. 3. 4. 5. 6. 7. 8. 9. In Server Explorer/Database Explorer, expand Tables. Right-click the Orders table and then click Table Properties. Click Add Relations. Type FK_Orders_Customers in the Relation Name box. Select CustomerID in the Foreign Key Table Column list. Click Add Columns. Click Add Relation. Click OK to complete the process and create the relationship in the database. Click OK again to close the Table Properties dialog box.

Populating the Sample Tables with Data

To populate the Customers table with data 1. In Server Explorer/Database Explorer, create a new connection to the Northwind sample database. For more information, see How to: Install Sample Databases and How to: Connect to Data in a Database. 2. Expand the Northwind database node in Server Explorer/Database Explorer. 3. Right-click the Northwind Customers table and then click Show Table Data. 4. Select all the records and copy them to the Clipboard. 5. Expand the SampleDatabase.sdf database in Server Explorer/Database Explorer. 6. Right-click the SampleDatabase.sdf Customers table and then click Show Table Data.

7. Paste the Northwind Customers table data from the Clipboard. To populate the Orders table with data 1. 2. 3. 4. 5. Right-click the Northwind Orders table and then click Show Table Data. Select all the records and copy them to the Clipboard. Expand the SampleDatabase.sdf database in Server Explorer/Database Explorer. Right-click the SampleDatabase.sdf Orders table and then click Show Table Data. Paste the Northwind Orders table data from the Clipboard.

Creating a Copy of the Database

Now that you have created a sample database containing data, you should make a copy of the database in its original state so that you can restore the data if you need to. To save the sample database 1. 2. 3. 4. On the File menu, click Save All. On the File menu, click Close Solution. Browse to the SampleDatabase.sdf file in your Projects folder, and copy it. Browse to a folder where you want to save the database, and paste the copy into the folder.

Next Steps

Now that you have a local database file containing some sample data, you can complete the following procedure:

How to: Deploy a SQL Server Compact 4.0 Database with an Application

See Also

Tasks
How to: Deploy a SQL Server Compact 4.0 Database with an Application

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

You have two deployment options for applications that contain SQL Server Compact databases. The method of deployment you choose depends on the servicing requirements of your application and whether your users will need administrative credentials on the computer on which the application will be installed. Following are the deployment options for SQL Server Compact databases:

Traditional Microsoft Windows Installer (Microsoft setup technology) o Users need administrative credentials to install the application. o SQL Server Compact will be serviced by Microsoft Update. o Can use ClickOnce deployment. -or-

Private filebased deployment (deploying the SQL Server Compact DLLs as part of the project) o Users do not need administrative credentials to install the application. o SQL Server Compact will not be serviced by Microsoft Update. o Can also use ClickOnce deployment.

Traditional Windows Installer

Traditional Windows Installer technology is used in both standard Setup and Deployment projects and in ClickOnce deployment. When you deploy a SQL Server Compact database, ClickOnce deployment provides an option that automatically installs SQL Server Compact if it is not detected on the target computer. For this reason, ClickOnce is the preferred method of deployment for applications that include SQL Server Compact databases (as opposed to creating a custom action in a Setup and Deployment project). ClickOnce deployment has been updated so that it automatically includes the SQL Server Compact runtime as a prerequisite for applications that include SQL Server Compact databases. It also recognizes .sdf files as data files and sets these to the correct publish status. Creating a ClickOnce deployment for an application that contains a SQL Server Compact database consists of configuring the proper publish information in the Project Designer.

Note

Adding a SQL Server Compact database file to a project automatically configures the appropriate publish information for ClickOnce deployment.
Note

Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more information, see Visual Studio Settings. To use Windows Installer technology for ClickOnce deployment of an application that contains a SQL Server Compact 4.0 database 1. To open the Project Designer, in Solution Explorer/Database Explorer, double-click My Project if you are working on a Visual Basic project (or Properties if you are working on a C# project). 2. Click the Publish tab. 3. Click Application Files and set the .sdf file to Data File (Auto). This setting notifies the installer to treat this as a local data file and to put it in the Data Directory. 4. Click Prerequisites and select SQL Server Compact. This setting notifies the installer to check whether the SQL Server Compact runtime exists and to install it from the Internet if it is not found.
Creating the Installer

After the publish information is configured, create the installer. To create the installer 1. In the Publishing Location box, type the Web site, FTP server, or file path to publish the installer to. 2. Click Publish Now to create the installer. The application is ready to be installed. Go to the location you published to, and install the application to verify.

Private FileBased Deployment

Private filebased deployment refers to the process of including the required SQL Server Compact DLLs as files in the project (as opposed to a reference to DLLs already on the target computer). If you include the necessary DLLs with the application, the requirement to install SQL Server Compact is removed. Therefore, the administrative credentials are no longer needed. You can use ClickOnce deployment technology for private filebased deployment. If you do, you must remember to clear the SQL Server Compact prerequisite so that the Setup program does not install it. To deploy a SQL Server Compact 4.0 database by using private filebased deployment 1. To open the Project Designer, in Solution Explorer/Database Explorer, double-click My Project if you are working on a Visual Basic project (or Properties if you are working on a C# project). 2. Click the Publish tab. 3. Click Prerequisites and then clear the check box for SQL Server Compact. 4. Close the Project Designer. 5. Go to the directory that contains the SQL Server Compact DLLs. These are located in C:\Program Files\Microsoft SQL Server Compact Edition\v4.0. 6. Select the seven SQL Server Compact DLLs and copy them: o Sqlceca40.dll o Sqlcecompact40.dll o Sqlceer40EN.dll o Sqlceme40.dll o Sqlceoledb40.dll o Sqlceqp40.dll o Sqlcese40.dll 7. Paste the DLLs into the project in Solution Explorer/Database Explorer. 8. Select all seven DLLs in Solution Explorer/Database Explorer and open the Properties window. 9. Set the Copy to Output Directory property to Copy if newer. This will replace any earlier DLLs in an existing application with the newer ones if the application is updated. 10. Click the Show All Files button in Solution Explorer/Database Explorer. 11. Expand the References node. 12. Select System.Data.SqlServerCe. 13. Set the Copy Local property to True. Because your development computer has the SqlServerCe DLLs in the global assembly cache, you must configure the application to use the DLLs in the output directory. 14. Right-click the project in Solution Explorer/Database Explorer and select Publish to open the Publish Wizard. 15. Complete the wizard to publish the application.

The application is ready to be installed. Go to the location you published to, and install the application to verify.

See Also

Creating Data Applications Send Feedback on this topic to Microsoft. View this topic online in your default browser.

Visual Studio provides many design-time tools to help you create applications that access data. This introduction presents an overview of the basic processes involved in creating applications that work with data. The information here deliberately skips over many details and is designed as a source of general information and a jumping-off point to the many other Help pages associated with creating a data application. As you develop applications that access data in Visual Studio, you will have different requirements. In some cases, you might simply want to display data on a form. In other cases, you might need to devise a way to share information with other applications or processes. No matter what you do with data, there are certain fundamental concepts that you should understand. You might never need to know some of the details of data handling for example, you might never need to programmatically create a database but it is very useful to understand the basic data concepts, as well as the data tools (wizards and designers) available in Visual Studio. A typical data application uses most of the processes illustrated in the following diagram: The Data Cycle

As you create your application, think of the task you are trying to accomplish. Use the following sections to assist in finding the Visual Studio tools and objects that are available to you.

Note Visual Studio provides wizards to simplify several of the processes shown in the previous diagram. For example, running the Data Source Configuration Wizard provides your application with enough information to connect to data, create a typed dataset to receive the data, and bring the data into your application.

To quickly see how Visual Studio helps you in developing data applications, see Walkthrough: Creating a Simple Data Application. Connecting to Data

To bring data into your application (and send changes back to the data source), some kind of two-way communication needs to be established. This two-way communication is typically handled by objects in your data model. For example, a TableAdapter connects applications that use datasets to a database, and ObjectContext connects entities in the Entity Framework to a database. Visual Studio provides several tools to assist in creating connections that can be used by your application. For more information on connecting your application to data, see Connecting to Data in Visual Studio. To learn how to use datasets to connect your application to data in a database, see Walkthrough: Connecting to Data in a Database (Windows Forms). For information on connecting to data through a conceptual model, see the Entity Framework Quickstart. Preparing Your Application to Receive Data

If your application uses a disconnected data model you need to temporarily store the data in your application while you work with it. Visual Studio provides tools that help you create the objects that your application uses to temporarily store data: datasets, entities, and LINQ to SQL objects.

Note An application that uses a disconnected data model will typically connect to a database, run a query bringing data into the application, disconnect from the database, and then manipulate the data offline before reconnecting and updating the database. For more information on creating typed datasets in your application, see Preparing Your Application to Receive Data. For additional information about using datasets in n-tier applications, see How to: Separate Datasets and TableAdapters into Different Projects. To learn how to create a dataset, complete the procedures in Walkthrough: Creating a Dataset with the Dataset Designer. To learn how to use the Entity Data Model Wizard to generate entities from a database, see How to: Create a New .edmx File (Entity Data Model Tools).

To learn how to create LINQ to SQL objects, complete the procedures in Walkthrough: Creating LINQ to SQL Classes (O/R Designer). Fetching Data into Your Application

Whether your application uses a disconnected data model or not, you need to be able to fetch data into your application. You bring data into your application by executing queries or stored procedures against a database. Applications that store data in datasets execute queries and stored procedures by using TableAdapters, whereas applications that store data in entities execute queries by using LINQ to Entities or by connecting entities directly to stored procedures. For more information about creating and editing queries that use TableAdapters, see How to: Create TableAdapter Queries and How to: Edit TableAdapter Queries. For information about using stored procedures with the Entity Framework, see How to: Map Modification Functions to Stored Procedures (Entity Data Model Tools). For more information about loading data into datasets, and about executing queries and stored procedures, see Fetching Data into Your Application. To learn how to load data into a dataset, complete the procedures in Walkthrough: Displaying Data on a Windows Form and examine the code in the form-load event handler. To learn how to load data into LINQ to SQL objects, complete the procedures in Walkthrough: Creating LINQ to SQL Classes (O/R Designer). To learn how to create and execute a SQL query, see How to: Create and Execute an SQL Statement that Returns Rows. To learn how to execute a stored procedure, see How to: Execute a Stored Procedure that Returns Rows. Displaying Data on Forms

After bringing data into your application, you will typically display it on a form for users to view or modify. Visual Studio provides the Data Sources Window, where you can drag items onto forms to automatically create data-bound controls that display data. For more information on data binding and displaying data to users, see Binding Controls to Data in Visual Studio. To learn how to present data to users, complete the procedures in the following walkthroughs (paying particular attention to the process of dragging items from the Data Sources window):

Walkthrough: Displaying Data on a Windows Form.

How to: Bind Objects to Windows Form Controls (Entity Framework) How to: Bind Objects to Windows Presentation Foundation Controls (Entity Framework) Walkthrough: Binding WPF Controls to a WCF Data Service Walkthrough: Binding Silverlight Controls to a WCF Data Service Editing Data in Your Application

Once your users have been presented with data, they will likely modify it by adding new records and editing and deleting records prior to sending the data back to the database. For more information on working with the data once it is loaded into your dataset, see Editing Data in Your Application. For more information on working with data in an Entity Framework application, see Working with Objects (Entity Framework). Validating Data

When making changes to data, you will typically want to verify the changes before allowing the values to be accepted back into the dataset or written to the database. Validation is the name of the process for verifying that these new values are acceptable for the requirements of your application. You can add logic to check values in your application as they change. Visual Studio provides tools that assist in adding code that validates data during column and row changes. For more information, see Validating Data. To learn how to add data validation to your application, see Walkthrough: Adding Validation to a Dataset. To learn how to add validation to a dataset that is separated into an n-tier application, see How to: Add Validation to an N-Tier Dataset. For more information on validating data in an Entity Data Model, see How to: Execute Business Logic When Saving Changes (Entity Framework). Saving Data

After making changes in your application (and validating those changes), you typically want to send the changes back to the database. Applications that store data in datasets typically use a TableAdapterManager to save data. For more information, see TableAdapterManager Overview. Entity Framework applications use the SaveChanges method to save data.

For more information on sending updated data back to a database, see Saving Data. To learn how to send updated data from a dataset to a database, complete the procedures in Walkthrough: Saving Data from Related Data Tables (Hierarchical Update). For more information about saving data in an Entity Framework application, see Saving Changes and Managing Concurrency. Related Topics What's New for Data Application Development in Visual Studio 2012 Describes new features that Visual Studio provides for working with data sources and creating data applications. Overview of Data Applications in Visual Studio Provides links to topics that discuss how to create applications that work with data. Connecting to Data in Visual Studio Provides links to topics about how to use Visual Studio to connect your application to data and create data sources for your applications. Preparing Your Application to Receive Data Provides links to topics that explain how to work with data models in your application, including datasets and Entity Data Models. Fetching Data into Your Application Provides links to topics that describe how to load data into your application. Binding Controls to Data in Visual Studio Provides links to topics that explain how to binding Windows Forms controls, WPF controls, and Silverlight controls to data sources. Editing Data in Your Application Provides links to topics that describe how to change data in your application. Validating Data Provides links to topics that describe how to add validation to data changes.

Saving Data Provides links to topics that explain how to send updated data from your application to a database, or how to save it to other formats such as XML. Tools for Working with Data Sources in Visual Studio Provides links to topics about tools that you can use to work with data sources in Visual Studio, such as the Data Sources window and the ADO.NET Entity Data Model Designer. Using SQL Server Compact (Visual Studio) Provides links to topics about how to incorporate SQL Server Compact databases into applications. 2012 Microsoft Corporation. All rights reserved. Send Feedback on this topic to Microsoft.
How to: Map Modification Functions to Stored Procedures (Entity Data Model Tools)

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

This topic describes how to use the ADO.NET Entity Data Model Designer (Entity Designer) to map the insert, update, and delete operations of an entity type to stored procedures. The Entity Framework generates a class derived from ObjectContext that represents the entity container in the conceptual model. (The name of the derived class is the name of the EntityContainer in the conceptual model file.) This class exposes a SaveChanges method that triggers updates to the underlying database. These updates can use SQL statements that are automatically generated by the system (the default), or they can use stored procedures that are specified by the developer. The application code you use to create, update, and delete entities is the same whether or not you use stored procedures to update the database.

Note

If you do not map all three of the insert, update, or delete operations of a entity type to stored procedures, the unmapped operations will fail if executed at runtime and an UpdateException is thrown.

The procedures below assume that you have an .edmx file open in the Entity Designer.

Mapping the Insert Operation to a Stored Procedure


To map the insert operation to a stored procedure 1. On the Entity Designer surface or in the Model Browser Window, right-click the entity type for which you want to map the insert operation and select Stored Procedures Mapping. The Map Entity to Functions view of the Mapping Details window appears. 2. Click <Select Insert Function>. 3. From the drop-down list, select the stored procedure to which the insert operation will be mapped. The window is populated with default mappings between entity properties and stored procedure parameters. 4. For each stored procedure parameter, modify the mapping as appropriate by clicking the corresponding property field and selecting the appropriate property from the drop-down list.

Note

All entity keys must have mappings. If the stored procedure uses an INSERT statement, the entity key will typically be mapped to the primary key that was created when the new row was inserted. The next few steps describe how to map data that is returned by the stored procedure to entity properties. 5. Click on <Add Result Binding>. The field becomes editable. 6. Type the name of the parameter that contains data that was returned by the stored procedure. 7. Click the property field that corresponds to the parameter name. The field becomes a drop-down list of properties. 8. Select the property to which you want the returned data mapped.

Note

For integer-valued output parameters, the Rows Affected Parameter checkbox is enabled. If the checkbox is selected for a parameter and the value returned is zero when the insert operation is called, an OptimisticConcurrencyException will be thrown. 9. Repeat steps 5 through 8 for each returned value and unmapped property. The insert operation for the selected entity type is now mapped to a stored procedure.

Mapping the Update Operation to a Stored Procedure


To map the update operation to a stored procedure 1. On the Entity Designer surface or in the Model Browser Window, right-click the entity type for which you want to map the insert operation and select Stored Procedures Mapping. The Map Entity to Functions view of the Mapping Details window appears. 2. Click <Select Update Function>. 3. From the drop-down list, select the stored procedure to which the update operation will be mapped. The window is populated with default mappings between entity properties and stored procedure parameters. 4. For each stored procedure parameter, modify the mapping as appropriate by clicking the corresponding property field and selecting the appropriate property from the drop-down list. 5. For each property, you can optionally check the box in the Use Original Value column. The Use Original Value option enables you to use concurrency control. If the Use Original Value option is selected for a property, the value of the property that was read from the database will be passed to the specified stored procedure parameter. Note that both the original and current values of a property can be passed to different parameters.

Note

When you map the update operation, you can map data that was returned by the stored procedure to entity properties. The next few steps describe how to map data returned by the stored procedure to entity properties. 6. Click <Add Result Binding>. The field becomes editable.

7. Type the name of the parameter that contains data that was returned by the stored procedure. 8. Click the property field that corresponds to the parameter name. 9. From the drop-down list, select the property to which you want the returned data mapped.

Note

For integer-valued output parameters, the Rows Affected Parameter checkbox is enabled. If the checkbox is selected for a parameter and the value returned is zero when the update operation is called, an OptimisticConcurrencyException will be thrown. 10. Optionally, repeat steps 6 through 9 for each returned value. The update operation for the selected entity type is now mapped to a stored procedure.

Mapping the Delete Operation to a Stored Procedure


To map the delete operation to a stored procedure 1. On the Entity Designer surface or in the Model Browser Window, right-click the entity type for which you want to map the insert operation and select Stored Procedures Mapping. The Map Entity to Functions view of the Mapping Details window appears. 2. Click <Select Delete Function>. 3. From the drop-down list, select the stored procedure to which the delete operation will be mapped. The window is populated with default mappings between entity properties and stored procedure parameters. 4. For each stored procedure parameter, modify the mapping as appropriate by clicking the corresponding property field and selecting the appropriate property from the drop-down list.

Note

You must map associations to the stored procedure parameters. Associations are available for selection from the property drop-down list.
Note

For integer-valued output parameters, the Rows Affected Parameter checkbox is enabled. If the checkbox is selected for a parameter and the value returned is zero when the delete operation is called, an OptimisticConcurrencyException will be thrown.

See Also
Walkthrough: Mapping an Entity to Stored Procedures (Entity Data Model Tools)

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

This topic shows how to use the ADO.NET Entity Data Model Designer (Entity Designer) to map the insert, update, and delete operations of an entity type to stored procedures. Insert, update, and delete operations of an entity type can use SQL statements that are automatically generated by the system (the default), or they can use stored procedures that are specified by the developer. The application code you use to create, update, and delete entities is the same whether or not you use stored procedures to update the database. In this walkthrough, you will map two entity types (in the conceptual model) to stored procedures (in the storage model) by modifying the .edmx file used in the CourseManager application (for more information, see the Prerequisites section, later in this topic). You will also write code that will insert, update, and delete entity types.

Note

If you do not map all three of the insert, update, or delete operations of a entity type to stored procedures, the unmapped operations will fail if executed at runtime and an UpdateException will be thrown.
Prerequisites

To complete this walkthrough, you must build the CourseManager application. For more information and instructions, see the Entity Framework Quickstart. After you build this application, you will modify its .edmx file by mapping two entity types to stored procedures.

Note

Because many of the walkthrough topics in this documentation use the CourseManager application as a starting point, we recommend that you use a copy of the CourseManager

application for this walkthrough, instead of editing the original CourseManager code. This walkthrough assumes that the reader has basic competency with Visual Studio, the .NET Framework, and programming in either Visual C# or Visual Basic.

Mapping the Person Entity to Stored Procedures

When you map the insert operation of an entity to a stored procedure, if the server creates the primary key value for the inserted row, you must map this value back to the entity's key property. In this example, the InsertPerson stored procedure returns the newly created primary key as part of the stored procedure's result set. The primary key is mapped to the entity key ( PersonID) using the <Add Result Bindings> feature of the Entity Designer.

Note

If you map an insert, update, or delete operation to a stored procedure that returns an integervalued output parameter, the Rows Affected Parameter checkbox is enabled. If the checkbox is selected for a parameter and the value returned is zero when the operation is called, an OptimisticConcurrencyException will be thrown. To map the Person entity to stored procedures 1. Open the CourseManager solution in Visual Studio. 2. In Solution Explorer, double-click the School.edmx file. The School.edmx file opens in the ADO.NET Entity Data Model Designer (Entity Designer). 3. Right-click the Person entity type and select Stored Procedure Mapping. The stored procedure mappings appear in the Mapping Details window. 4. Click <Select Insert Function>. The field becomes a drop-down list of the stored procedures in the storage model that can be mapped to entity types in the conceptual model. 5. Select InsertPerson from the drop-down list. Default mappings between stored procedure parameters and entity properties appear. Note that arrows indicate the mapping direction: Property values are supplied to stored procedure parameters.

6. Click <Add Result Binding>. The field becomes editable. 7. Type NewPersonID, the name of the parameter returned by the InsertPerson stored procedure. Press Enter. By default, NewPersonID is mapped to the entity key PersonID. Note that an arrow indicates the direction of the mapping: The value of the result column is supplied to the property. 8. Click <Select Update Function> and select UpdatePerson from the resulting dropdown list. Default mappings between stored procedure parameters and entity properties appear. 9. Click <Select Delete Function> and select DeletePerson from the resulting drop-down list. Default mappings between stored procedure parameters and entity properties appear. The insert, update, and delete operations of the Person entity type are now mapped to stored procedures.

Mapping the OfficeAssignment Entity to Stored Procedures

In this example, we map the OfficeAssignment entity type to stored procedures. In this mapping we use the Use Original Value option on the update operation to enable a convenient way to check concurrency in our application code. To map the OfficeAssignment entity to stored procedures 1. Right-click the OfficeAssignment entity type and select Stored Procedure Mapping. The stored procedure mappings appear in the Mapping Details window. 2. Click <Select Insert Function> and select InsertOfficeAssignment from the resulting drop-down list. Default mappings between stored procedure parameters and entity properties appear. 3. Click <Add Result Binding>.

The field becomes editable. 4. Type Timestamp. 5. Click the empty field in the Property/Value column next to Timestamp. The field becomes a drop-down list of properties to which we can map the value that is returned by the InsertOfficeAssignment stored procedure. 6. Select Timestamp from the drop-down list. 7. Click <Select Update Function> and select UpdateOfficeAssignment from the resulting drop-down list. Default mappings between stored procedure parameters and entity properties appear. Checkboxes appear in the Use Original Value column next to each mapped property. 8. Click the empty field in the Property column that corresponds to the OrigTimestamp parameter, and select Timestamp from the resulting drop-down list. The Entity Designer did not make this the default mapping because the parameter name did not exactly match the property name. 9. Check the box in the Use Original Value column that corresponds to the Timestamp property. When an update is attempted, the value of the Timestamp property that was originally read from the database will be used when writing data back to the database. If the value does not match the value in the database, an OptimisticConcurrencyException will be thrown. 10. Click <Add Result Binding>. The field becomes editable. 11. Replace <Add Result Binding> with Timestamp. 12. Click the empty field in the Property/Value column next to Timestamp. The field becomes a drop-down list of properties to which we can map the result column that is returned by the UpdateOfficeAssignment stored procedure. 13. Select Timestamp from the drop-down list. 14. Click <Select Delete Function> and select DeleteOfficeAssignment from the resulting drop-down list. Default mappings between stored procedure parameters and entity properties appear.

The insert, update, and delete operations of the OfficeAssignment entity type are now mapped to stored procedures.

Constructing the User Interface

Next, you will add two forms to the CourseManager application. One form provides an interface for viewing and updating instructor information. The other form provides an interface for viewing and updating office assignments. To construct the user interface 1. Right-click the CourseManager project in the Solution Explorer, point to Add, and select New Item. The Add New Item dialog box appears. 2. Select Windows Form, set the name of the form to InstructorViewer.vb or InstructorViewer.cs and click Add. A new form is added to the project and opens in the form designer. The name of the form is set to InstructorViewer and the text is set to InstructorViewer. 3. Drag a DataGridView control from the Toolbox to the form and set its Name to instructorGridView in the Properties window. 4. Drag a Button control from the Toolbox to the form. Set its Name to updateInstructor and its Text to Update Instructor. 5. Drag another Button control from the Toolbox to the form. Set its Name to viewOffices and its Text to View Offices. 6. Right-click the CourseManager project in the Solution Explorer, point to Add, and select New Item. The Add New Item dialog box appears. 7. Select Windows Form, set the name of the form to OfficeViewer.vb or OfficeViewer.cs, and click Add. A new form is added to the project and opens in the form designer. The name of the form is set to OfficeViewer and the text is set to OfficeViewer. 8. Drag a ComboBox control from the Toolbox to the form and set its Name to instructorList. 9. Drag a TextBox control from the Toolbox to the form and set its Name to officeLocation.

10. Drag a Button control from the Toolbox to the form. Set its Name to updateOffice and its Text to Update Office. 11. In the Solution Explorer, double click CourseViewer.vb or CourseViewer.cs. The design view of the CourseViewer form appears. 12. Drag a Button control from the Toolbox to the form. 13. In the Properties window, set the Name property of the Button to viewInstructors and set the Text property to View Instructors. 14. Double click the viewInstructors Button control. The code-behind file for the CourseViewer form opens. 15. Add the following code to the viewInstructors_Click event handler:
JavaScript C# C++ F# JScript VB Copy to Clipboard
InstructorViewer instructorViewer = new InstructorViewer(); instructorViewer.Visible = true;

16.

Return to the design view of the InstructorViewer form. 17. Double click the viewOffices Button control. The code-behind file for Form2 opens. 18. Add the following code to the viewOffices_Click event handler:
JavaScript C#

C++ F# JScript VB Copy to Clipboard


OfficeViewer officeViewer = new OfficeViewer(); officeViewer.Visible = true;

The user interface is now complete.


Viewing and Updating Instructor Information

In this procedure, you will add code to the InstructorViewer form that allows you to view and update instructor information. More specifically, the code does the following:

Binds the DataGridView to a query that returns information about Person types that are instructors. For more information about binding objects to controls, see Binding Objects to Controls (Entity Framework). Saves any changes (inserts, updates, or deletions) in the DataGridView control to the database. Uses the stored procedures we mapped earlier to writes data to the database when SaveChanges() is called in the updateInstructor_Click event handler.

To view and update instructor information 1. With the InstructorViewer form open in the form designer, double-click the InstructorViewer form. The code-behind file for the InstructorViewer form opens. 2. Add the following using (C#) or Imports (Visual Basic) statements:
JavaScript C# C++

F# JScript VB Copy to Clipboard


using System.Data.Objects; using System.Data.Objects.DataClasses;

3.

Add a property to the InstructorViewer class that represents the object context:
JavaScript C# C++ F# JScript VB Copy to Clipboard
// Create an ObjectContext instance based on SchoolEntity. private SchoolEntities schoolContext;

4.

In the InstructorViewer_Load event handler, add code to initialize the object context and set the data source for the DataGridView control to a query that returns all Person types that do not have a null HireDate.
JavaScript C# C++ F#

JScript VB Copy to Clipboard


// Initialize schoolContext. schoolContext = new SchoolEntities(); // Define the query to retrieve instructors. ObjectQuery<Person> instructorQuery = schoolContext.People .Include("OfficeAssignment") .Where("it.HireDate is not null") .OrderBy("it.LastName"); // Execute and bind the instructorList control to the query. instructorGridView.DataSource = instructorQuery. Execute(MergeOption.OverwriteChanges); instructorGridView.Columns["EnrollmentDate"].Visible = false; instructorGridView.Columns["OfficeAssignment"].Visible = false; instructorGridView.Columns["StudentGrades"].Visible = false; instructorGridView.Columns["Courses"].Visible = false;

5.

Return to the design view of the InstructorViewer form and double-click the updateInstructor Button control. The updateInstructor_Click event handler is added to the code-behind file. 6. Add code to the updateInstructor_Click event handler that saves any changes made to instructor information in the instructorGridView DataGridView control.
JavaScript C# C++ F# JScript VB Copy to Clipboard
// Save object changes to the database, display a

// message, and refresh the form. schoolContext.SaveChanges(); MessageBox.Show("Change(s) saved to the database."); this.Refresh();

Press Ctrl + F5 to run the application. Instructor information can now be viewed and updated by clicking View Instructors, making changes in table that appears, and clicking Update Instructor.

Viewing and Updating Office Information

In this procedure, you will add code to the OfficeViewer form that allows you to view and update office assignment information. More specifically, the code does the following:

Binds the ComboBox to a query that returns instructor information. Displays office location information for the selected instructor in the TextBox. Uses the stored procedures we mapped earlier to write data to the database when SaveChanges() is called in the updateOffice_Click event handler.

To view and update office information 1. With the OfficeViewer form open in the form designer, double-click the OfficeViewer form. The code-behind file for the OfficeViewer form opens. 2. Add the following using (C#) or Imports (Visual Basic) statements:
JavaScript C# C++ F# JScript VB Copy to Clipboard
using System.Data.Objects;

using System.Data.Objects.DataClasses;

3.

Add a property to the OfficeViewer class that represents the object context:
JavaScript C# C++ F# JScript VB Copy to Clipboard
// Create an ObjectContext instance based on SchoolEntity. private SchoolEntities schoolContext;

4.

Add the following method to the form:


JavaScript C# C++ F# JScript VB Copy to Clipboard
private void ExecuteInstructorQuery() { // Define the query to retrieve instructors. ObjectQuery<Person> instructorQuery = schoolContext.People .Include("OfficeAssignment")

.Where("it.HireDate is not null") .OrderBy("it.LastName"); //Execute and bind the instructorList control to the query. //Using MergeOption.OverwriteChanges overwrites local data //with data from the database. instructorList.DataSource = instructorQuery .Execute(MergeOption.OverwriteChanges); instructorList.DisplayMember = "LastName"; }

This method executes a query that returns instructor information and binds the results to the instructorList ComboBox control. 5. In the OfficeViewer_Load event handler, add code to initialize the object context and call a method that binds the ComboBox control to a query that returns all Person types that do not have a null HireDate.
JavaScript C# C++ F# JScript VB Copy to Clipboard
schoolContext = new SchoolEntities(); ExecuteInstructorQuery();

6.

Return to the design view of the OfficeViewer form and double-click the instructorList ComboBox control. The instructorList_SelectedIndexChanged event handler is added to the code-behind file. 7. Add code to the event handler that displays the selected instructor's office location in the ListBox control and disables the updateOffice Button control. This control will be enabled when a change has been made to a selected office location.
JavaScript

C# C++ F# JScript VB Copy to Clipboard


Person instructor = (Person)this.instructorList. SelectedItem; if (instructor.OfficeAssignment != null) { this.officeLocation.Text = instructor. OfficeAssignment.Location.ToString(); } else { this.officeLocation.Text = ""; } // Disable the updateOffice button until a change // has been made to the office location. updateOffice.Enabled = false; //forceChanges.Enabled = false;

8.

Return to the design view of the OfficeViewer form and double-click the updateOffice Button control. The updateOffice_Click event handler is added to the code-behind file. 9. Add code that saves any changes made to office information in the officeLocation TextBox control:
JavaScript C# C++ F#

JScript VB Copy to Clipboard


try { Person currentInstructor = (Person)this.instructorList. SelectedItem; if (this.officeLocation.Text != string.Empty) { if (currentInstructor.OfficeAssignment != null) { currentInstructor.OfficeAssignment.Location = this.officeLocation.Text; } else { currentInstructor.OfficeAssignment = OfficeAssignment.CreateOfficeAssignment( currentInstructor.PersonID, this.officeLocation.Text, new byte[8]); } } else { schoolContext.DeleteObject(currentInstructor .OfficeAssignment); } schoolContext.SaveChanges(); MessageBox.Show("Change(s) saved to the database."); } catch (OptimisticConcurrencyException oce) { MessageBox.Show(oce.Message + " The conflict " + "occurred on " + oce.StateEntries[0].Entity + " with key value " + oce.StateEntries[0]. EntityKey.EntityKeyValues[0].Value); //forceChanges.Enabled = true; } catch (UpdateException ue) { MessageBox.Show(ue.Message + " Click OK to retrieve " + "the latest data from the database."); ExecuteInstructorQuery(); this.Refresh(); } finally { // Disable the updateOffice button until another // change has been made to the location. updateOffice.Enabled = false; }

10.

Return to the design view of the OfficeViewer form and double-click the officeLocation TextBox control. The officeLocation_TextChanged event handler is added to the code-behind file. 11. Add code to enable the updateOffice Button control when a change has been made to the selected office location:
JavaScript C# C++ F# JScript VB Copy to Clipboard
// Enable the udateOffice button when there is a change // to write to the database. updateOffice.Enabled = true;

The application is now complete. Press Ctrl+F5 to run the application. You can now view and update office information in the OfficeViewer form.
Handling Concurrency Conflicts

In this procedure, you will add code to the Office Viewer form that forces client changes to the database after a concurrency conflict occurs. To handle concurrency conflicts 1. Double-click InstructorViewer.vb or InstructorViewer.cs in the Solution Explorer. The form opens in the form designer. 2. Double-click the View Offices button.

The code-behind file for the InstructorViewer form opens. 3. Add the following code to the viewOffices_Click event handler so that two OfficeViewer forms will be loaded when the View Offices button is clicked.
JavaScript C# C++ F# JScript VB Copy to Clipboard
OfficeViewer officeViewer2 = new OfficeViewer(); officeViewer2.Text = "Demonstrate Conflict"; officeViewer2.Visible = true;

4.

Double-click OfficeViewer.vb or OfficeViewer.cs in the Solution Explorer. The form opens in the form designer. 5. Drag a Button control from the Toolbox to the form. Set its Name to forceChanges and its Text to Force Changes. 6. Double click the Force Changes button. The code-behind file for the Office Viewer form opens. 7. Add the following code to the forceChanges_Click event handler so that changes on the client will be forced to the server or data bound to the instructorList ComboBox control will be refreshed from the database.
JavaScript C# C++ F#

JScript VB Copy to Clipboard


Person currentInstructor = (Person)this.instructorList .SelectedItem; try { currentInstructor.OfficeAssignment.Location = this.officeLocation.Text; // Using RefreshMode.ClientWins disables the // optimistic concurrency check. schoolContext.Refresh(RefreshMode.ClientWins, currentInstructor.OfficeAssignment); schoolContext.SaveChanges(); MessageBox.Show("Change(s) saved to the database."); //forceChanges.Enabled = false; } catch (InvalidOperationException ioe) { MessageBox.Show(ioe.Message + " Click OK to retrieve " + "the latest data from the database."); ExecuteInstructorQuery(); this.Refresh(); }

8.

Uncomment the forceChanges = False (Visual Basic) or forceChanges = false; (C#) line of code in the instructorList_SelectedIndexChanged event handler so that the Force Changes button will be disabled when a new instructor is selected. 9. Uncomment the forceChanges = True (Visual Basic) or forceChanges = true; (C#) line of code in the updateOffice_Click event handler so that the Force Changes button will be enabled when a concurrency conflict occurs. 10. Uncomment the forceChanges = False (Visual Basic) or forceChanges = false; (C#) line of code in the forceChanges_Click event handler so that the Force Changes button will be disabled after changes have been forced to the database. To see the application handle a concurrency conflict, run the application (press Ctrl+F5), click View Instructors, and then click View Offices. Update an office location in the Office Viewer form, then attempt to update the same office location in the other Demonstrate Conflict form. A message box will appear notifying you of the concurrency conflict. To force the changes from the Demonstrate Conflict form to the database, click Force Changes.

Code Listing

This section contains final versions of the code-behind files for the InstructorViewer and OfficeViewer forms.
JavaScript C# C++ F# JScript VB Copy to Clipboard
using using using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Linq; System.Text; System.Windows.Forms; System.Data.Objects; System.Data.Objects.DataClasses;

namespace CourseManager { public partial class InstructorViewer : Form { // Create an ObjectContext instance based on SchoolEntity. private SchoolEntities schoolContext; public InstructorViewer() { InitializeComponent(); } private void viewOffices_Click(object sender, EventArgs e) { OfficeViewer officeViewer = new OfficeViewer(); officeViewer.Visible = true; OfficeViewer officeViewer2 = new OfficeViewer(); officeViewer2.Text = "Demonstrate Conflict"; officeViewer2.Visible = true;

} private void InstructorViewer_Load(object sender, EventArgs e) { // Initialize schoolContext. schoolContext = new SchoolEntities(); // Define the query to retrieve instructors. ObjectQuery<Person> instructorQuery = schoolContext.People .Include("OfficeAssignment") .Where("it.HireDate is not null") .OrderBy("it.LastName"); // Execute and bind the instructorList control to the query. instructorGridView.DataSource = instructorQuery. Execute(MergeOption.OverwriteChanges); instructorGridView.Columns["EnrollmentDate"].Visible = false; instructorGridView.Columns["OfficeAssignment"].Visible = false; instructorGridView.Columns["StudentGrades"].Visible = false; instructorGridView.Columns["Courses"].Visible = false; } private void updateInstructor_Click(object sender, EventArgs e) { // Save object changes to the database, display a // message, and refresh the form. schoolContext.SaveChanges(); MessageBox.Show("Change(s) saved to the database."); this.Refresh(); } } } using using using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Linq; System.Text; System.Windows.Forms; System.Data.Objects; System.Data.Objects.DataClasses;

namespace CourseManager { public partial class OfficeViewer : Form { // Create an ObjectContext instance based on SchoolEntity. private SchoolEntities schoolContext; public OfficeViewer() { InitializeComponent(); } private void OfficeViewer_Load(object sender, EventArgs e)

{ schoolContext = new SchoolEntities(); ExecuteInstructorQuery(); } private void instructorList_SelectedIndexChanged(object sender, EventArgs e) { Person instructor = (Person)this.instructorList. SelectedItem; if (instructor.OfficeAssignment != null) { this.officeLocation.Text = instructor. OfficeAssignment.Location.ToString(); } else { this.officeLocation.Text = ""; } // Disable the updateOffice button until a change // has been made to the office location. updateOffice.Enabled = false; //forceChanges.Enabled = false; } private void updateOffice_Click(object sender, EventArgs e) { try { Person currentInstructor = (Person)this.instructorList. SelectedItem; if (this.officeLocation.Text != string.Empty) { if (currentInstructor.OfficeAssignment != null) { currentInstructor.OfficeAssignment.Location = this.officeLocation.Text; } else { currentInstructor.OfficeAssignment = OfficeAssignment.CreateOfficeAssignment( currentInstructor.PersonID, this.officeLocation.Text, new byte[8]); } } else { schoolContext.DeleteObject(currentInstructor .OfficeAssignment); } schoolContext.SaveChanges(); MessageBox.Show("Change(s) saved to the database.");

} catch (OptimisticConcurrencyException oce) { MessageBox.Show(oce.Message + " The conflict " + "occurred on " + oce.StateEntries[0].Entity + " with key value " + oce.StateEntries[0]. EntityKey.EntityKeyValues[0].Value); //forceChanges.Enabled = true; } catch (UpdateException ue) { MessageBox.Show(ue.Message + " Click OK to retrieve " + "the latest data from the database."); ExecuteInstructorQuery(); this.Refresh(); } finally { // Disable the updateOffice button until another // change has been made to the location. updateOffice.Enabled = false; } } private void officeLocation_TextChanged(object sender, EventArgs e) { // Enable the udateOffice button when there is a change // to write to the database. updateOffice.Enabled = true; } private void forceChanges_Click(object sender, EventArgs e) { Person currentInstructor = (Person)this.instructorList .SelectedItem; try { currentInstructor.OfficeAssignment.Location = this.officeLocation.Text; // Using RefreshMode.ClientWins disables the // optimistic concurrency check. schoolContext.Refresh(RefreshMode.ClientWins, currentInstructor.OfficeAssignment); schoolContext.SaveChanges(); MessageBox.Show("Change(s) saved to the database."); //forceChanges.Enabled = false; } catch (InvalidOperationException ioe) { MessageBox.Show(ioe.Message + " Click OK to retrieve " + "the latest data from the database."); ExecuteInstructorQuery(); this.Refresh(); }

} private void ExecuteInstructorQuery() { // Define the query to retrieve instructors. ObjectQuery<Person> instructorQuery = schoolContext.People .Include("OfficeAssignment") .Where("it.HireDate is not null") .OrderBy("it.LastName"); //Execute and bind the instructorList control to the query. //Using MergeOption.OverwriteChanges overwrites local data //with data from the database. instructorList.DataSource = instructorQuery .Execute(MergeOption.OverwriteChanges); instructorList.DisplayMember = "LastName"; } } }

Next Steps

You have successfully mapped the insert, update, and delete operations of an entity to stored procedures. For more information about how to build applications that use the Entity Framework, see ADO.NET Entity Framework.
See Also

How to: Use a Model Defined in a Class Library (Entity Data Model Tools)

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

This topic describes how to use a conceptual model that was defined in a Visual Studio 2008 Class Library project. The first procedure in this topic describes how to use a conceptual model that was defined in a Class Library from projects other than ASP.NET Website projects. The second procedure describes how to use a conceptual model that was defined in a Class Library from an ASP.NET Website project.

To use a model defined in a Class Library from projects other than ASP.NET Website projects
1. In Visual Studio, create a Visual C# or Visual Basic Class Library project. For information about creating projects in Visual Studio, see Solutions and Projects. 2. Add a conceptual model to the Class Library project. For information about creating a new conceptual model and adding it to a project, see How to: Create a New .edmx File (Entity Data Model Tools). For information about adding an existing conceptual model to a project, see How to: Add an Existing .edmx File (Entity Data Model Tools). 3. Add a new project that is not an ASP.NET Website project to your existing solution. For information about adding a project to an existing solution, see Multi-Project Solutions. How to: Create How to: Create

4. Right-click the newly added project (not the Class Library project) and select Add Reference. The Add Reference dialog box appears. 5. Click the Projects tab of the Add Reference dialog box and select your Class Library project. Click OK. 6. Again, right-click the newly added project (not the Class Library project) and select Add Reference. 7. Click the .NET tab of the Add Reference dialog box and select System.Data.Entity. Click OK. 8. Open the App.Config file of the Class Library Project. 9. Highlight the connection string section of the App.Config file, right-click it, and select Copy. For example, copy the code that looks like this:
Copy to Clipboard
<add name="SchoolEntities" connectionString="metadata=res://*/School.csdl| res://*/School.ssdl| res://*/School.msl; provider=System.Data.SqlClient; provider connection string=&quot; Data Source=(local); Initial Catalog=School;

Integrated Security=True; MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />

10.

Open the App.Config file of the newly added project and paste the copied connection string information into the <connectionStrings> node.

Note

If the project does not have an App.Config file, you can add one by right-clicking the project in Solution Explorer, pointing to Add, and selecting New Item. Choose Application Configuration File from the dialog box that opens and click OK. You can now write code in the newly added project that will use the conceptual model that is defined in the Class Library project.

Note

You might have to set the newly added project as the startup project before building the solution. To do this, right click the project in Solution Explorer and select Set as StartUp Project.

To use a model defined in a Class Library from an ASP.NET Website project


1. In Visual Studio, create a Visual C# or Visual Basic Class Library project. For information about creating projects in Visual Studio, see Solutions and Projects. 2. Add a conceptual model to the Class Library project. For information about creating a new conceptual model and adding it to a project, see How to: Create a New .edmx File (Entity Data Model Tools). For information about adding an existing conceptual model to a project, see How to: Add an Existing .edmx File (Entity Data Model Tools). 3. Add an ASP.NET Website project to your existing solution. How to: Create

For information about adding a project to an existing solution, see Multi-Project Solutions. 4. Right-click the ASP.NET Website project and select Add Reference. The Add Reference dialog box appears.

How to: Create

5. Click the .NET tab of the Add Reference dialog box and select System.Data.Entity. Click OK. 6. The next step is to reference the Class Library project from the ASP.NET Website project. There are two ways you can do this: 1. Right-click the ASP.NET Website project in Solution Explorer and select Add Reference. The Add Reference dialog box appears. 2. Click the Projects tab of the Add Reference dialog box and select your Class Library project. Click OK. -OR3. In Solution Explorer, right-click the Class Library project and select Build. The Class Library assembly is added to the bin\Debug folder of the project. 4. Right-click the ASP.NET Website project and select Add ASP.NET Folder. Select Bin. The Bin folder is added to the project. 5. In Windows Explorer, navigate to the bin\Debug folder of the Class Library project. Right-click the project assembly (the <project_name>.dll file) and select Copy. 6. In Solution Explorer, right-click the Bin folder under the ASP.NET Website project and select Paste. 7. The next step is to make the model and mapping files available to the ASP.NET Website project. You can do this by embedding the model and mapping files as resources in the Class Library assembly, as described in the following steps. For alternative methods, see the procedure at the end of this topic ("To copy mapping and metadata files to an ASP.NET Website project"). 1. Open the App.Config file of the Class Library project. 2. Highlight the connection string information, right-click, and select Copy. For example, copy the code that looks like this:
Copy to Clipboard

<add name="SchoolEntities" connectionString="metadata=res://*/School.csdl| res://*/School.ssdl| res://*/School.msl; provider=System.Data.SqlClient; provider connection string=&quot; Data Source=(local); Initial Catalog=School; Integrated Security=True; MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />

3.

Open the Web.config file of the ASP.NET Website project and paste the copied connection string information into the <connectionStrings> node. You can now write code in the ASP.NET Website project that will use the conceptual model that is defined in the Class Library project.

Note

You might have to set the newly added project as the startup project before building the solution. To do this, right click the project in Solution Explorer and select Set as StartUp Project.

Copying Mapping and Metadata Files to an ASP.NET Website Project


The following procedures describe two options for copying model and mapping files to an ASP.NET Website project. Both methods described here are alternatives to step 7 in the procedure above. The first procedure describes how to copy the files to the Bin folder of an ASP.NET Website project and the second procedure describes how to copy the files to the App_Data folder. Do not embed the model and mapping files as resources in the Class Library assembly if you choose either of the these options. To copy model and mapping files to the Bin folder of an ASP.NET Website project 1. Double click the .edmx file in the Class Library project. The .edmx file opens in the ADO.NET Entity Data Model Designer (Entity Designer). 2. Right-click an empty area of the design surface and select Properties. 3. In the Properties window, set the value of the Metadata Artifact Processing property to Copy to Output Directory. When you select this value, the Entity Designer changes the connection string in the Class Library's App.Config file to have relative file paths. 4. In Solution Explorer, right-click the Class Library project and select Build. 5. In Windows Explorer, navigate to the Class Library output directory (bin\Debug folder) and copy the .csdl, .ssdl, and .msl files. 6. Right-click on the Bin folder under the ASP.NET Website project and select Paste.

Note

If the project does not contain a Bin folder, you can add one by right-clicking the project in Solution Explorer, pointing to Add ASP.NET Folder, and selecting Bin. 7. Open the App.Config file of the Class Library project. Highlight the connection string information, right-click, and select Copy. 8. Open the Web.config file of the ASP.NET Website project and paste the copied connection string information into the <connectionStrings> node. 9. Change the metadata entries in the connection string to be prefixed by ~\bin\. For example, the copied and modified connection string entry should look similar to this:
Copy to Clipboard
<add name="SchoolEntities" connectionString="metadata=~\bin\School.csdl| ~\bin\School.ssdl| ~\bin\School.msl; provider=System.Data.SqlClient; provider connection string=&quot; Data Source=(local); Initial Catalog=School; Integrated Security=True; MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />

To copy the model and mapping files to the App_Data folder of the ASP.NET Website

The steps for copying the model and mapping files to the App_Data folder are similar to the steps for copying them to the Bin folder. However, there are two key differences: o The .csdl, .ssdl, and .msl files should be copied to the App_Data folder of the ASP.NET Website project, instead of the Bin folder (step 6 above). Note If the project does not contain a App_Data folder, you can add one by right-clicking the project in Solution Explorer, pointing to Add ASP.NET Folder, and selecting App_Data.
o

After copying the connection string information from the App.Config folder of the Class Library to the Web.config file of ASP.NET Website (steps 7 and 8 above), change the metadata entries to be prefixed by |DataDirectory|. For example, the copied and modified connection string entry should look similar to the following:
Copy to Clipboard

Connection Strings

Send Feedback on this topic to Microsoft.

View this topic online in your default browser.

A connection string contains initialization information that is passed as a parameter from a data provider to a data source. The syntax depends on the data provider, and the connection string is parsed during the attempt to open a connection. Connection strings used by the Entity Framework contain information used to connect to the underlying ADO.NET data provider that supports the Entity Framework. They also contain information about the required model and mapping files. The connection string is used by the EntityClient provider when accessing model and mapping metadata and connecting to the data source. The connection string can be accessed or set through the ConnectionString property of EntityConnection. The EntityConnectionStringBuilder class can be used to programmatically construct or access parameters in the connection string. For more information, see How to: Build an EntityConnection Connection String. The Entity Data Model tools generate a connection string that is stored in the application's configuration file. ObjectContext retrieves this connection information automatically when creating object queries. The EntityConnection used by an ObjectContext instance can be accessed from the Connection property. For more information, see Managing Connections and Transactions.

Connection String Parameters


The format of a connection string is a semicolon-delimited list of key/value parameter pairs: keyword1=value; keyword2=value; The equal sign (=) connects each keyword and its value. Keywords are not case sensitive, and spaces between key/value pairs are ignored. However, values can be case sensitive, depending on the data source. Any values that contain a semicolon, single quotation marks, or double quotation marks must be enclosed in double quotation marks. The following table lists the valid names for keyword values in the ConnectionString. Keyword Description Required if the Name keyword is not specified. The provider name, which is used to retrieve the DbProviderFactory object for the underlying provider. This value is constant. When the Name keyword is not included in an entity connection string, a nonempty value for the Provider keyword is required. This keyword is mutually exclusive with the Name keyword. Optional. Specifies the provider-specific connection string that is passed to the underlying data source. This connection string is expressed by using valid keyword/value pairs for the data provider. An invalid Provider Connection

Provider

Provider Connection String

String will cause a run-time error when it is evaluated by the data source. This keyword is mutually exclusive with the Name keyword. The value of the Provider Connection String must be surrounded by quotes. The following is an example: Provider Connection String ="Server=serverName; User ID = userID"; The following example is not going to work: Provider Connection String =Server=serverName; User ID = userID Required if the Name keyword is not specified. A pipe-delimited list of directories, files, and resource locations in which to look for metadata and mapping information. The following is an example: Metadata= Metadata c:\model | c:\model\sql\mapping.msl; Blank spaces on each side of the pipe separator are ignored. This keyword is mutually exclusive with the Name keyword. The application can optionally specify the connection name in an application configuration file that provides the required keyword/value connection string values. In this case, you cannot supply them directly in the connection string. The Name keyword is not allowed in a configuration file. Name When the Name keyword is not included in the connection string, a non-empty values for Provider keyword is required. This keyword is mutually exclusive with all the other connection string keywords. The following is an example of a connection string for the AdventureWorks Sales Model stored in the application configuration file: Copy to Clipboard
<connectionStrings> <add name="AdventureWorksEntities" connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\Adve ntureWorks.msl; provider=System.Data.SqlClient;provider connection string='Data Source=localhost; Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;

multipleactiveresultsets=true'" providerName="System.Data.EntityClient" /> </connectionStrings>

Model and Mapping File Locations


The Metadata parameter contains a list of locations for the EntityClient provider to search for model and mapping files. Model and mapping files are often deployed in the same directory as the application executable file. These files can also be deployed in a specific location or included as an embedded resource in the application. Embedded resources are specified as follows: Copy to Clipboard
Metadata=res://<assemblyFullName>/<resourceName>.

The following options are available for defining the location of an embedded resource: Option Description The full name of an assembly with the embedded resource. The name includes the simple name, version name, supported culture, and public key, as follows: ResourceLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Resources can be embedded in any assembly that is accessible by the application. If you specify a wildcard (*) for assemblyFullName, the Entity Framework runtime will search for resources in the following locations, in this order: assemblyFullName 1. The calling assembly. 2. The referenced assemblies. 3. The assemblies in the bin directory of an application. If the files are not in one of these locations, an exception will be thrown.

Note: When you use wildcard (*), the Entity Framework has to look through all the assemblies for resources with the correct name. To improve performance, specify the assembly name instead of the wildcard. resourceName The name of the included resource, such as AdvendtureWorksModel.csdl. The metadata services will only look for files or resources with one of the

following extensions: .csdl, .ssdl, or .msl. If resourceName is not specified, all metadata resources will be loaded. The resources should have unique names within an assembly. If multiple files with the same name are defined in different directories in the assembly, the resourceName must include the folder structure before the name of the resource, for example FolderName.FileName.csdl. resourceName is not required when you specify a wildcard (*) for assemblyFullName. Note: To improve performance, embed resources in the calling assembly, except in non-Web scenarios where there is no reference to underlying mapping and metadata files in the calling assembly. The following example loads all the model and mapping files in the calling assembly, referenced assemblies, and other assemblies in the bin directory of an application. Copy to Clipboard
Metadata=res://*/

The following example loads the model.csdl file from the AdventureWorks assembly, and loads the model.ssdl and model.msl files from the default directory of the running application. Copy to Clipboard
Metadata=res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/model.csdl|model.ssdl|model.msl

The following example loads the three specified resources from the specific assembly. Copy to Clipboard
Metadata=res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/model.csdl| res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/model.ssdl| res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/model.msl

The following example loads all the embedded resources with the extensions .csdl, .msl, and .ssdl from the assembly. Copy to Clipboard
Metadata=res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/

The following example loads all the resources in the relative file path plus "datadir\metadata\" from the loaded assembly location. Copy to Clipboard
Metadata=datadir\metadata\

The following example loads all the resources in the relative file path from the loaded assembly location. Copy to Clipboard
Metadata=.\

Support for the |DataDirectory| Substitution String and the Web Application Root Pperator (~)
DataDirectory and the ~ operator are used in the ConnectionString as part of the Metadata and Provider Connection String keywords. The EntityConnection forwards the DataDirectory and the ~ operator to MetadataWorkspace and the store provider, respectively. Term Description Resolves to a relative path to a mapping and metadata files. This is the value that is set through the AppDomain.SetData("DataDirectory", objValue) method. The DataDirectory substitution string must be surrounded by the pipe characters and there cannot be any whitespace between its name and the pipe characters. The DataDirectory name is not case-sensitive. If a physical directory named "DataDirectory" has to be passed as a member of the list of metadata paths, add whitespace should on either side or both sides of the name, for example: Metadata="DataDirectory1 | DataDirectory | DataDirectory2". An ASP.NET application resolves |DataDirectory| to the "<application root>/app_data" folder. Resolves to the Web application root. The ~ character at a leading position is always interpreted as the Web application root operator (~), although it might represent a valid local subdirectory. To refer to such a local subdirectory, the user should explicitly pass ./~.

|DataDirectory|

DataDirectory and the ~ operator should be specified only at the beginning of a path, they are not resolved at any other position. The Entity Framework will try to resolve ~/data, but it will treat /data/~ as a physical path. A path that starts with the DataDirectory or the ~ operator cannot resolve to a physical path outside the branch of the DataDirectory and the ~ operator. For example, the following paths will resolve: ~ , ~/data , ~/bin/Model/SqlServer. The following paths will fail to resolve: ~/.., ~/../other. DataDirectory and the ~ operator can be extended to include sub-directories, as follows: |DataDirectory|\Model, ~/bin/Model The resolution of the DataDirectory substitution string and the ~ operator is non-recursive. For example, when DataDirectory includes the ~ character, an exception will occur. This prevents an infinite recursion.

Deployment Considerations (Entity Framework) Send Feedback on this topic to Microsoft. View this topic online in your default browser.

This topic provides information about deploying applications that use the ADO.NET Entity Framework for data access. For more information about the Entity Framework, see Getting Started (Entity Framework). The Entity Framework provides a set of tools that integrate with and make it easier to develop in Visual Studio. For more information, see Entity Data Model Tools. This topic does not describe how to use specific technologies to deploy an Entity Frameworkbased application. Visual Studio provides facilities for distributing and deploying applications, such as ClickOnce deployment. For more information, see Deploying Applications and Components in the Visual Studio documentation. The following considerations apply when you deploy an application that uses the Entity Framework:

The Entity Framework is a component of the .NET Framework starting with the .NET Framework 3.5 Service Pack 1 (SP1). You must ensure that the .NET Framework 3.5 SP1 or a later version is installed when deploying an Entity Frameworkbased application. When a conceptual model is generated by the Entity Data Model Wizard, a connection string is created in the application configuration file. Model and mapping files can be embedded as application resources or they can be copied to the output directory. By default, they are deployed as embedded application resources. Use the Metadata Artifact Processing property of the Entity Designer file to select one of these options. For more information, see How to: Copy Model and Mapping Files to the Output Directory. Ensure that the model and mapping information (expressed in conceptual schema definition language (CSDL), store schema definition language (SSDL), and mapping specification language (MSL)) is deployed together with the application and in the location specified by the connection string. For more information, see Connection Strings. When you embed model and mapping information as application resources, you must recompile and redeploy the application every time the conceptual model is updated. Because the Entity Framework is a component of the .NET Framework, it can be redistributed with your application as permitted by the .NET Framework license agreement.

See Also
Concepts ADO.NET Entity Framework Development and Deployment Considerations

Potrebbero piacerti anche