ImageButton control for Windows Phone 7
Posted on January 14, 2011
Filed Under Windows Phone 7 | 5 Comments
While implementing one of my Windows Phone 7 application I realized that even tough there is ApplicationBar control but there is no separate control for it’s button. To be more precise, there is no control you can use anywhere else except ApplicationBar. It seems to be strange as I found that kind of control in People view of my phone. Anyway I decided to create simple control that will achieve that functionality. I will call it ImageButton. Here’s how I did that.
First I needed to create UserControl. It will be used by our application to provide our desired behavior. So, I added new Class and named it accordingly.
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace ImageButtonControl { public class ImageButton : Button { } }
As you can see I inherited from Button. This is because generic button provides the most of features we need for our control. Then, I implemented constructor for the class.
public ImageButton() { DefaultStyleKey = typeof(ImageButton); }
In the constructor I set DefaultStyleKey. What it does is to look for style that has target type of ImageButton and use it for the control. Without that line of code our template won’t be applied to the control.
The next step is to create properties that will hold our images for two states: Normal and Pressed. Maybe it is not the best solution to provide two bitmaps but for our simple control it is good enough. I will post more advanced ImageButton control in future that will work in similar way than ApplicationBar. You will have to provide only one bitmap and control will do the rest (add circle and invert image on click). But, back to our simple version. I defined two properties one named Image and the other named PressedImage. Each property consists of definition of Dependency Property and definition of Property itself. Both are needed to use of TemplateBinding described below.
public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(ImageButton), null); public ImageSource Image { get { return (ImageSource)this.GetValue(ImageProperty); } set { this.SetValue(ImageProperty, value); } } public static readonly DependencyProperty PressedImageProperty = DependencyProperty.Register("PressedImage", typeof(ImageSource), typeof(ImageButton), null); public ImageSource PressedImage { get { return (ImageSource)this.GetValue(PressedImageProperty); } set { this.SetValue(PressedImageProperty, value); } }
Now, is time to design style for our control. First we will add our control to Page for easy access in Expression Blend. After opening it, we add namespace at top of XAML, below definition of system namespaces. In my case it looks like this:
<phone:PhoneApplicationPage x:Class="ImageButtonControl.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ImageButtonControl" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True">
Then I added our control somewhere that it will be visible. In example:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <local:ImageButton Image="bookmark.png" PressedImage="bookmark_pressed.png" Width="48" Height="48"/> </Grid>
Also we need to add normal and pressed bitmaps to the project. This is crucial as you can stuck for long time thinking why your control doesn’t work. I also set initial size of the button. It is important because as you will see below we won’t change Image Stretch property and leave it to default value (Uniform). To see the control on the page you need to build project first. Without that Visual Studio won’t be able to apply style to your control as it doesn’t know anything about our control.
Now, we are ready to start designing our style for the control. To do so we open the project in Expression Blend. Then, we open the page and right click on our control on the page. Next, we choose Edit Template → Create Empty…
We set name of style and where it should be defined. The most sensible place to create style in is Application. You could also include the style in separate file and connect it to your application resources with Merged Dictionary but it is out of scope of this article. The values on the dialog should look similar to one from image below:
Next step is to add two images to Grid that was created automatically by Expression Blend. I named them NormalImage for image that stores Normal State image and PressedImage for image that stores Pressed State image. You should see something like that on my example image:
Ok, we have now our images. Now we need to bind our Image Properties that we defined in our class to our Image controls that we have just added. We do that by selecting image and clicking on small box in right of Source to open Advanced options. Then we choose Template Binding and Image property for NormalImage and PressedImage property for PressedImage.
Next we need to define states of button. These are special behaviors of Button (in this case) like Normal or Pressed states. We open States tab and choose Base. The base state is initial state of our control – the state that will be visible just after the button shows. The base state should have NormalImage shown and PressedImage hidden. We do that by choosing image and set Visibility property. Next state we need to set is Pressed state. In this state we shows PressedImage and hide NormalImage.
And this is all that we have to do. The result may look like one below:
As I mentioned above the goal of this control is simplicity. I am planning to develop more advanced control, so track my Twitter or visit this blog once again in the future.
Download source code: ImageButtonControl.zip
Comments
5 Responses to “ImageButton control for Windows Phone 7”
Leave a Reply
Hi Przemyslaw Chruscicki !
The first thanks for image button control u had done but i want my image button also have text at center like normal , with background is images , can u teach me how i can do that ?
Best Regards !
Tom
Sorry for a long delay. What exactly do you want to achieve ? ImageButton that looks exactly the same as one from ApplicationBar (with text above) ? Can you describe more ?
Thanks,
PC
Hi bro !
Exactly i wanting to make button like menu in my game
here is screenshot what i want to do :
http://123viet.net/tomcodon/AiLaTrieuPhu_ScreenMain.jpg
button with background and text at center or left,right
Can you teach me how i can do that ?
Tom
PC
I am using a variation of imagebuttons you have posted here in my WP7 projects.
I have written an article
Windows Phone 7 Help and About files using HTML and Isolated Storage images in CodeProject.
The link is
http://www.codeproject.com/KB/windows-phone-7/WP7Help.aspx
Thanks for the good work.
Vijay
Thank you so much Przemyslaw! This was exactly what I was looking for! As I don’t have experience with expression blend, I was very happy with your clear step-by-step description. I lost you in the last part abut states, but when I looked at the source code everything was clear.
Marcel.