The world's coolest Laptop

Computing technology

The perfect UI for a logon screen

Communications has made our world tiny

Cant live without one

Showing posts with label Windows Phone 7(WP7). Show all posts
Showing posts with label Windows Phone 7(WP7). Show all posts

Friday, November 23, 2012

Scrollable Textbox Silverlight/WP7

I was doing an Application that required a Scrollable TextBox. Unfortunately the textbox that is available via the default WP7 controls is not scrollable. Naturally, i was looking for alternative controls/workarounds. But this time Googling did not work. There wasn't any decent work around available. I was about to quit doing the application, but thanks to a friend of mine i didn't. He found of a work around for this :) (had the eureka feeling :P ). OK enough story, lets get down to business.

Solution: 

Key thing: Set the height of the texbox to Auto, attach a scrollviewer to it & enclose it inside a grid.

By scrollable textbox generally, we mean that the container inside the textbox control (that holds the text) should be scrollable. Instead of that, what we are going to do is set the height of the textbox to "Auto" and put it inside a stackpanel and attach a scrollviewer to this textbox. The idea here is that, instead of moving the container that holds the text, we are moving the entire textbox. Since the height is set to auto, the textbox height extends automatically. To give the user an effect thats is similar to scrolling textbox, it should be enclosed inside a grid. The grid's dimensions should match that of the required textbox.

Code:

<Grid Height="390" HorizontalAlignment="Left" Margin="140,42,0,0" x:Name="grid1" VerticalAlignment="Top" Width="478"  >
            <ScrollViewer VerticalScrollBarVisibility="Auto" >
                <StackPanel Width="469">
                <TextBox AcceptsReturn="True" x:Name="ScrollableTextBox" Height="Auto" MinHeight="320" Width="454" TextWrapping="Wrap"/>
                </StackPanel>
            </ScrollViewer>

            </Grid>

 
Catch:

The catch in this solution is that, as the user keeps typing in and the textbox is just about to extend beyond the region of visibility, the textbox doesn't automatically scroll. The user has to use the scroll gesture and manually pull it up. An alternative is to (Though i haven't tried this) use the Height changed event of the textbox and when it crosses the threshold, programatically scroll up.This would give the feel of a proper Scrollable Textbox.

Hope this solution helped :) 


Saturday, February 18, 2012

Detect Alarm Entry–Wp7

If you  have used Alarms and Reminders in Wp7 Mango SDK, you will notice that reminders can be detected by having a separate page in the application. But unfortunately there is no such detection mechanism available for Alarms. By detection mechanism what I mean is that- the differentiation between the app launch due to alarm and manual launch. What if the developer wanted to do something after the alarm has occurred? how does he detect that? I had the same problem and I am going to share the work around here. Its not a perfect substitute and may not be valid for all cases.

Microsoft has made the detection mechanism for knowing whether an alarm has occurred- private.The variable called p_completed which shows the status cannot be accessed. So practically there is not much we can do.

Prerequisites:

  • You should be familiar with WP7 app development
  • You should know about alarms and reminders in WP mango. If you are not aware of it check out this link- code samples of WP7

So lets get started.

For the sake of demonstration I am going to first create an application that adds and alarm and also can detect  the same. So I open a new project, select Silverlight for windows phone 7 and load the project. Then drag and drop a button into the designer area. And place the following code in the click event. This is for creating a new alarm

try
            {
                Alarm a = new Alarm("first");
                a.BeginTime = DateTime.Now.AddSeconds(40);
                ScheduledActionService.Add(a);
            }
            catch
            {
                ScheduledActionService.Remove("first");

 

/*assuming that alarm already exists exception occurs due to that */

Alarm a = new Alarm("first");
a.BeginTime = DateTime.Now.AddSeconds(40);
ScheduledActionService.Add(a);
           }

 

I create an alarm object a with the alarm name as first. I set the begin time as 40 seconds from the current time. And I add it to the ScheduledActionService. I handle the exception that is caused if the alarm named first already exists by removing it first and then creating it again.

Now I am going to detect whether the alarm launch has occurred in the PhoneApplicationPage_Loaded a event handler of Main page. The code is as follows ::

 

try
           {
               ScheduledAction a1 = ScheduledActionService.Find("first");
               if ((a1.IsEnabled == true) && (a1.IsScheduled == false))
               {
                   MessageBox.Show("Alarm detected");
               }

ScheduledActionService.Remove("first");
           }
           catch
           {

           }

Now launch the application click add alarm and then close the application. Wait for the alarm pop up. Tap the pop up and there you go. Get a message saying that alarm is created.

How it works:

First I have declared an object a1 of schedule action and I pull the alarm first and store it in a1. This is done using ScheduledActionService.Find("first"). There are two key aspects to this. For an alarm to have occurred and after that the application is launched then the alarm must have been enabled but its not scheduled. So I check the above condition & then display a message saying alarm is detected. Now why did I add the remove alarm command. I do this because the next time the user launches the application manually, the state of alarm would be same. As I said earlier this work around is not a perfect substitute but can help sometimes. So you need to again create the alarm for the next use.

Bottleneck :

This workaround doesn’t work perfectly if the user clicks dismiss and then launches the application manually. In this case the application will say alarm is detected though its not the case

You can download the source code from here.

Monday, January 9, 2012

Buttons in Listbox–WP7

Its really wonderful and dynamic to have a button associated with every element of listbox. This is really advantageous if you running short of screen space (often the case in phone applications).

This is an extension of data binding techniques.But how do we know which element’s button is tapped because while defining the button using binding we give a single event handler. One more constraint not in many cases we will not know the number of items in the listbox. So lets see what can be done about this.
1[6]

Prerequisites:
  • You should be aware of the data binding techniques in WP7. If not please read my blog post on data binding to listbox in wp7
  • You should have basic understanding of wp7 app development
  • You should have the Windows phone 7 SDK installed
Here I am going to start from the point where I assume you have done data binding as I said in my data binding blog post. If not I would recommend you to download the source code from my previous blog and start off with that or if you are a Pro start of with from scratch.
Now in the listbox.itemtemplate tag I where we have add elements to define the structure of an item, add a button at the last in the textgrid. The code is
<Button Name="hello" Margin="0,100,0,0" Height="70" Content="Tap" />
Now select the button and goto the properties, select the events tab, and double click on the field besides the click ( Basically create an event handler for the click ). You will be redirected to the C# page. Come back to the XAML page. You should see the code of the button modified as follows..
<Button Name="hello" Margin="0,100,0,0" Height="70" Content="Tap" Click="hello_Click" />
Now the entire code of the item template will look something like this.
<ListBox Height="373" HorizontalAlignment="Left" Name="listBox1" VerticalAlignment="Top" Width="439" Margin="0,41,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="-200,0,0,0" Name="masterpanel">
<StackPanel Width="100" Height="100" Margin="0,0,0,0" Name="imagepanel">
<Image Source="pic.png" Stretch="Fill" />
</StackPanel>
<Grid Margin="300,-100,0,0" Name="textgrid">
<TextBlock Text="{Binding name}" FontSize="25" Foreground="Gold"/>
<TextBlock Text="{Binding phone}" Margin="0,50,0,0" FontSize="25" Foreground="Gold"/>
<Button Name="hello" Margin="0,100,0,0" Height="70" Content="Tap" Click="hello_Click" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>



Alright. But still I have not told you the solutions for the constraints Lets get to that now. There is a property called the TAG associated with many elements and its also present for button. Now we are going to use this to know from which element the button was tapped.
Untitled[7]

As we can see first lets bind some data to the tag property. The data should be such that it should be unique to every element. Here I am going to bind the name. When I tap the button I will get a message displaying the name.
So first lets add Tag="{Binding name}" to the XAML code of the button. So the button code should be looking like this.
<Button Name="hello" Margin="0,100,0,0" Height="70" Content="Tap" Click="hello_Click" Tag="{Binding name}"/>

Now in the event handler where you add the items to the listbox and bind them ( in the previous blog post example it should be the event handler for the add button), the moment you add the tag gets associated with the button of that item.Here since I am using name that is already used in textblock the code is same. However if you would like to add something else make sure you add the property and make necessary modifications in the XAML code.

Now the next step is to retrieve the tag. Now this syntax is the key thing of the entire process. In the event handler hello_Click use the following code to retrieve the tag.
string name = (string)((Button)sender).Tag;
Basically we are typecasting the object sender into a button since its called from a button click and accessing the tag property and type cast the output to a string and then store it in the variable name.

Now we have retrieved the tag. Next step is to process and get the required output. Here my aim is restricted to just displaying the name of the item I call
So I am going to write the following code
MessageBox.Show("The name of the item you tapped is " + name);
So the event handler function hello_Click should have this code:
string name = (string)((Button)sender).Tag;
MessageBox.Show("The name of the item you tapped is " + name);


So that’s it. Launch the application tap on the button in every item and notice the output.
3[3]

You can download the source code from here.

Sunday, January 8, 2012

Item template & Data binding with listbox–WP7

ADDING PICTURES AND FORMATTING THE DATA IN LISTBOX

The listbox is an element that is used to display a list of data. The default manner in which the data is presented in the listbox sucks. So we are going to format this by using a technique called data binding. I am going to show how to add pictures and do some formatting with the data.

Advantages:

  • Enables you to present multiple data in a single element. For example a single element can display the name, address phone number and a picture
  • The design seems really better with data binding when compared to a list of words
As we can see the default listbox(left pic) is really not that good. We are going to transform that to the style shown in the second picture(right pic)

Lets try to format the listbox now.

 

Prerequisites:

  • You should have a basic understanding of wp7 app development
  • You should have the Windows phone 7 SDK installed

The first step is to encapsulate your data or the properties that you want into a single element - class. For the sake of demonstration I am going to add a picture a name and phone number  (i.e., those things that you want to display in a single item of listbox). This class I am going to write it in the Csharp page that is the .cs file associated with every XAML page.

public class list
        {
            public string name {get; set;}
            public string phone {get; set;}
        }

Now go to the designer page ie., the XAML page and drag and drop a listbox into the UI. This will automatically generate the XAML code for listbox. Now we need to change the template of every item of the listbox. So we are going to do some modifications to the XAML code of the listbox.

<ListBox Height="373" HorizontalAlignment="Left" Name="listBox1" VerticalAlignment="Top" Width="439" Margin="0,41,0,0">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Margin="-200,0,0,0" Name="masterpanel">
                            <StackPanel Width="100" Height="100" Margin="0,0,0,0" Name="imagepanel">
                            <Image Source="pic.png" Stretch="Fill" />
                            </StackPanel>
                            <Grid Margin="300,-100,0,0" Name="textgrid">
                            <TextBlock Text="{Binding name}" FontSize="25" Foreground="Gold"/>
                                <TextBlock Text="{Binding phone}" Margin="0,50,0,0" FontSize="25" Foreground="Gold"/>
                            </Grid>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

How it works?

The first xaml tag that is inserted is the <ListBox.ItemTemplate> which is used to define the item template of that listbox. The second tag <DataTemplate>is where we define how the data is structured in the item template . Then we create a stackpanel called master panel that holds all the items we need in the item. Here our listbox needs a picture, 2 textblocks one for name and the other for phone number. Now we create another stackpanel called image panel for holding the image and give the image source and other details like the source in the tag.Next we create a grid to hold the 2 textblocks

Now notice that the property text of both the textblocks are set as

Text="{Binding name}"  & Text="{Binding phone}"

This is Data binding meaning dynamically get the data and use it here. Notice that the property of binding is set as Binding name and Binding phone where name and phone are the exact property names of the class we declared earlier. If they are not exact the data wont bind properly.

Here for the image I have not used data binding . But if you want different images for different elements you can use the same technique of data binding to the source property of the image.

Key thing:

The key thing thing is that I have altered the margins of every element so that every element gets arranged the way I want it. So you need to this based on trial and error basis which is slightly annoying but never the less worth the pain. This process is going to drive you crazy but do have patience.

Another key thing is that you need to make sure that all properties in the class are public and the class is public. Else even if you add data to your listbox it will appear blank.

This process can also be done using Expression blend which has a easy to use graphical interface and a lot more.

Continuing …. :

Now I add a button and handle the click event so that it adds items to the listbox. I created a new object of the class called obj1. Now I set the properties name and phone no with some sample data (here I use listbox’s count + 1 just for the sake of demonstration). And then add that object to the listbox item list.

private void button1_Click(object sender, RoutedEventArgs e)
        {
            list obj1 = new list();
            obj1.name = "Name " + (listBox1.Items.Count + 1);
            obj1.phone = "Phone - 100" + (listBox1.Items.Count + 1);
            listBox1.Items.Add(obj1);

        }

 

And that’s all its over. Launch the application!!

You can download the source code from here. .

If you have any queries please leave a comment.

Saturday, July 30, 2011

Build action property - WP7:The property could not be read/written because the language service returned an unknown error



The property could not be read/written because the language service returned an unknown error

One of the most frustrating errors I have faced till now while developing app for Windows phone 7(WP7). I didn’t get any proper solution when I googled. So I wanted to share what solution I found for this error.

The story goes like this. I finished my windows phone 7 app – Finance Manager beta(listed in my blog). When i submitted to the App hub it said,

The [NeutralResourceLanguage] attribute is missing on the entry Linkassembly.

Well i was puzzled by this and as every person does I googled. And I got the solution to this problem easily. It was because fortunately many of the people had faced the same problem. I found 2 ways to solve this problem either manually through or using wizards. As a programmer I went for the manual option. The manual solution is to go to assemblyinfo.cs file. This file can be accessed in the solution explorer under the properties section. Then add the following commands.

using System.Resources; //on the top

[assembly: NeutralResourcesLanguage("en")] //In the section where all the attributes are given.

Else you can right click on the properties tab and under the build tab below default namespace. Click on the assembly information. In that under the Neutral language drop down select the language you want.

Normally this should solve the problem.

But unfortunately, my problem did not get solved, I gave the new XAP after adding this tag also, App Hub returned the same error. So I went to the second option of using the wizard. But when I clicked Assembly information all the fields were empty. I was wondering what the problem was. So I decided to manually feed in the values in to the fields. But when I clicked ok, Visual studio threw an error

The property could not be read/written because the language service returned an unknown error

I googled this, but unfortunately no solutions. I had no other choice but to solve the problem myself. So as I looked in to various things in my project settings, properties etc, I did find what the problem was.

There is a property of all the items in the project called Build Action. If this property is set wrong then the functionality of the app will be totally different even if one has done the coding perfectly. When I saw what the Build action property of Assemblyinfo.cs ,it was set to content. It should have been compile. I changed it to compile. Immediately all the fields in Assembly information of the properties of the project were loaded properly(As I described earlier, all the fields were empty but now they were loaded with values ).

Make sure your Build action property for all items is set properly. For example if u set the property of the DLL’s used for Localization should be set to content. If you set it to resource, though DLL have been created properly you will not get the output. So as such, Build action property if not set to the proper value can be really bugging.

Tuesday, July 12, 2011

Frames in Windows phone 7 - The concept of vanishing grids



One of the major challenges while designing a mobile application is that size of the mobile screen is very small compared to the regular screen size of the laptops or desktops. So it becomes really tedious in terms of the design even though most of the smart phones today have the scroll feature. Particularly when we want to design a page with many options, the page gets really crammed up with buttons. So what do we do? Recollect the concept of frames in a website. By frames what is I mean is that frames allow the designer to present multiple documents in a single interface.

While I was designing my windows phone 7 app, my main aim was user friendliness. It is very tedious for the user to navigate to different pages every by clicking numerous buttons. It doesn’t present a single interface for all the functions. For an end user it is not comfortable as it involves too much of navigation, interface keeps changing, No centralization etc. So when I decided to do something about this, as everyone does I googled my query with different tags. I ended up seeing something about Pivot and panorama controls which was also there in the offline training kit. Well I did find it interesting but at the same time, I thought of doing some experimentation. So here i provide my approach to the problem without using any of the pivot or panorama controls.

I started recollecting what grids were (Equivalently the canvas and stack panels). I recollected there is a property called height of a grid. What if I can make that height zero and resize it whenever I want to. So if I have multiple grids and make one appear at a time and at the same time make others not appear (make their height 0), it would solve the problem. Indeed, this approach did work. You can also use the same approach with width of the grid.

The first step is to categorize the options you have. The second step is to decide how you want the interface to be. Next step is the design an interface. I designed the page as follows. On the top section of the page, I had buttons denoting the categories and bottom of the page I had an area to display the associated items for that category like textbox, buttons etc.

When I click category one, the set of associated items should appear in the display area. Now how exactly do you achieve this is the next question. To do this first create different grids for different categories with each grid encapsulating the items belonging to that particular category. Let’s say for the sake example that the names of the grids are grid1,grid2,grid3 and so on for category1, category2, category3 etc. respectively. Now these grids are placed in the display area inside the main content panel. Under each grid encapsulate those items belonging to that category. Say for example, if category1 has 6 buttons and one textbox, then those items are to be placed under grid1. Now in the XAML code note the height or width of that grid and then make the height or width of the grid1 zero. Now repeat this procedure for all the grids so that you have a customized grid for each category. Please note that during design you won’t be able to see what you have done with previous grids(you can see only the present grid you are working with) as you have made the heights of those grids 0. You can view them by making the height of the present grid (the one you are working with) as zero and assign the height of the grid to that value, you have made note of earlier.

Coming to the coding part of it I am going to demonstrate using C# though this concept can be applied to VB also. In main constructor (Where the function initialize component is invoked) below the InitializeComponent() function give the following code.

grid1.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

You can also create an event handler when the page loads and give the above code there. This code is to make sure that all the grids are at zero height or in other words no category is displayed when the user enters the page. This is not mandatory and can vary depending on how you want the user to see the interface when he enters the page, the logic etc.

The next step is the event handlers when the category buttons are clicked. While placing the components, note the size of the grids which is according to your design. Let’s say for example sake that 255 is a height suitable for the design(the one you noted earlier). Create the event handler for click event of Category1 button by double clicking the category1 button in the design view. The following code goes into that:

grid1.Height = 255;

grid2.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

Similarly for category 2 buttons, in the click event handler the following code goes:

grid1.Height = 0;

grid2.Height = 255;

grid2.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

grid2.Height = 0;

This process is repeated for all the categories.

You can alternatively make the width of the grid also zero. The purpose is to make the other grids vanish and make only one grid appear at a time.

And there it is your own frames page in WP7 with vanishing grids.

Well the advantage with this technique is that it’s very simple to use, many of them are just copy pasting the things that have already been done, easy management, a single UI with multiple options etc. The disadvantage is that while designing if you lose track of what you have been doing it is very difficult to come back to what you have been designing because if you have large categories it is very much difficult as the XAML code becomes big. Apart from this I personally didn’t face any disadvantage.