by
kirupa | 23 August 2009
In Silverlight and WPF, when working with
UserControls and Behaviors, you may find yourself in
situations where you need to call a method or access
a property that is stored in the parent. This parent
can be anything - it could be a container or it
could be another UserControl. Accessing what you want in those
locations is not as straightforward as you may
imagine it to be.
To describe this scenario a bit more, let's look
at the following diagram where I am simplifying to a
world where the parents and children are just
Window, UserControl, or Behavior types:
In this short tutorial, I will describe a few
things:
-
How to access the contents of your
application's root Page or Window regardless of
where you are.
-
How to access the contents of a parent user
control such as the Yellow user control calling
something in the Blue user control.
-
How Behaviors are a bit different.
The syntax for both WPF and Silverlight can be a
little different, so if there are any differences, I will provide both versions
for the scenarios I list above.
The most common type of cross-usercontrol
communication you would engage in is one where you
are trying access the root of your application. The
root of your application in Silverlight is of type
UserControl, and the root of your application in WPF
is of type Window. This distinction is important
because it results in a varying syntax.
The syntax for accessing the root UserControl in
Silverlight is:
-
UserControl
rootPage
=
Application.Current.RootVisual
as
UserControl;
The syntax for accessing the root Window in WPF
is:
- Window
rootWindow
=
Application.Current.MainWindow
as
Window;
The above code will hook into your root and
provide you with access to any types that are
available to UserControl and Window.
So now, you get access to the root element, but
you probably don't want this particular approach.
The problem is that casting to both UserControl and
Window is very generic, and it contains no
references to anything you may have done. Any
elements you added in XAML or any properties and
methods you added in your code-behind file are
hidden from view.
The reason is actually pretty simple. The root of
your application is not actually UserControl or
Window. It is something derived directly from
UserControl or Window. To fix this, you need to cast the returned value
to the actual type of your root element. By default,
in Expression Blend, the type of your root
usercontrol is MainPage in Silverlight:
In WPF, the type of your root window is
MainWindow:
This means, you will need to make just some minor
tweaks to your code. For Silverlight, your code now
becomes:
- MainPage
rootPage
=
Application.Current.RootVisual
as
MainPage;
For WPF, your code is:
- MainWindow
rootWindow
=
Application.Current.MainWindow
as
MainWindow;
While MainPage and MainWindow are new types, they
are directly derived from UserControl and Window
respectively. This means that any properties or
methods you would expect to see either in
UserControl or Window are still accessible to you. In your own projects, if you are not
using Expression Blend, be sure to set the type of
the root element appropriately because you cannot
assume that MainWindow and MainPage will actually
exist.
Ok, you just learned how to access your root
directly from whereever you are inside your
application. Let's look at how to access other
parents using a more general solution on the
next page.
Onwards to the
next page!
|