Tải bản đầy đủ (.pdf) (14 trang)

Visual studio 2010 part 26 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (391.07 KB, 14 trang )

234 Microsoft Visual Studio 2010: A Beginner’s Guide
Notice that the class in this code is named NewOrder, illustrating that a window is just
another class. As you know, you can instantiate classes and call their methods, which is
the technique you’ll use to open this window from the NewOrder_Click event handler in
the code-behind of the MainWindow window.
In practice, you’ll populate the NewOrder window with whatever controls you need
to implement a new order. You would populate the window by dragging and dropping
controls, just like the Button in this example. However, we’ll skip that task for now
because the current focus is on adding code to the NewOrderButton_Click event handler
so that you can learn how to code an event handler and open another window. Go back to
the NewOrderButton_Click event handler in MainWindow.xaml.cs and add the following
code:
C#:
private void NewOrderButton_Click(object sender, RoutedEventArgs e)
{
NewOrder newOrd = new NewOrder();
newOrd.Show();
}
VB:
Private Sub NewOrderButton_Click(
ByVal sender As System.Object,
ByVal e As System.Windows.RoutedEventArgs)
Handles NewOrderButton.Click

Dim newOrd As New NewOrder
newOrd.Show()

End Sub
Since NewOrder is a class, you can instantiate it as shown in the preceding code
example. To open the window, call the Show method.
Now you have a WPF program that handles events and opens new windows. Press


F5
to run the program. Click New Order and observe that the New Order window appears.
The New Order window isn’t very useful because it lacks controls and data management.
The next section shows you how to populate window controls with data.
Working with Data in WPF
This section builds upon what you learned in Chapter 7 by showing how to bind data
to WPF controls. Binding is the process of populating and retrieving data to and from
controls. You’ll learn how to show data in your user interface. The examples in the
Chapter 8: Building Desktop Applications with WPF 235
following sections show you how to perform create, read, update, and delete (CRUD)
operations via WPF. You’ll first see how to insert data, using VS tools to construct a data
entry screen. Then you’ll learn how to read, modify, and delete data through a DataGrid.
We’ll start with single value binding. To make the examples more interesting, I added
extra fields to the tables. You can review Chapter 7 to learn how to add fields to a database
and create a LINQ to SQL entity model.
Setting Up a Data Source
Before you can bind to data in the window, you’ll need a data source to work with data. To
get started, update the Order table, created in Chapter 7, so that it has the following fields:
● OrderID, int, primary key, auto-increment
● CustomerID, int
● OrderDate, datetime
● Location, varchar(50)
● Amount, money
Then update the Customer table with the following fields:
● CustomerID, int, primary key, auto-increment
● Name, nvarchar(50)
● Age, int
● Birthday, datetime
● Income, money
With the database updated, you can add a LINQ to SQL entity model to the project,

using the same techniques described in Chapter 7.
To add the data source for binding, open the NewOrder window in the Designer, and
select the Data | Add New Data Source menu, which opens the Choose A Data Source
Type window, shown in Figure 8-11.
There are different ways to connect to a data source, including directly to the database,
via a Web service, via an object, or through SharePoint. This book shows you how to use
LINQ to SQL, which is connected by selecting Object and clicking Next, which shows the
Select The Data Objects window in Figure 8-12.
236 Microsoft Visual Studio 2010: A Beginner’s Guide
Figure 8-11 Choosing a new data source
On the Select The Data Objects window, check the box next to each object you want
to bind in your application. The example in this chapter uses Customer and Order objects,
which you can see checked in Figure 8-12. Clicking Finish will configure the data source
for use in the application. You can view data sources by selecting Data | Show Data
Sources, shown in Figure 8-13.
The Data Sources window allows you to create controls on a form that are bound
to each field of a data source. In the Data Sources window in Figure 8-13, you can see
that both Customer and Object are listed with their fields. What is also evident is the
icons associated with each field. The icons describe what type of control should be
associated with each data field. For example, Name on Customer is a TextBox because it is
nvarchar(50), but Birthday is a calendar because it is a datetime. If you don’t like a default
control type for a field, you can change it by selecting the field and choosing another
control type from the drop-down list, as shown in Figure 8-14.
Chapter 8: Building Desktop Applications with WPF 237
Figure 8-12 Selecting data objects
Figure 8-13 The Data Sources window
238 Microsoft Visual Studio 2010: A Beginner’s Guide
In Figure 8-14, the CustomerID is being changed to a ComboBox because it makes
more sense to give the user the option of selecting a customer from a list for a new order,
rather than typing in an ID number. Also, the object defaults to a Grid control, but in this

first example, we only want to add a new order, meaning that the control type should be
changed to Detail. To create a new order form with controls bound to order data, select the
Order object in the Data Sources window and drag and drop the order onto the Designer
of the NewOrder window. Figure 8-15 shows this new window.
Figure 8-15 shows how VS added a Grid layout with two columns and a row for each
field in the Order table. As explained, the CustomerID is a ComboBox and the OrderDate
is a calendar. VS was smart enough to put spaces between the words in the labels, too.
VS didn’t put the Save button on the screen, which is something you would need to do
to save the data. In addition to adding controls to the Designer,
VS added the following
CollectionViewSource control to the NewOrder window’s XAML:
<Window.Resources>
<CollectionViewSource x:Key="orderViewSource"
d:DesignSource="{d:DesignInstance my:Order, CreateList=True}" />
</Window.Resources>
Figure 8-14 Changing the control type for a field
Chapter 8: Building Desktop Applications with WPF 239
This is another reason it’s important to be able to read the XAML for a window, so
you can see how objects like this are added and configure them if you need to. In our
case, we need to know the name of the CollectionViewSource, which is orderViewSource.
We need to add an Order object to the CollectionViewSource so that the controls that are
bound to it have a place to save data that the user enters. Press
F7 to see the code that VS
added to the Window Loaded event handler, as follows:
C#:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
System.Windows.Data.CollectionViewSource
orderViewSource =
((System.Windows.Data.CollectionViewSource)

(this.FindResource("orderViewSource")));
// Load data by setting the
//CollectionViewSource.Source property:
// orderViewSource.Source = [generic data source]
}
Figure 8-15 Controls bound via a data source
240 Microsoft Visual Studio 2010: A Beginner’s Guide
VB:
Private Sub Window_Loaded(
ByVal sender As System.Object,
ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded

Dim OrderViewSource As System.Windows.Data.CollectionViewSource
= CType(Me.FindResource("OrderViewSource"),
System.Windows.Data.CollectionViewSource)
'Load data by setting the CollectionViewSource.Source property:
'OrderViewSource.Source = [generic data source]
End Sub
The preceding skeleton code gets a reference to OrderViewSource, but that’s all. The
commented portion of the code suggests how you might populate that control. However,
we aren’t interested in populating OrderViewSource with data because the purpose of
this screen is to insert a new record. Instead, the proper approach is to bind an empty
object. Later, you’ll see how to pull the data from that object after the user fills in the
form and clicks on the Save button. In addition to assigning a blank Order object to
OrderViewSource, we need to populate the ComboBox that holds the list of customers
and their IDs. The following code is a revision to the Window_Loaded event handler
that assigns a blank Order object to the OrderViewSource and binds customers to the
ComboBox holding customers:
C#:
private void Window_Loaded(object sender, RoutedEventArgs e)

{
var orderViewSource =
FindResource("orderViewSource") as CollectionViewSource;
orderViewSource.Source =
new List<Order>
{
new Order
{
OrderDate = DateTime.Now
}
};

customerIDComboBox.ItemsSource =
from cust in new MyShopDataContext().Customers
select cust;
}
Chapter 8: Building Desktop Applications with WPF 241
VB:
Private Sub Window_Loaded(
ByVal sender As System.Object,
ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded

Dim OrderViewSource As CollectionViewSource =
CType(FindResource("OrderViewSource"), CollectionViewSource)
OrderViewSource.Source =
New List(Of Order) From
{
New Order With
{
.OrderDate = DateTime.Now

}
}

CustomerIDComboBox.ItemsSource =
From cust In New MyShopDataContext().Customers

End Sub
The previous re-write of Window_Loaded accomplishes two things: assigning an order
to orderViewSource and populating customerIDComboBox with customers. The Order
object assigned to the Source property of orderViewSource is empty, except assigning
today’s date to OrderDate, demonstrating how you can set default values. When the user
fills out the form on the page, WPF will populate this Order with data because it is data
bound, through orderViewSource, to the controls on the screen. This section showed you
how the data is assigned to the controls, but some controls require even more attention to
ensure they display the data correctly. The next section expands upon what you must do to
get the ComboBox to work.
Configuring a ComboBox
A couple of the particularly more complex controls to configure are ComboBox and
ListBox. The reason is that they have a few different properties that must be set to ensure
that whatever is selected can be read and correctly referenced back to the original data
source. This section doesn’t try to teach you about WPF binding because there are entire
books with multiple chapters related to the subject. Instead, you’ll learn an essential skill
for helping you figure out how to set the right properties on a ComboBox control. In so
doing, you’ll get a better feel for the features of VS that help you perform the task of
setting up controls.
242 Microsoft Visual Studio 2010: A Beginner’s Guide
The previous example assigns the results of a LINQ query for Customer objects to
the customerIDComboBox, but this is only the first step to getting the combo box to work
properly; you must specify which property of Customer must display, which property of
Customer maps to Order, and which property of Order to bind the selected item to. To do

this binding, open the NewOrder.xaml file in the Designer, select the combo box, and set
the properties as specified in Table 8-2.
The following XAML shows the results of the settings you should make in the
Properties window, based on Table 8-2:
<ComboBox DisplayMemberPath="Name"
SelectedValue="{Binding Path=CustomerID}"
SelectedValuePath="CustomerID"
Grid.Column="1" Grid.Row="1"
Height="23" HorizontalAlignment="Left"
Margin="3" Name="customerIDComboBox"
VerticalAlignment="Center" Width="120">
</ComboBox>
DisplayMemberPath and SelectedValuePath are names of the properties from the
Customer objects bound to the ComboBox. However, the SelectedValue syntax uses a
binding expression, where Path identifies the property of the Order that will be assigned
to with SelectedValuePath. The binding for SelectedValue is based on the Order object
Table 8-2 ComboBox Properties for Data Binding
Property Explanation
ItemsSource We set this through code in the Window_Loaded event. It holds the collection
of objects that will appear in the combo box. You need two properties, one to
display and one for the key of the object being displayed. The key will be used
to map the object back to the database or associate the object in a relationship
with another object. In the case of the Customer list, the properties of interest are
Name for display and CustomerID for key. Since we are creating a new Order,
the CustomerID for the Name selected in the combo box will be assigned to the
CustomerID field of the Order. That way, when the Order is saved, its database
record will have the CustomerID for the customer the user selected.
DisplayMemberPath This is the Name property from each Customer object bound to the combo box.
SelectedValuePath As explained for ItemsSource, you need to associate the selected Customer with
the Order being created. SelectedValuePath is the name of the Customer object’s

key, which is CustomerID in our example.
SelectedValue When saving the Order, you must have the key associated with the selected
customer. The SelectedValue is a binding to the property of the Order that will
be set with the key from the selected Customer.
Chapter 8: Building Desktop Applications with WPF 243
that was assigned to the Source property of the orderViewSource in Window_Loaded.
Coming full circle, the orderViewSource is what the default binding of the containing
Grid layout is based on; it was set when dragging and dropping the Order data source
onto the Design surface.
Now you have an input form that displays data, allowing the user to enter new
order information. After the user fills in the form, you need to save the data, which is
discussed next.
Reading and Saving Data
Next, you’ll want to save the order when a user clicks Save. To do this, add a Button
control to the form, set its Content property to Save, and set its Name property to
SaveButton, which you learned how to do earlier in this chapter. Then double-click Save
to create a Click event handler like this:
C#:
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
CollectionViewSource orderViewSource =
FindResource("orderViewSource") as CollectionViewSource;

List<Order> ordList =
orderViewSource.Source as List<Order>;
Order ord = ordList.FirstOrDefault();

var ctx = new MyShopDataContext();

ctx.Orders.InsertOnSubmit(ord);


ctx.SubmitChanges();

MessageBox.Show("Order Saved!");
}
VB:
Private Sub SaveButton_Click(
ByVal sender As System.Object,
ByVal e As System.Windows.RoutedEventArgs)
Handles SaveButton.Click

Dim OrderViewSource As CollectionViewSource =
CType(FindResource("OrderViewSource"), CollectionViewSource)

244 Microsoft Visual Studio 2010: A Beginner’s Guide
Dim ordList As List(Of Order)
ordList = CType(OrderViewSource.Source, List(Of Order))
Dim ord As Order
ord = ordList.FirstOrDefault()

Dim ctx As New MyShopDataContext

ctx.Orders.InsertOnSubmit(ord)
ctx.SubmitChanges()

MessageBox.Show("Order Saved!")
End Sub
Before the SaveButton_Click event handler ends, it shows a message box to the user
with a status message, Order Saved. The MessageBox class has several overloads of the
Show method that allows you to specify buttons, icons, and more.

So far, you’ve learned how to create an input form for adding a new record to the
database. The next section will build upon this by showing you how to view, modify, and
delete records with the DataGrid.
Using the DataGrid
The DataGrid is the best option for working with data that must be shown with multiple
rows and columns. This section will show you how to show, update, and delete items with
a Grid. First, we’ll display orders.
We’ll build off the data source created in the previous example to show data in a Grid.
First, you’ll need to open the Data Source window by selecting Data | Open Data Sources.
The preceding section specified the CustomerID as a ComboBox. If you’re following
along, you’ll want to change CustomerID to a TextBox by clicking on CustomerID for
the Order object in the Data Sources window and selecting TextBox. Change the control
type of Order from a form to a Grid by selecting the combo box for the Order object in
the Data Sources window and selecting the DataGrid option. Open the MainWindow
.xaml file in the Designer and drag and drop Order from the Data Sources window to the
Designer. Remember there is a New Order button that you’ll want to move to the bottom
of the form. Also, add another button, set its Name property to UpdateButton, and set its
Content property to Update. Position the New Order and Update buttons at the bottom of
the form. Resize and move controls and form so they look like Figure 8-16.
Just as with the form view in the preceding section, VS added a CollectionViewSource
to the window when adding the Order to the Designer. The following Window_Loaded
event handler provides the Order data to display in the Grid:
Chapter 8: Building Desktop Applications with WPF 245
C#:
private MyShopDataContext m_ctx = new MyShopDataContext();

private void Window_Loaded(object sender, RoutedEventArgs e)
{
CollectionViewSource orderViewSource =
FindResource("orderViewSource") as CollectionViewSource;


orderViewSource.Source =
from ord in m_ctx.Orders
select ord;
}
VB:
Dim m_ctx As New MyShopDataContext

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

Figure 8-16 Displaying information in a Grid
246 Microsoft Visual Studio 2010: A Beginner’s Guide
Dim OrderViewSource As CollectionViewSource =
CType(FindResource("OrderViewSource"), CollectionViewSource)

OrderViewSource.Source =
From ord In m_ctx.Orders
Select ord

End Sub
This code loads orders into the Grid. Notice that the MyShopDataContext, m_ctx, is a
field outside of the Window_Loaded method handler. It is raised to field level so that the
same instance can be used in multiple methods. As you may notice from Figure 8-16, there
is also an Update button on the form. Double-clicking the Update button produced the
following Click event handler that saves changes, such as updates and deletes, to the Grid:
C#:
private void UpdateButton_Click(object sender, RoutedEventArgs e)

{
m_ctx.SubmitChanges();

MessageBox.Show("Updates and Deletes Saved!");
}
VB:
Private Sub UpdateButton_Click(
ByVal sender As System.Object,
ByVal e As System.Windows.RoutedEventArgs)
Handles UpdateButton.Click

m_ctx.SubmitChanges()

MessageBox.Show("Updates and Deletes Saved!")

End Sub
When you run the program, you can add new rows, modify the cells of existing rows,
or delete a row by selecting the row and pressing
DELETE on the keyboard. After making
changes to the Grid, click Update, which will call the previous UpdateButton_Click event
handler.
To understand how this works, remember that the Window_Loaded event handler
assigned a collection of Order objects to the CollectionViewSource, orderViewSource,
which is data bound to the Grid. Each row of the Grid is bound to an instance of an Order
object. Each Order object is part of the LINQ to SQL MyShopDataContext. Since we are
Chapter 8: Building Desktop Applications with WPF 247
using m_ctx, which is a field, both the Window_Loaded method and the UpdateButton_
Click method are using the same object instance. When making changes in the Grid,
those changes are saved in the Order objects for the changed rows. The Order objects
notify MyShopDataContext that they have changed, which is a service of LINQ to SQL.

The UpdateButton_Click method uses m_ctx, which is the MyShopDataContext that
knows about the changes to the Order objects. Calling SubmitChanges on m_ctx saves all
changes to the database.
You might need to read the preceding paragraph more than one time to understand
how this is working. If it’s still fuzzy, it might be helpful to review the language chapters
earlier in this book to understand how objects are instantiated and used, and review
Chapter 7 to ensure you understand the data manipulation picture.
Summary
While there is much more to learn about WPF, this is a beginner’s guide and intended to
give you the essentials so that you can begin moving in the right direction. Y
ou should
now be able to create a new WPF project. You learned about layout controls and how they
allow you to manage how controls appear on your form. A section explains the windows
involved in working with controls. While there are many controls you can use that ship
with both WPF and many third-party products, remember that the concepts are relatively
the same for using the controls: drag and drop, and configure properties. Most applications
work with data, so this chapter builds upon what you know about LINQ to SQL and
shows you how to apply this data management knowledge to create user interfaces that
users can work with to manage their data.
This chapter introduces you to working with desktop applications, which are still very
necessary and popular. However, a lot of today’s applications are written for the Internet.
The next chapter shows you how to build Web applications with ASP.NET.

×