by
kirupa | 9 December 2007
In the
previous page, you saw why our code worked the
way it did. So, while you were able to accomplish
what you set out to do, you can still make some
improvements, and in this and subsequent pages, we will look at one
such improvement where we increase the separation
between the data and the user interface.
Right now, if you made any modifications to your
AddButton_Click event handler, you will almost
certainly have to ensure that the five lines of code
required to have your data binding work are
unmodified. What if you decided later to add a
Remove button? Will you be copying the same lines of
code and swapping out the Add functionality with a
Remove functionality? What about having new windows
(and classs) where you would still want the ability
to have data added to your PeopleList collection?
If the previous paragraph hasn't scared you,
let's say that further down the road,
you decide to make a modification that involves
adding a few extra fields to your Person class.
Instead of just taking a user’s name, you also
specify their date of birth and address. Now, if you
want to represent that information in the UI, you
have go back and find every instance where you
connect to the ObjectDataProvider and make sure to
add the missing pieces of information so that your
UI properly displays the new fields you added to your
Person object.
As you can see, this is turning out pretty messy.
As your application grows, the complexity is growing far
faster because your design isn’t particularly
modular. Currently, adding new functionality requires you
modifying a chain of existing functionality in order
to not break anything. If this is becoming a problem for our
(very) simple application, imagine how
painful changes to more substantial applications
will be?
There are numerous ways of separating the view from
the model, and there are various degrees of
correctness in doing so. Because this is more of a
designer-centric tutorial, I am going to a present a
good-enough solution that increases the level of
flexibility in your application without requiring a
lot of coding.
The first thing we’ll do is remove as much of the
data-related information from our Window1.xaml.cs
file. From Visual Studio, add a new C# Class file
called PeopleData. Once you have created that class,
Visual Studio will automatically have it opened for
you for editing.
Right now, all you will see is the following:
- namespace
BindingToPeople
- {
- class
PeopleData
- {
- }
- }
First, from your Window1.xaml.cs, cut and paste
both your Person and PeopleList classes and paste
them below your newly created PeopleData class
definition. Your PeopleData.cs file should look like
the following:
- namespace
BindingToPeople
- {
- class
PeopleData
- {
- }
-
- class
Person
- {
- public
string
PersonName
- {
- get;
- set;
- }
- }
-
- class
PeopleList
:
ObservableCollection<Person>
- {
- public
PeopleList()
- {
- this.Add(new
Person
{
PersonName
=
"Link"
});
- this.Add(new
Person
{
PersonName
=
"Gordon
Freeman"
});
- this.Add(new
Person
{
PersonName
=
"Mario"
});
- this.Add(new
Person
{
PersonName
=
"Master Chief"
});
- }
- }
- }
Be sure to build your application (F6) to make
sure that everything works and any missing
namespaces are added. For example, you will probably
need to resolve ObservableCollection because the
namespace required to support that class is usually
not provided by default, but those are all things
building your project will let you know:
[ building your project frequently lets you spot and
(hopefully) fix errors quickly ]
Anyway, if you run your project, notice that
everything still works! You are able to add a new
person just like before. Moving the Person and
PeopleList classes to the new location doesn’t
really break anything, but it does move us closer to
our stated goal of separating the visuals from the
data.
Our next order of business will be to greatly
simplify what our AddButton_Click event handler
does. Right now, all of the functionality required
for attaching to the existing data provider and
adding new data is located here. In the
next
page, let’s shift some of this responsibility to our
PeopleData class.
Onwards to the
next page!
|