Pixel perfect positioning of list elements in WPF

21. januar 2010

This is something I had to look up several times myself, so I thought I should write it down for later reference.

I was building a simple level editor for SilverTile (more about that in another post later) and wanted to place the map tiles in a grid-like fashion. This could be done using my dynamic Grid control, but I wanted pixel perfect control of where the tiles were placed on screen. Note the gaps between the grid rows in the following screen shot.

Fail!

Fail! Note the gaps between the tiles!

To do this I would need to use a Canvas control and place each tile using the Canvas.Left and Canvas.Top properties to set the position.

Win! This is what we want. Pixel perfect placement of our images!

The challenge is that the Canvas control doesn’t support list binding directly, so you must use some other control to accomplish this. Luckily there is a solution available by using the ItemsControl class. The ItemsControl is a list control that lets you specify which control should be the root element. In our case we will use a Canvas control as the root and then use data binding to specify the values for the Canvas.Left and Canvas.Top properties.

Using the ItemsControl

To exemplify the usage of the ItemsControl I first created a simple view model for the application. This was simply a list of TileData objects where each describes one tile. Each TileData object has an image source and Left and Top properties. The Left and Top properties tell where the tile should be placed on screen. In a real application your view model would probably be more complex and possibly calculate the positions based on some other data.

// The TileData class describes a tile
public class TileData
{
    public Uri Image { get; set; }
    public double Left { get; set; }
    public double Top { get; set; }
}

Now, with the view model in place we can setup our application.

<Grid Name="Root" Loaded="Root_Loaded">
    <Grid.Resources>
        <Style x:Key="ContainerStyle">
            <Setter Property="Canvas.Left" Value="{Binding Left}" />
            <Setter Property="Canvas.Top" Value="{Binding Top}" />
        </Style>
    </Grid.Resources>
    <ItemsControl Name="map" ItemsSource="{Binding}" ItemContainerStyle="{StaticResource ContainerStyle}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas Width="{Binding Path=Root.ActualWidth}" Height="{Binding Path=Root.ActualHeight}" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Image Source="{Binding Image}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

Here we have a Grid as the root element of the application. I’ve used a grid since it will be sized dynamically when the window is resized, something the Canvas control doesn’t. We then have the ItemsControl that has its ItemsSource bound to our data context. The ItemsSource is the list of TileData objects that is used to describe the map.

And now we get to the interesting part: The ItemsControl.ItemsPanel property. This property defines which control should be the container into which all our list items are placed. By setting this to a Canvas control we end up with a layout where you can set your child controls position as you want.

Further we have the ItemsControl.ItemsTemplate that tells how you want each object in your ItemsSource to be rendered. In our case we render it as an Image control with its source bound to the Image property of your TileData object.

The final missing part is how we place our controls. The obvious way to do this would be to set the Canvas.Left and Canvas.Top properties of our Image control by binding them to the Left and Top properties of our TileData object. One would expect this to work but if you try it you will see that all our controls are placed at the top left corner of the canvas, with Canvas.Left = 0 and Canvas.Top = 0. The solution is to create a style that sets the Canvas.Left and Canvas.Top properties and to assign that to the ItemContainerStyle property of the ItemsContainer. By doing this you will see that our Image controls are placed correctly where we want them.

Using Snoop to find out what really happened here

To understand what really happened here we need to examine the control hierarchy our Xaml code generates. A good tool to do this is Snoop. It lets you attach to a running Wpf application to examine all properties of all generated controls.

Using Snoop to look at our applications control hierarchy

Look at the above screen shot. Here you can see the control hierarchy of the GridWin application. If you look down the tree you will find an ItemsControl control with a child Border control. The Border contains an ItemsPresenter Control that contains a Canvas. This Canvas control is the one we assigned to our ItemsControl.ItemsPanel property.

The Canvas contains a bunch of ContentPresenter controls that each contains one Image control. And this is the reason why we cannot set the Canvas.Left and Canvas.Top properties of our Image controls directly. Since the images are contained in the ContentPresenter controls we need to set the properties here instead. And this is what we do when we set the ItemContainerStyle property. The style is applied to the ContentPresenter which is placed at the correct position.

Using the code

I am using this approach in a level editor application for SilverTile that I will be writing about soon. The application stores the map as a list of Tile objects where each Tile knows which row and column they should be placed in. The Canvas.Left and Top properties are then bound to the X and Y properties that are caluclated by multiplying the row or column number with the tiles width or height in pixels. The tile list is used as the ItemsSource for an ItemsControl that renders the tiles at the wanted position.

The ItemsControl is available in Silverlight as well as in WPF, so this approach works just as well there. The only challenge is that the binding of the Canvas' size to the size of the Root grid cannot be done in Silverlight 3 since it doesn't support element to element binding. This is fixed in Silverlight 4 though, so there you should be able to use the exact same approach.

kick it on DotNetKicks.com

.NET, Silverlight, WPF , ,

Comments

22.01.2010 10:14:22 #
Pixel perfect positioning of list elements in WPF

You've been kicked (a good thing) - Trackback from DotNetKicks.com
27.01.2011 16:29:03 #
why you delete my comments?
27.01.2011 21:34:01 #
Did I delete your comments? I may have mistaken a comment as spam and deleted it by mistake. Sorry in that case!
Sudarshan
Sudarshan
15.05.2011 15:09:59 #
Very useful post. I was required to build a dynamic grid which could bind to a datasource. Both of your posts helped me. This one and the post about dynamic grid. Thanks a bunch.
11.11.2013 05:52:21 #
Ensures close collaboration, innovation, transparency and agility not only in our near shore delivery and client engagement models but also in our approach.
11.11.2013 18:44:54 #
Have you learned all the charisma of logo designing? Do you think now yourself a master in the designing field? Well, you have to learn yet more things to be a successful designer. It is not just an important thing to invest all your creativity with great attention.
14.11.2013 16:44:11 #
Antares Agile Solutions is a nearshore software development company located in Heredia, Costa Rica with experience in agile software development delivery model and Microsoft technologies.
02.12.2013 18:42:28 #
We are always conscious about our products; we notice and find out errors by reviewing the creation. We ensure about top quality services than all other Costa Rica software development companies. You will get 100% quality service within a faster and safe method.
05.12.2013 17:25:16 #
Si usted no tiene portones  y desea reemplazar los que ya tiene, por favor visite nuestra galería de fotos para ver algunos ejemplos de estilos arquitectónicos de hierro forjado, aluminio y lámina insulada americana.Todas nuestros portones están hechos con los mejores materiales del mercado, somos flexibles a su necesidad.
05.01.2014 18:19:34 #
Brampton Limo Rental Company is here to handle all your transfer needs. We offer a world-class fleet of the newest and finest limousines available and are equipped with the most current amenities and communications.
06.01.2014 18:00:17 #
We estimate that you think a limo is an excessive luxury. That is not true. We offer both the best quality and best prices in Brampton limo hire. You will be surprised how realistic our Limo rental prices are. In addition, no compromise with the services is permitted. Our limos are even very good if you want to appear at the Airport in a luxury vehicle. What can better display prestige than a shiny limo? We promise that you will for all time arrive in time and in style. If you wish, you are able to hire a limousine in Brampton 24 hours a day, 365 days a year, whenever you need it.
07.01.2014 18:01:08 #
Goodtime Limousine Services is most Prestigious Limousine Service. The owner of the company and his team are committed to giving the Finest Quality Service at very Competitive Rates. When you contract Goodtime Limousine Services you will receive a high quality late model vehicle with a professional trained chauffeur whose number one concerns are safety and services. Whether you choose a luxury sedan, 6, 8, 10, 12, 14, 16, 18, 20, 25 or 30 passenger limousines, for associates, corporate executives, or a night on the town, you can depend on our company to provide the highest quality and standards at a competitive price. Your business is a valued asset to our company.
07.01.2014 20:10:44 #
Our wedding limo Toronto hire company specializes in offering top-notch limousine hire services for weddings. As an experienced company in the wedding limousine hire, we understand the needs of our customers better than any other wedding limo hire company. We know that your wedding is the most important day of your life, you will want nothing but the best for your wedding and that is why we put in extra efforts to take care of your wedding limo Brampton hire needs.
08.01.2014 20:42:28 #
Brampton Limo Rental takes pride in providing service like no other. Our commitment to confidentiality and client satisfaction sets us above the competition. No matter what the event is, our team will provide the special touches that will keep you coming back! We lighten your load.
09.01.2014 09:00:44 #
Goodtime Limousine Services customizes each Limousine Charter, working with your plans for Birthday's, Graduations, Proms, Marriages, Airport pickups or any other special occasion, to make your special event even better.
09.01.2014 16:40:51 #
Our wedding limo Toronto hire company specializes in offering top-notch limousine hire

services for weddings. As an experienced company in the wedding limousine hire, we

understand the needs of our customers better than any other wedding limo hire company.

We know that your wedding is the most important day of your life, you will want nothing

but the best for your wedding and that is why we put in extra efforts to take care of

your wedding limo Brampton hire needs.
10.01.2014 17:29:33 #
Goodtime Limousine Services customizes each Limousine Charter, working with your plans for Birthday's, Graduations, Proms, Marriages, Airport pickups or any other special occasion, to make your special event even better. No other Limousine Company in the region will give you that "Peace-of-Mind" that Goodtime Limousine Services can… Reliability, Affordability, backed by Honesty and Integrity at the right price.
10.01.2014 19:01:15 #
We offer outstanding expert services for all wedding Limo Toronto hire needs. All

individual needs and requirements are catered for and you will also be allocated your

own personal coordinator to deal with your booking. We like to add this personal touch

to ensure that your most important day goes exactly to plan and you enjoy the dream

wedding Limo Mississauga you deserve. At Wedding Limo Brampton rental, we pride

ourselves on providing service to all our clients.

12.01.2014 18:09:31 #
We are very prompt and our limousines will arrive at the appointed venue ahead of time

so that you don't have to wait in anxiety for the arrival of your wedding limo. All our

chauffeurs are well trained and they know how to make you feel special and how to please

you. When you approach us for your wedding limousine hire needs you can be sure that you

are in the safest hands. We offer the most professional wedding limo Toronto hire

services.
12.01.2014 19:56:45 #
Goodtime Limousine Services customizes each Limousine Charter, working with your plans for Birthday's, Graduations, Proms, Marriages, Airport pickups or any other special occasion, to make your special event even better. No other Limousine Company in the region will give you that "Peace-of-Mind" that Goodtime Limousine Services can… Reliability, Affordability, backed by Honesty and Integrity at the right price.
13.01.2014 16:47:31 #
Our professional chauffeurs are very knowledgeable of the City of Toronto and surrounding areas. You can enjoy a carefree evening as you travel to your destination in comfort and luxury!
14.01.2014 17:45:29 #
Our wedding limo Toronto hire company specializes in offering top-notch limousine hire services for weddings. As an experienced company in the wedding limousine hire, we understand the needs of our customers better than any other wedding limo hire company. We know that your wedding is the most important day of your life, you will want nothing but the best for your wedding and that is why we put in extra efforts to take care of your wedding limo Brampton hire needs.
16.01.2014 20:14:27 #
Limo services for such magnificent occasions are mostly exceptional. Only most excellent cars are Limo Mississauga availed for those who are getting married to make sure that you create a grand look and a smooth grander exeunt. The services that are typically obtainable will need you to build a reservation of the best journey that you would wish to present transport for your special day.
04.02.2014 21:29:07 #
Our visa services gives you detailed and updated information on how to apply for any visa (business visa, tourist visa, and holiday visa) the required forms and the current visa fees. Our Vision is to be your preferred choice for VISA assistance. We believe, if we keep our Customers Happy, they keep us in the Business.
13.02.2014 17:59:10 #
Our Vision is to be your preferred choice for VISA assistance. We believe, if we keep our Customers Happy, they keep us in the Business.

18.02.2014 22:22:10 #
We understand the fair price fair job model however we can tailor our services to all clients including custom homes. Please call us now! (905)-469-0092
20.02.2014 17:27:15 #
At Airport renowned Limousine, our chauffeurs are qualified professionals and have the understanding to provide a assortment of transportation services as well as airport limo hire, trade meetings otherwise night outs. So if any quarry or need information please feel free to contact us we waiting for you.
26.02.2014 06:55:31 #
Our aim is not just an airport transfer to your destination in Canada but also you’re relaxed ride from till the end point of trip. It is to transport a full enclose of professionalism attached through customer service so if any quarry or need information please feel free to contact us we waiting for you.
03.03.2014 17:02:43 #
We for all time finding way to serving peoples technology related service genuinely, our I.T Firm progressive with information knowledge always, we are given that online and offline technological service, DTH recharge In Bangladesh one of them.

05.03.2014 18:00:12 #
Tata Sky is a leading Direct-to-Home (DTH) service provider. Subscribe to Tata Sky DTH and experience the revolution in digital TV viewing so we are Bangladeshi Tata Sky DTH service provider. Please feel free to contact us.


12.03.2014 16:46:26 #
We for all time finding way to serving peoples technology related service genuinely, our I.T Firm progressive with information knowledge always, we are given that online and offline technological service, Dish TV Bangladesh In Bangladesh one of them.

Add comment




  Country flag

The number (5) not with letters. This is to stop spammers.

biuquote
  • Comment
  • Preview
Loading