Nov 8 2011

A basic lessen in marketing of apps.

Category: Administrator @ 18:40

So, I made two apps for Windows Phone 7 for generating QR Codes. The first one is ok at generating the codes, but really limited in functionality.

I decided to start from scratch and make a really great app with a Windows Phone’ish UI, live-tiles and the works.

The funny thing – the crappy app is downloaded A LOT more!

Great App: QR Coder

    5 downloads, but great reviews

Limited App: QR Generator

  600 downloads and counting and crappy reviews

Granted, the crappy-app has had a little bit more time in the marketplace and both apps are mere drops in the sea of apps, but I see a CLEAR appetite for the crappy app in the marketplace.

I just can’t help it. I think it’s because of the girl on the icon… I really do!

Just think it’s kind of funny…

 

 

Tags:

Jul 17 2011

Creating Design Data for XAML using a dynamics wrapped in a static class with a fluid interface.

Category: mvvm | wpfAdministrator @ 22:48

Why and How

Having design data while designing a user interface in Visual Studio or Blend is great. Designing multi-level ItemTemplates without design time data is like trying to paint in the dark.


But sometimes I struggle getting my actual ViewModels to work as design data. They have too many dependencies and I don’t want to clutter my production code with functionality that is only there to make my objects have the extra purpose of being Design Time friendly.


I wanted to mock some quick objects. So, I started using dynamics with the ExpandoObject in .NET 4 to create a quick object that I would use in Design Time like this:

 

I know my ViewModel has a property named “Name” and some City objects in a Cities collection. With a dynamic object, I can just duck-type away until I have enough to enable me to see what I’m doing  while designing the user interfarce.


The ExpandoObject inherits from DynamicObject. A DynamicObject will accept any method or property and just “try” to figure out what to do at runtime. It has methods like “TryInvokeMember” so if someone tries to call a member on it that does not exist, it can decide what to do at runtime.


I then created my own version of the dynamic ExpandoObject  and wrapped it in a static class to make it easy to use. Ease of use my top priority for creating Design Time data. I added methods on the static class that would create properties, collections and child objects on the dynamic object. Most of the methods returns the same object to enable a fluent programming interface.


Now You can write something like this to create design time data:

You start by creating a DesignData object. Adding properties to the object is done with the .Property() method. The .Property() method returns itself to allow you to continue adding. Adding a Child object simply adds a new DesignData object as a property and returns the new DesignData object that you continue adding properties children or collections to.

Adding collections (to mock your Observable Collections in the real ViewModels) is done by using the .Collection() method. It accepts a number (or range) of objects that you with to create and can either “yield return” an IEnumerable to let you foreach over the created items in the collection (in order to add Properties to them) or you can specify a Delegate Action of DesignData to enable a lambda expression syntax with anonymous methods.

The .Property method allows you to specify up to 10 pieces of design data that will randomly be used. The properties are Objects so you are not limited to strings. You can use ints, true/false, images or what ever you like.

You don't have to understand how it works to use it! The great thing about this is that it is totally separated from your runtime code so you can't shoot yourself in the foot and will not add complexity or bugs to your runtime code.

Setting it up

1)    Add the DesignData class to your project. (download the class here)

2)    Add the DesignDataLocator class to your project. (download example here)

3)    Add a reference to the DesignDataLocator in your App Resources.

 

4)    In the DesignDataLocator class, add a property for each ViewModel you wish to mock and let it return the .Output property of a DesignData object.

5)    In your xaml, Add a reference to that property in the DesignDataLocator as the design DataContext.

 

Now you can add properties, children and collections to your fake ViewModel and see what you are doing in Blend and Visual Studio.


Please note that this does not work in Silverlight because Silverlight will not let you bind to dynamic objects from Xaml. But Silverlight 5 has an ICustomTypeProvider interface that I will try to use to enable the exact same behavior when I get time to play with that.

Demo Project

I created a little demo-project for you. It uses the above demo-data and it is hooked up to a window that displays the data in nested ItemsControls like this:

 

This is how it looks in DESIGN MODE! It’s not pretty, but making it pretty is relatively easy now because the changes I make to the xaml are instantly visible in the designer and I can use Blends Template editor without having to continuously run my solution.

(download demo-project here)

Tags: , , ,

Jun 22 2011

XAML Intellisense for Databindings!

Category: mvvm | silverlight | wpfAdministrator @ 08:55

Resharper 6 adds intellisense to XAML by helping you specify the object you are binding to (your View Model) as the Design Instance in your XAML. This enables you to enjoy sweet intellisence no matter how you choose to join your view to your wiewmodel at runtime.

ViewModel:

When you ViewModel is not specified, you can press ALT+Enter to get some help specifying it:

This is how you specify what ViewModel to use for intellisense (it must have a parameter-less constructor by the way...):

And now I have my intellisence by pressing Ctrl-Space after the Path=:

Great, I have been waiting for that and I’m definitely upgrading to Resharper 6!

Tags:

Feb 23 2011

Slides from wp7 geek-night (danish)

Category: Administrator @ 07:42

 

 WP7_Geek_night.pptx (4.38 mb)

 

Tags:

Jan 11 2011

Microsoft rejects my app due to “Certain Types of Illegal Activity”.

Category: silverlightAdministrator @ 17:11

 

So, I got my first app rejection. No big deal. I have to fix something and resubmit, right?

Well, not exactly. One of the reasons for this rejection apparently is section 3.7 regarding Certain Types of Illegal Activity, specifically:

“Any content that facilitates or promotes underage drinking, consumption of illegal drugs, or socially irresponsible behavior due to alcohol or drug consumption (e.g., drinking and driving).”

What I don’t understand is why my app Hangover Helper 1.4 all of the sudden violates that clause. The changes in this new version include a small twitter feed and some improvements to the accuracy of the reverse geo coding. That is it, everything else is the same. Try it, and if you get an urge to do certain types of illegal activity from using it, I would like to hear from you. It’s frustrating to suddenly not be able to update and bug-fix an app that I spend a lot of time on since version 1.0. 

 

The purpose of the app is to highlight the disadvantages of drinking excessively in a humors way. The app description states the primary purpose of the app as “getting a taxi-friendly street address” from your current location.

To me, this is the exact opposite of promoting irresponsible behavior or drinking and driving.

You may choose to like the app or not, but it delivers what it promises and is fairly popular with decent reviews. The new version addresses the primary complaint among the >5.000 users, the accuracy of the street address.

I don’t get it. One day Microsoft is promoting my app on msdn, the next they reject an update to the same app for it’s content.

My problem is that I have no way of knowing what to do. I added a disclaimer saying “Please drink responsibly…” and replaced an image of a guy drinking a beer with an image of folk-dance.

Hope the app will be accepted now.

UPDATE: YEHAAA!!!  22 Hours later and it got accepted!

Tags:

Jan 8 2011

Using TweetSharp in a Windows Phone 7 app

Category: silverlightAdministrator @ 18:17

Version 1.4 of Hangover Helper has a tiny twitter feed build in. The apps purpose is to give users 5 minutes of fun; it’s not a serious app. I don’t want to force users to log on to anything in the app, but I do want to show the user that he/she is not alone. Others have hangovers and to prove it, I will show some recent tweets from others with hangovers.

This turns out to be very simple using TweetSharp:

Download TweetSharp from Codeplex http://tweetsharp.codeplex.com/ and reference the dll’s to your app.

Go to http://www.twitter.com and register an app. You will get a “Customer key” and a “Consumer secret”. You will need these two values to register your Twitter Service object and start a search like this:

TwitterService service = new TwitterService("your key", "Your secret");

 

Then you kick off your search with a search term (in my case the word “hangover”):

 

service.Search("hangover", ProcessIncommingSearch);

 

You need a method to handle your asynchronous search result. Add the tweets via the dispatcher to get the result back into the UI thread:

public void ProcessIncommingSearch(TwitterSearchResult searchResult, TwitterResponse response)

        {

            if (response.StatusCode == HttpStatusCode.OK)

            {

                foreach (var status in searchResult.Statuses)

                {

                    TwitterStatus inline = status;

                    Tweet tweet = new Tweet(inline);

 

                    Dispatcher.BeginInvoke(() => tweets.Items.Add(tweet));

                }

            }

            }

        }

 

The tweet object is holding the information regarding individual tweets:

  public class Tweet

    {

        private TwitterStatus _status;

 

        public Tweet(TwitterStatus status)

        {

            _status = status;

        }

 

        public string CreatedDate

        {

            get { return _status.CreatedDate.ToLongDateString() + "  " + _status.CreatedDate.ToLocalTime().ToLongTimeString(); }

        }

 

        public string Text

        {

            get

            {

                return _status.Text;

               

            }

        }

 

        public string ScreenName

        {

            get

            {

                return _status.User.ScreenName;

            }

        }

 

        public string ProfileImageUrl

        {

            get

            {

                return _status.User.ProfileImageUrl;

            }

        }

    }

 

In the xaml page, a listbox is displaying the tweet collection via a DataTemplate that formats the individual tweets. The image will download from the URL provided by twitter:

  <ListBox Name="tweets" >

            <ListBox.ItemTemplate>

                <DataTemplate>

                    <Grid Margin="2,10,2,2">

                        <Grid.ColumnDefinitions>

                            <ColumnDefinition Width="80"></ColumnDefinition>

                            <ColumnDefinition Width="*"></ColumnDefinition>

                        </Grid.ColumnDefinitions>

                        <Grid.RowDefinitions>

                            <RowDefinition Height="Auto"></RowDefinition>

                        </Grid.RowDefinitions>

                        <Image VerticalAlignment="Top"  Margin="0,10,10,0" Grid.RowSpan="3" Grid.Column="0" Grid.Row="0" Source="{Binding ProfileImageUrl}" Width="73" Height="73"></Image>

                        <StackPanel Grid.Column="1" Orientation="Vertical">

                        <TextBlock Text="{Binding ScreenName}" FontWeight="Bold" FontSize="20" Foreground="Black"></TextBlock>

                        <TextBlock Text="{Binding Text}" TextWrapping="Wrap" FontSize="18" VerticalAlignment="Top"></TextBlock>

                        <TextBlock Text="{Binding CreatedDate}" FontSize="14" Foreground="LightGray"></TextBlock>                           

                        </StackPanel>

                    </Grid>

                </DataTemplate>

            </ListBox.ItemTemplate>

        </ListBox>

 

 

Tags:

Dec 24 2010

Hangover Helper on Hot Apps!

Category: Administrator @ 10:54

 

Watch Laura Foy demo Hangover Helper on channel9.msdn.com:

 

Tags:

Dec 23 2010

The winner of the Christmas Quizzz!

Category: Administrator @ 07:56

Tak fordi du deltog i min jule-quiz!

System.Random er jo klassen som i virkeligheden styrer meget af verden, inklusive hvem der vinder en Amazon Kindle, har talt:

Og det blev: Stefan Daugaard Poulsen.  Tillykke!

God jule til alle!

 

Tags:

Dec 22 2010

Christmas fun!

Category: Administrator @ 08:40

 

Så er det min tur til at hoste Microsofts julekalender:

Hjælp julemanden og vind en Amazon Kindle

Tags:

Dec 18 2010

1800PocketPC reviews my apps

Category: Administrator @ 10:45

Read the review and watch the video of Hangover Helper and Magic 7 Ball

 

Tags: