by
kirupa | 7 July 2009
In the
previous page you went into your ListBox's
ItemsPanel and replaced the StackPanel with a panel
that wraps - aptly called a WrapPanel. In this page,
you will dive into another part of your ListBox's
anatomy tomake your content truly wrap.
As you can see, there is no wrapping going on.
The reason why you see your content horizontally
stacked is
because the width of the WrapPanel is scaling with
the size of the contents inside it. This means
instead of your content reaching the edges of your
WrapPanel and moving down to the next row, your
WrapPanel just decides to keep increasing its width
to accommodate the content.
To fix this, you need to go into the ListBox's
template that specifies what parts of the ListBox
actually look like. To edit your ListBox's
template, right click on it and, from the menu that
appears, go to Edit Template |
Edit a Copy.
[ let's look at what your ListBox's template looks
like ]
After you click on
Edit a Copy, you will see a dialog that says "Create
Style Resource" appear:
[ before you can see the template, you need to see a
dialog first ]
Just accept all
of the default values and press OK. Once you hit OK,
you will now be inside the ListBox editing its
template. What you see on your artboard will not be
different from what you may have seen a few seconds
ago. What will be different is what you see in your
object tree:
[ your object tree now displays the innards of your
ListBox ]
Expand your tree until
you see something shown as the ItemsPresenter appear. It
will be nested inside a Border and ScrollViewer:
[ find the ItemsPresenter by expanding your tree ]
When you select it,
notice what is selected on your artboard. It is your
collection of squares that your ListBox is hosting.
Keep your ItemsPresenter selected, and take a look
at the Width property found in the Layout category
in your Properties Inspector:
[ take a look at your ItemsPresenter's Width
property ]
Notice that the width
of your ItemsPresenter is pretty large. If you are
working with my example, the width is 1008 pixels!
This width needs to be constrained so that it is no
wider than the ScrollViewer that is the parent of
the ItemsPresenter. By constraining the width, you
ensure that your wrap panel adequately wraps its
contents instead of expanding to accomodate the
contents on the same row.
There are several ways
you can constrain the width. The easiest
(and incorrect)
way is to specify an actual, numerical value in the
Width property. For example, setting a value like
300, will cause your WrapPanel to properly wrap the
content:
[ while it may seem to wrap, there are problems with
this approach ]
While this is pretty
easy to do, you should not do this. The reason is that
your applications will probably be resizable where
the size of your listbox will increase or decrease
depending on how much space there is available. If
your ItemsPresenter's width is set to a fixed value,
then the contents of your listbox will not scale
appropriately. They will remain at whatever width
you specified.
The correct approach
is to bind the width of your ItemsPresenter to the
ActualWidth of its parent ScrollViewer control. This
is a standard element-to-element binding, so go back
to your Width property and click on the tiny square
to the right of the Width property. Once you have
clicked on the tiny square (known as the Properties
Marker), a menu will appear. From this menu, click
on the Data Binding item:
[ select Data Binding from the Width property's
Properties Marker ]
After you clicked on
Data Binding, the Create Data Binding dialog will
appear:
[ this dialog will allow you to specify the various
binding properties ]
From the Create Data
Binding dialog, click on the Element Property tab.
Once you have clicked on the Element Property tab,
you will see a variant of your object tree appear on
the left-hand column. Select your ScrollViewer from
this tree, and from the Properties list on the right
column, select the ActualWidth property:
[ you want to bind to your ScrollViewer's
ActualWidth property ]
Once you have done
this, click OK to accept the changes you have made
and to close the Create Data Binding dialog. If you
look at your Width property now, notice that you see
an actual value specified as well, but the
difference is that the value is dependent on
something else - hence the yellow border indicating
a binding is present:
[ the yellow color indcates that the value isn't
local but from a binding ]
Well, that is it. You
have successfully performed the two big steps needed
to have your listbox wrap its contents. If you test
your application now, notice that your items
successfully wrap:
[ the wrapping - I see it! ]
Best of all, if you
make your application's size a bit larger, your
listbox and its contents resize accordingly:
[ the wrapping behavior is as you would expect ]
You are almost done
with this tutorial. There are just a few loose ends
we need to tie up, so let's do that in the next
page.
Onwards to the
next page!
|