Welcome to MSDN Blogs Sign in | Join | Help

Alex Yakhnin's Blog

Development and architecture for Windows Mobile devices. And a few useful tips on the way...

News

Introduction into touch.

Take a look at this great introduction into the world of touch screens and gestures by Marcus. He also starts describing the APIs that are available in Windows Mobile 6.5 for handling gestures.

New attractive controls for mobile development.

There's a new company that has just released a few really nice controls for .NET Compact Framework and which you can use to develop attractive UIs in your Windows Mobile applications:

http://www.beemobile4.net/

They where nice to let me know that they've learned a lot from my blog and webcasts on creating cool UI's. It is really satisfying that the work that I do is useful for Mobile developers.

WM 6.5 Develper Tool Kit

The Windows Mobile 6.5 Developer Tool Kit is available for download. It includes the Emulator images as well as the documentation and the samples on Gesture APIs.

Enjoy!

Identifying VGA resolution on WM devices.

Very often when developing managed applications you need to target both VGA (480x640) and the older QVGA (240x320) type of devices. If the AutoScaleMode property of your form is set to Dpi, your controls such as textboxes. labels, buttons etc... will be scaled automatically. However if your draw images yourself or utilizing the ImageList, the images are not going to be autoscaled for you. During the runtime you can easily identify the VGA resolution by using the following code:

  public static bool IsHighResolution(this Form form)

  {

       SizeF currentScreen = form.CurrentAutoScaleDimensions;

       if (currentScreen.Height == 192)

       {

            return true;

       }

       return false;

  }

This is an extension method which is a part of the ControlExtension class from the ListViewDemo project which you can download from here.

So how would you use that method. Here's a sample function that you can place in your form's code:

  private void HandleHiRes()

  {

       if (this.IsHighResolution())

       {

             this.imageList1.ImageSize = new Size(32 * 2, 32 * 2);

       }

  }

Enjoy...

Overview of the Sync Services v2

Sean Kelley who is the PM for the Sync Services for ADO.NET has recorded a webcast that walks through the new features of the next version of the SyncServices. The team has collected a lot of the feedback from the customers on the first version and tried to incorporate it into vNext. The notable changes are: ability to create database snapshots, P2P synchronization, batching, etc... Check out the Sean's webcast for more details: 

https://msevents.microsoft.com/CUI/Register.aspx?culture=en-US&EventID=1032413045&CountryCode=US&IsRedirect=false

The article on Compelling UI has been published.

My article on the UIFramework that I presented during my webcasts has been published on MSDN:

http://msdn.microsoft.com/en-us/library/dd630622.aspx

 

Update to MobileMVC with Container

I've recently made a substantial update to the MobileMVC framework. I've added the ability to utilize a (D)epenendcy (I)njection container by adding IControllerProvider interface into the framework which looks like this:

public interface IControllerProvider

{

     Controller GetController(string name);

     Controller GetController(Type type);

     Controller GetController<T>();

     Controller GetController<T>(IView view);    

     void RegisterController(Controller controller);

}

This interface gets used in the new class Navigator which could be used instead of NavigationService to navigate between the controllers since it implements the same methods such as Navigate, GoBack, GoForward etc... The Navigator class is exposed as a singleton via the property in the Controller class:

/// <summary>

/// Gets an instance of the Navigator.

/// </summary>

public Navigator Navigator

{

     get

     {

          return Navigator.Current;

     }

}

The Navigator class also includes the following static method:

/// <summary>

/// Sets the IControllerProvider to use.

/// </summary>

/// <param name="controllerProvider"></param>

public static void SetControllerProvider(IControllerProvider controllerProvider)

{

     if (navigator == null)

     {

           navigator = new Navigator(controllerProvider);

     }

}

As you can see the SetControllerProvider method accepts as a parameter an instance of the IControllerProvider which you will need call when your application is initialized.

Before diving into the full usage sample let's talk about the DI container. As we know, there's not much of the DI and IoC containers exist for .NET CF right now, however Paterns & Practices team has been quetly working on the update of the Mobile Application Blocks that where released a few years back. P&P has recently posted a Community Drop of the code refresh for the Mobility Block on the Codeplex and it includes the new block which is called ContainerModel. P&P has decided to utilize the Funq container that was developed by Daniel Cazzulino. So, I've taken this container and updated the sample for the MobileMVC to make a use of it. 

Let's continue on the sample of how you can utilize the new features in the MobileMVC framework. I have modified the existing sample MVCDemoClient (a part of the download of the framework), so let's see how we'd initialize container with the views and controllers:

  private static void Initialize()

  {

       container = new Container();

 

       // Register Login view and controller

       container.Register<LoginForm>(c => new LoginForm());

       container.Register<LoginController>(c =>

                           new LoginController(c.Resolve<LoginForm>()))

                .InitializedBy((c, v) => v.Container = c);

 

       // Register Search view and controller

      container.Register<SearchForm>(c => new SearchForm());

            container.Register<SearchController>(c =>

                         new SearchController(c.Resolve<SearchForm>()))

                .InitializedBy((c, v) => v.Container = c);

 

       // Register Search view and controller

       container.Register<DetailForm>(c => new DetailForm());

       container.Register<DetailController>(c =>

                         new DetailController(c.Resolve<DetailForm>()))

                .InitializedBy((c, v) => v.Container = c);

       // Register data model

       container.Register<Products>(c => new Products());

 

 

       // Set ControllerProvider

       Navigator.SetControllerProvider(new ControllerProvider(container));        

  }

In the code above when we register a controller, you can see that we call: .InitializedBy((c, v) => v.Container = c). This means that when an instance of the controller will be created we want to assign the same instance of the container to the Container property which I've added to the controller. We also make a call to the SetControllerProvider method and passing and instance of the ControllerProvider class which as you can guess implements IControllerProvider interface and makes use of the Container:

public class ControllerProvider : IControllerProvider

{

        private Container container;

       

        public ControllerProvider(Container container)

        {

            this.container = container;

        }      

      

        #region IControllerProvider Members      

 

        public Controller GetController<T>()

        {

            return this.container.Resolve<T>() as Controller;          

        }

 

        public Controller GetController<T>(IView view)

        {

            Controller controller = this.container.Resolve<Controller>();

            controller.View = view;

            return controller;

        }

 

        // … Other methods ommitted for brevity

 

        #endregion

 }

After this short preparation we can now modifiy our code to use the Navigator class. This is how we can show the SearchForm from the LoginController:

private void ShowSearchView()

{

    //SearchController controller = new SearchController(new SearchForm());

    //NavigationService.Navigate(controller);  

 

    this.Navigator.Navigate<SearchController>();

}

Ability to access the Container from the controller is also giving us much more separation from the Data Model or other services that you may use in the application. For example this is how we can get access to the Products data model in the SearchController:

// ViewLoaded event from the view

private void OnViewLoaded(object sender, EventArgs e)

{

      // Show busy cursor

      Cursor.Current = Cursors.WaitCursor;

      // Get an instance from the container

      Products products = this.Container.Resolve<Products>();

      // Populate data

      products.PopulateList();

      // Assign the Model

      this.view.ViewData.Model = products;

      // Notify the view of the changes

      this.NotifyView();

      // Restore the cursor

      Cursor.Current = Cursors.Default;

 }

Overall, I think the usage of the container with the MVC pattern gives you much more flexibility when designing your applications. It allows you to decouple the access to the application services giving you more room during the unit testing as well as making changes to the application without breaking too many dependencies.

You can find the updated version of the MobileMVC framework and the sample in the downloads section of the codeplex project:

http://mobilemvc.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=26507

 

 

 

 

 

More memory for managed apps.

Check out the Rob's blog post in which he describes the technique that can help you to allocate less memory when creating managed applications on Windows Phones: 

http://blogs.msdn.com/robtiffany/archive/2009/04/09/memmaker-for-the-net-compact-framework.aspx

 

 

Bluetooth on the emulator.

Would you like to develop applications that utilize the bluetooth functionality on the WM emulator? Now you can. Check out this article on CodeProject:

http://www.codeproject.com/KB/mobile/bth4devemul.aspx

 

Dimming the background.

I've received a question from the customer the other day asking me how he can implement functionality of "dimming" background effect when a message box is shown in his Windows Mobile application. In fact it should be pretty easy to do utilizing the DrawAlpha method from the GraphicsExtender class that I showed you in this webcast. Take a look at the following code snippet:

protected override void OnPaint(PaintEventArgs e)

{

      // Create a temp bitmap

      Bitmap dimBackGround = new Bitmap(this.Width, this.Height);

      Graphics gxTemp = Graphics.FromImage(dimBackGround);

      // Color it black

      gxTemp.Clear(Color.Black);

      // Draw it with alpha transparency

      e.Graphics.DrawAlpha(dimBackGround, 100, 0, 0);

      // Clean up

      gxTemp.Dispose();

      dimBackGround.Dispose();               

 }  

The code above shows OnPaint override method in the BackgroundForm class that I've added to the demo project. I've set the FormBorderStyle to None and WindowState to Maximized for this from to make it full screen.

So, now before displaying a message box you will need to show the BackroundForm:

  BackgroundForm form = new BackgroundForm();

  form.Show();

  MessageBox.Show(txtMessage.Text);

  form.Close();

And here's the result:

Download the sample code from here.

TechDays - 24 hour virtual event

I will be participating in the TechDays next week on April 1st. It's a 24 hour virtual event with almost a hundred sessions that will be repeated for different time zones for people across the globe. I was asked to repeat the Creating Compelling and Attractive UIs for Windows Mobile Applications session. I am going to have two live sessions 10:30 pm GMT and 1:30 pm GMT. Chistopher Fairbairn will be presenting the same session in the Asia Pacific time zone.

 

Another Webcast on controls customization.

Next week I am going to present a second part of the series on creating attractive UIs on Windows Mobile devices. This time I will show you how to customize built-in controls that come with .NET CF, such as TextBox, DataGrid, ListView etc...

You can register for the web cast here:

http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032408754&EventCategory=4&culture=en-US&CountryCode=US

UPDATE:

The code from the session is available for download from:

https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=uiframework&ReleaseId=2315

 

 

 

MSDN Webcast on creating attractive UI on WM devices

Please join me for the webcast that I will be presenting the upcoming Wednesday:

MSDN Webcast:

24 Hours of Windows Mobile Application Development: Creating Compelling and Attractive UIs for Windows Mobile Applications.

Update:

You can download the source code from:

http://code.msdn.microsoft.com/uiframework

 

FAQ's

From time to time I receive questions that are submitted from this blog related to my old blog, so I have decided to create this post as a place holder for the answers. I will continue updating this post by adding answers to the questions as they come along.

Q: When I use your HookKeys class that you posted on your old blog, but it doesn't work on my smartphone device.

A: When running this code on smarthone (WM Standard) devices, the SetWindowsHookEx API function requires that your application to be signed with at least the developer certificate.

 

Q: I am writing an application on windows mobile phone (smartphone) . When my app is running if I press the VK_TEND/VK_F4 key ( red button on the phone ), our window gets the message "0xC003"(49155). But I am not able to figure out what message is this. How can capture this message?

A: Please see the post about creating keyboard hooks on WM.

 

Q: In your blog post about keyboard hooks you mention that something is missing. What is it?

A: The code that is provided in this blog should be functional. The only part is missing is the code that implements IDisposable interface to handle the scenarios when the HookKeys class goes out of scope and you should unhook messages in the Dispose method.

Functional Validation

Since posting a few of my last ideas, my brain has been running a few background threads on how else we can utilize the functional programming when developing applications for .NET Compact Framework (and desktop as well) and take advandage of the power of the LINQ to improve the readability and possibly performance of our applications. So here is another one.

Everybody who develops applications that involve getting some data from a user knows that the data which is coming from the user must be thoroughly validated in order to avoid having "dirty" data in the databases. So we have been creating some validation procedures that would go through the controls on the form, validate the data in them and either display an error to a user or pass it through to a data layer. What if we could utilize the delayed execution of the anonymous delegates to set the validation rules before hand and then apply them when it's needed? Let's consider a typical scenario of validating a numeric only input in some TextBox that you may have on your form and see my ideas in action:

Validator validator;

 

public Form1()

{

     InitializeComponent();

    

     SetValidationRules();

}

 

private void SetValidationRules()

{

     validator = new Validator();

     validator.AddRule<TextBox>("Numeric", u => IsNumeric(u.Text) );

}

 

private bool IsNumeric(string text)

{

     bool result = true;

     try

     {

         Double.Parse(text, System.Globalization.NumberStyles.Any,

                      System.Globalization.NumberFormatInfo.InvariantInfo);

     }

     catch (Exception ex)

     {

         result = false;

     }

     return result;

 }

In the code above we set a validation rule in the SetValidationRules method in which we utilizing the IsNumeric method. When calling the AddRule method on the Validator class we can make use of the lamda expression syntax. After we are done with the rules we can employ these rules to validate an input in the TextBox: 

private void txtPin_Validating(object sender, CancelEventArgs e)

{

    if (!validator.Validate<TextBox>("Numeric", txtPin))

    {

        MessageBox.Show("The pin mush be numeric");

    }

}

So we call on to the Validate method of the same Validator class by passing the name of the rule and an instance of the TextBox to be validated. Not bad. Better yet, we should be able to provide a method that would be called when out validation method is executed. Let me illustrate what I am talking about:

// Add another rule

validator.AddRule<TextBox>("Empty", u => u.Text == "", new Action<bool>(ExecuteOnValidate));   

private void ExecuteOnValidate(bool result)

{

    if (result)

    {

        MessageBox.Show("TextBox is empty.");

    }         

}

In the code above we are adding another rule that checks if the Text property of the TextBox is empty, passing an instance of the txtUserName and a handler for the Actition delegate: ExecuteOnValidate. Now when running this validation rule we can write the code:

validator.ValidateWithResult<TextBox>("Empty", txtUserName);

Are you interested in looking at how the Validator class may be implemented? Let's start with the IRule interface and the Rule class implements this interface:

public interface IRule

{

     bool Validate();

     void ValidateWithResult();

}

public class Rule<T> : IRule

{

     private T instance;

     private Func<T, bool> ruleDelegate;

     private Action<bool> outDelegate;

 

     public Rule(T instance, Func<T, bool> ruleDelegate)

     {

          this.instance = instance;

          this.ruleDelegate = ruleDelegate;

     }

 

     public Rule(T instance, Func<T, bool> ruleDelegate,

Action<bool> outDelegate)

     {

          this.instance = instance;

          this.ruleDelegate = ruleDelegate;

          this.outDelegate = outDelegate;

     }

 

     #region IRule Members

 

     public bool Validate()

     {

          return this.ruleDelegate(instance);

     }

 

     public void ValidateWithResult()

     {

          this.outDelegate(this.ruleDelegate(instance));

     }

 

     #endregion

 

     public T Instance

     {

         get

         {

             return instance;

         }

         set

         {

             instance = value;

         }

     }                        

}

The Rule class is just a helper class that we are going to use in the Validator class:

public class Validator

{

     // Cache for rules

     private Dictionary<string, IRule> rulesList;      

 

     public Validator()

     {

         // Create an instance of the cache

         this.rulesList = new Dictionary<string, IRule>();

     }

 

     public void AddRule<T>(string key, Func<T, bool> rule)

     {

         // Add rule to the cache

         this.rulesList.Add(key, new Rule<T>(default(T), rule));

     }

     public void AddRule<T>(string name, Func<T, bool> rule,

Action<bool> result)

     {

          // Add rule to the cache

          this.rulesList.Add(name, new Rule<T>(default(T), rule, result));

     }

     public bool Validate<T>(string name, T instance)

     {

         // Retrieve the rule

         Rule<T> rule = (Rule<T>)this.rulesList[name];

         // Assign the instance

         rule.Instance = instance;

         // Call validate

         return rule.Validate();

     }

 

     public void ValidateWithResult<T>(string name, T instance)

     {

          // Retrieve the rule

          Rule<T> rule = (Rule<T>)this.rulesList[name];

          // Assign the instance

          rule.Instance = instance;

          // Call validate

          rule.ValidateWithResult();       

     }

}

In the AddRule methods in the code above we create an instance of the Rule class and them to the rulesList dictionary. In the Validate methods we retreive an instance of the Rule class and call on its Validate method. Nothing much to it. I am attaching the whole test project to this post. It's a device project, but surely you could use the same code on the desktop. Please consider this code as a sample which has not been tested.

More Posts Next page »
Page view tracker