Graphics Reference
In-Depth Information
redisplayed, with the triangle absent. If we somehow
changed
the triangle, that
too would prompt a redisplay.
Unfortunately, this “watching for changes in children” extends to only a cer-
tain level of detail. If the
Collection
of
Point
s that makes up the
Polygon
changes, this in fact becomes a change in the
Polygon
itself, which prompts a
redisplay of the containing
GraphPaper
. But what does it mean for a
Collection
to change? The designers of WPF chose to make it mean “the collection of refer-
ences must change” rather than “one of the objects referred to by the references
must change.” Thus, deleting or inserting an item in the collection is treated as
a change, but merely altering an item—for example, changing the
x
-coordinate
of the first point—is not. So, if we alter the first coordinate of the first
Point
that defines the polygon, nothing happens: The
Point
itself changes, but the
Collection
containing the
Point
does not recognize the change and propagate
it. Instead, we can
remove
the
Point
from the collection, create a new
Point
with
a changed coordinate, and insert this new
Point
into the collection, resulting in a
change that propagates upward. We'll see details of this in the next section.
The choice of what constitutes a “change” in a system like WPF can have
a huge impact on performance: If it's too fine-grained, all the platform's com-
putational power will be spent watching for changes; if it's too coarse-grained,
application programmers will need to do lots of change notifications and may
eventually abandon the system-provided change tracking in favor of handling it
all themselves, because they can then do so consistently.
WPF takes user interaction, in the form of key presses, mouse clicks, and mouse
drags, and treats them as
events.
When an event is detected, it sets off a complex
sequence of activities, which ends with some event handler being called by WPF.
To be more precise, a great many event handlers may be called by WPF, but in our
case, we'll use just a single handler for an event and then mark the event as “han-
dled” so that no further handlers will be called. Sometimes the event handlers are
part of WPF; sometimes they are callback procedures provided by the application
programmer.
In particular, when WPF detects that a button has been clicked, it invokes
that button's
Click
handler. In the case of our first button (defined on line 25 in
Listing 4.3), we set the
Click
handler to be
b1Click
back in the XAML code. The
b1Click
method is rather simple: It prints a debugging message and then declares
that this click has been handled by setting a flag on the event (see Listing 4.6).
Listing 4.6: The handler for a click on the first button.
1
2
3
4
5
public void
b1Click(
object
sender, RoutedEventArgs e)
{
Debug.Print(
"Button one clicked!
\
n"
);
e.Handled =
true
;
// don't propagate the click any further
}
The
sender
in this code is the entity in WPF from which the click was relayed
to us; this relaying of clicks is part of a complex hierarchy, one that we can largely
ignore, in which a click on a piece of text displayed on a button in a grid on a
canvas will trigger responses from the text object, the button, the grid, and the
canvas. To break this chain of events, we set the
RoutedEventArgs Handled
field