Posts Tagged ‘ Windows Phone ’

The Image Control

The Image Control allows me to display images in my Silverlight Windows Phone 7 application. To have a first closer look at this control I just created a new project and dragged an Image Control to my main form. In my properties window I have a little helper, an ellipsis button next to the Source property. The source property is going to define where the image should come from that will be displayed:

I am going to click the ellipsis button to add a new image to my project:

When I click the Add button I can choose the image I want to display. So, let me go ahead and do that:

What happened is that Visual Studio created an Images folder in my Solution Explorer that contains my image:

The next thing is that that path  has kind of a strange look:

“/Images;” is going to refer to the deployment package. What comes after the semicolon will reference that file within the deployment package once it is loaded onto the phone.

This altogether, this path, is actually referred to as an URI, Uniform Resource Identifier. It’s kind of like an URL, except an URI can reference any location, not just a web based location. In this case it is referencing the location internally within a file.Anyway, when I am going to click the OK button, I see my image loaded in the Image Control in my main form:

There’s only one tiny, little problem. When I start moving the dimensions of the Image Control around, it stretches my image out of proportion:

 

How can I resolve that? In my properties window right under the Source property is the Stretch property. By default it is set to Fill, that means it fills the whole area of the Image Control. If I resize that control, it still fills that area completely regardless of the dimensions.

Let’s set it to Uniform. That will keep the perspective correct. But it only will honor either the horizontal or the vertical proportion of the image within the Image Control, but it will not crop it:

When I set it to UniformToFill, it will honor both the horizontal and the vertical proportion of the image:

Depending on how I adjust the size or the dimensions of the Image Control, there’s going to be a lot of clipping involved. So, it just depends on how I am planning on using that Image Control.

For now I am going to set it back to Uniform. For my purposes I can determine exactly how much space I want to give this image.

The next step is that I am programmatically going to change from this to another picture.

First of all I am going to need a button, because I want this to fire off when somebody clicks the button. So I am double clicking that button to get to my C# code.

Now I first have to add another image to my Images folder. For that I that little drop down arrow next to the “Add New Item” Button right under “Edit” in my menu and select “Add Existing Item”:

That will let pop up the “Add Existing Item” dialog and I am already in the images directory I navigated to earlier. I select the image I want, click the Add button and my image is added to the Images folder:

Now I want to create a new instance of an object that will essentially represent the new image I am going to load in. And then I am going to set the Source property to that instance of my Image object. The object that I am going to use is called a BitmapImage. In the constructor I am going to use this uriSource:

In other words, I am going to tell the location as I am creating a new instance of the BitmapImage where it can find the picture that I want to use.This is where I am going to create a new URI, and I am going to pass in the string that represents the location within the deployment package where Silverlight is going to be able to find that second image. Plus I am going to tell it what type of Url it is looking at. It’s a relative Url, it’s relative to the deployment package.

The second step of this process is to set the Source equal to myImage:

Let’s run the application:

 

Let’s go a step further and see how to allow the image to be zoomed in and how to allow the user to scroll around inside the image.

For that I go to my XAML page, and there I can surround my Image Control with a ScrollViewer. Then I remove the Margin of my image completely and change the Width to 800, and also the Height:

When I run the application I can use my mouse cursor to simulate a finger to scroll around in the image:

 

To be continued…

 

Advertisement

Input Controls in Silverlight

So far I didn’t spend much time on Input Controls. When I needed an example, I just quickly created a project that probably would contain a textbox control, a textblock control and/or a button control. But as I have seen on other applications, there are other types of Input Controls that are used to allow the user to input different types of information. Today I am getting a little overview over the major Input Controls used in Silverlight.

I am not using the toolbox, I am just typing in all the definitions into my XAML pane. That’s giving me the opportunity to get more familiar with XAML. After all, I am a beginner, and beginners need the extra exercise, right?

Also, what I am doing is using a Grid to have all my Input Controls nicely arranged. More exercise. In this blog post you can find more information about Layout controls in Silverlight from a beginner’s view.

I have defined 7 rows and 3 columns:

Let’s move on and place some input controls in each of the cells I just defined.

I am going to begin with a TextBox control. The TextBox allows the user to type in values using the input scope or rather the on screen keyboard. I also created a TextChanged event that fires off each time the user types in a new value:

The next control I want to show is a PasswordBox. This looks very similar to the TextBox. The PasswordBox has limited utility though. It is useful in situations that I want to allow the user to type in values that can’t be seen by others who might look over the user’s shoulder. Its declaration is almost identical to that of the Textbox. There are two subtle differences. First there is a PasswordChanged event available. And secondly instead of the Text property here the Password property is used:

Assuming I need a simple yes or no answer by the user, I could let him type in the value in a textbox, or I could use yet another control, the CheckBox control. The CheckBox control limits the entry of the user to true or false:

A few things I want to point out here. First of all the CheckBox has a content property which is what is displayed to the right of the CheckBox itself. Second there is a Checked event that I can handle. So whenever the user taps the CheckBox it will fire off an event. And third, this is a perfect demonstration of how to span a single control across multiple columns using the ColumnSpan property. I knew the content would not fit into the first column, so I allowed it to use more space. I allowed it to span over all three columns.

If I would want the user to choose between multiple options I would use the RadioButton control instead:

Each RadioButton is independent, but the GroupName property, that I set to “myGroup” on both of my RadioButtons, is the property that keeps them collected together. They “work as a team”. In other words, when one RadioButton is selected, any other RadioButton in the same group is automatically deselected. I’ve set the default IsChecked property on the first RadioButton to “True”. It’s not really necessary to do that, but in a running application it is a good visual reminder for the user to see what the intend of those RadioButtons is. The user sees that he needs to select one of these. If the by default preselected one is not the right one for you, make sure to click the other one.

The RadioButton control also supports a Checked event, just like the CheckBox, which I did not use for now.

What I need to keep in mind is, that when I go to retrieve the value, I have to be a little creative about how to find out which RadioButton of those two was selected.

But first I want to add another Input Control. Let’s say, I have a number of options to choose from, and I want to allow the user to select one or more values from that list, I would choose a ListBox control. The ListBox is a little bit more complicated than these other controls, because a ListBox will contain other controls inside of it, ListBoxItem controls:

In my ListBox I have eight ListBoxItems, each of them has a Content property that I am just setting to a simple string.

Let’s run the application:

Everything’s nicely in place. Just the ListBox doesn’t show all items at the same time. I can use my mouse cursor there, to simulate a finger on a real device, and scroll through my list. I can manage the selected item with the SelectionChanged event.

At this point I am running into a little bit of a problem. I need to add a Button control to the very bottom of my main form. I need to figure out a way to accomplish this, because right now there is no free space. I’ve run out of space vertically. I need some way to allow the user to scroll down to see the rest of my application. Luckily there is an easy way to retrofit this functionality through the use of a ScrollView control. The ScrollViewer creates a little window to the information that it contains within it.

So I am going back to before my ContentPanel in my XAML code and add a ScrollViewer:

I just have to make sure that I don’t forget the ScrollViewer ending tag after my Content Grid.

I essentially now wrapped a ScrollViewer around my Content  Grid.

Now that I have a little space I want to add my button. First I have to add another row to the Grid.RowDefinition collection. Now I can add my Button definition after the ListBox definition:

Now I can scroll down to the very end of that application until I actually can see the just created button:

I could have dragged the ScrollViewer from the toolbox to my main form, but since everybody says as a Windows Phone developer I have to understand XAML, let’s not even go there. After all, my code is working, so why change it?

Anyway, the button indicates that there is some action to be taken when the button is clicked. In XAML I can set properties for my button, like the appearance or the content, but I kind of rely on the button to provide a click event, so that I can write code to handle. By right clicking on that click event in my XAML code I can navigate directly to that click event handler in C#. What I want to do there is to retrieve all the values of the controls that I added:

To be continued…

Working with Silverlight Events

An event is simply a method that’s executed when some action takes place. This action is typically by a user when the user clicks a button using their finger, but could also be triggered by something that happens internally in the application.

Each control defines a number of events that it can respond to. Being a developer I get to pick and choose the events that I want to execute when that event is fired. Or I could choose to ignore events, like I did before with a simple input control like a textbox control. On the other hand, if I needed to, I could respond to every single event in some way. It’s probably never necessary, but it would be possible if really needed.

To see a list of events for every control, I would go to the properties window and click on the events tab. For example, I drag a button on my main form, and then I can see every event that the button control can handle:

I could choose any event for my button control and double click it.

Another way would be double clicking my button to create the default event handler, which for a button would be a click event.

In both cases it is creating the event handler to my code behind, my C# file, where I can then add my code.

Yet another way is to type within the XAML code editor:

IntelliSense is helping me there.

If I look to my C# code now, I notice that VS already created that click event there for me.

I’ve just added a second button and a TextBlock to my main form. In my XAML editor I type in the same click event for the second button:

Notice, that this button has the name “button2”, but the click event still says “button1”.

In my code behind I am just adding two lines of code inside the click event handler:

First of all I rely on the parameter “sender”. This parameter gives me access to the control that triggered the event. The second parameter, this “RoutedEventArgs e”, deals with routed events. At a high level Silverlight passes event notifications down from the parent to the child to its child and again to its child until the event is finally routed to the last child.

Anyway, to make the event handler as generic as possible, the sender is of type object. Object is a data type from which all other data types are based. The sender could be any data type. So, in order to use this in my code I had to do a little “work”. I somehow had to turn it into a button in order to access the properties available to buttons, like the Name property.

That’s what I did. I created a variable, called myButton of type Button, then I set it equal to the sender parameter. But first I had to cast the sender object into a button type. Casting is a temporary data conversion from one data type to another. I just need to convert it long enough to be able to create a reference to that object in memory and treat it like a button. In order to do that I used the Casting syntax , where I use an opened and a closed parenthesis with the type I want to cast to, and prefix it to the object I want to cast. In this case this would be  “(Button)sender”. Once I have a reference to the button that actually fired off this event handler to that object, and once I get it into the correct type, type button, then I can access what I want to get from that control from that point on.

I have two buttons with different names, both using the same event handler. Inside the event handler I inspect the sender object, cast it to a button, so I can get to its properties. I determine which button actually sent that click event, and then write the result to a TextBlock.

So, let’s wrap it up. Some events are triggered by a user’s action, like clicking a button. Other events are triggered by the phone itself, for example when the user indicates he wants to open the application, the first page of the application is loaded up, when all the controls are positioned correctly and the application as almost ready to be displayed to the user, a loaded event is fired on that most top PhoneApplicationPage object.

This is the perfect place to do some initialization of the input controls, like filling them with data from a server, that can be grabbed from the internet. Or data from local storage can be grabbed.

Let’s type in that loaded event:

So, the point is: While some events are triggered by something that the user does, some events are triggered by something that the application does or that the phone does. And a developer can choose to ignore or handle as many events as he wants to.

 

To be continued…

%d bloggers like this: