Category Archives: Metro style App

Using TaskCompletionSource in wraping event handler


Using TaskCompletionSource you can wrap any operation in to task, so that you can do anything you can with the task object. The TaskCompletionSource class is very important and today’s post will be explain how to wrap button click event in to TaskCompletionSource. With this wrap we will see how complicated operation behind click button handler can be simplified.

The for this blog post is simple Windows Store app shown on the picture below.

screen_sample2

When the Play Slides is clicked, Image slide is started which start animation of images. XAML code behind this app is listed here:

<Page.Resources>
    <Storyboard x:Name="animImageSlideIn">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
                                        Storyboard.TargetName="img">
            <EasingDoubleKeyFrame KeyTime="0" Value="900"/>
            <EasingDoubleKeyFrame KeyTime="0:0:2" Value="0" />
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" Height="250" >
        <Button x:Name="playbtn" Height="50" Margin="0,5,0,5" Content="Play Slides" HorizontalAlignment="Center" Click="playbtn_Click"></Button>

        <Image x:Name="img" HorizontalAlignment="Center">
            <Image.RenderTransform>
                <CompositeTransform TranslateY="900" />
            </Image.RenderTransform>
        </Image>
    </StackPanel>
</Grid>

First, it will be presented  the implementation without TaskCompletionSource. The Play Slides Click event is the following code:

private async void  playbtn_Click(object sender, RoutedEventArgs e)
{
    int i = 1;

    EventHandler<object> handler = null;

    handler = delegate
    {
        if (i <= 3)
        {
            playbtn.Content = string.Format("Slide Image {0}",i);

            LoadSourceImage(i);

            animImageSlideIn.Begin();

            i++;
        }
        else
        {
            playbtn.Content = "Play Slides";
            animImageSlideIn.Completed -= handler;
            LoadSourceImage(0);

        }
    };

    animImageSlideIn.Completed += handler;
    handler(null,null);
}

As we can see from the listing above the code is pretty much long and little bit confused because we subscribe to the handler and call it as much as we reach the magic number of slides. Whe the number of slides is reached we unsubscribed from the handler and exit  the method.

Now implement the same functionality with the TaskCompletionSource class. The following listing shows the implementation:

private async void playbtn_Click(object sender, RoutedEventArgs e)
{

for(int i=1; i<=3; i++)
{
playbtn.Content = string.Format("Slide Image {0}",i);
LoadSourceImage(i);
await animImageSlideIn.RunAsync();
}

playbtn.Content = "Play Slides";
}

As we can see the implementation is very simple and concise. in for loop we call LoadSourceImage then asynchrony run animation.

The source code of the demo can be found by clicking the image below:

This blog post is inspired by Stephen Toub //build/ session.

Advertisements

Pausing and cancelling async method in C#


Responsiveness of your app is not just fee UI thread by implementing async. It is more that that. When a long operation is under process in your app, user sometimes wants to cancel it  or  pause the operation. Imagine your app processing hundreds of files or images. Such a operation can take more that few seconds and user must have option to cancel it. Canceling and pausing are very important feature for every app that implements long operations.

This blog post will present the way of using CancelationToken built in cancel feature in .NET, as well as a PauseToken custom implementation which is very similar to CancelationToken.

Original implementation of PauseToken is from the pfxteam blog which you can find here.

We will implement simple Windows Store app with cancel and pausing the async operation. The picture below shows the sample app:

screen_sample1

 

As you can see when the Start Process button is clicked it begins process of processing image files. There is also ProgressRing control which shows the progress and percentage of completeness. From the right side you can see two buttons. The Cancel button cancels the operation, and pause button pauses operation until the Pause button is clicked again.

The implementation behind Process button is the folowing:

private async  void btnProcess_Click(object sender, RoutedEventArgs e)
{
    //creating cancel and pause token sources
    m_pauseTokeSource = new PauseTokenSource();
    m_cancelationTokenSource = new CancellationTokenSource();

    //get al picture from picture library
    var picturesFolder = KnownFolders.PicturesLibrary;
    var fileList = await picturesFolder.GetFilesAsync();

    //set ProgressRing to active
    ring2.IsActive = true;

    try
    {
        //asynchrony process files, by passing pasue and calcel tokens

        await ProcessImages(fileList, m_pauseTokeSource.Token, m_cancelationTokenSource.Token);
    }
    catch (Exception)
    {
        //do nothing when somthing went wrong not when taks is canceled
    }
    finally
    {
        //make inactive ProgressRing
        ring2.IsActive = false;
    }
}

Click event implementation of the Start Process button 

First we create Cancel and Pause Source tokens. Gent the picture content in form of list of files. Then we call asynchonious ProcessImages method by passing list of images files, cancel and pause tokens. Process images is called within try catch finally blocks, because every cancel task throws exception.

Implementation ProcessImages async method

ProcesImage method is async method which accept cancelation and pasue token nad returns Task object.

public async Task ProcessImages(IEnumerable<StorageFile> images, PauseToken pauseToken, CancellationToken cancelToken)
{
    double count=images.Count();
    double current=0;
    foreach (var file in images)
    {
        //if the paise is active the code will wait here but not block UI thread
        await pauseToken.WaitWhilePausedAsync();

        ring2Text.Text = string.Format("{0}%",(int)(100*current / count));

        await ProcessAsync(file, cancelToken);
        current++;
    }
    ring2Text.Text = string.Format("100%");
}

In foreach loop first we await pauseToken.WaitWhilePausedAsync(); which wait if IsPause property of the Token class is true, otherwize there is no awaiting here. The next await is out Delay which takes cancelation token as parameters. When the Pause button is clicked, pauseToken is awaiting until the pause button is clicked again. In case of cancelation when the Cancel button is clicked the Cancel() method of the cancelationTokenSource is called and exception is thorwn. Then processImages method is interupted and finally blick progressring is disabled.
Pause and Cancel Click implementation are shown in the following listing:

private void btnPause_Click(object sender, RoutedEventArgs e)
{
 m_pauseTokeSource.IsPaused = !m_pauseTokeSource.IsPaused;
}

private void btnCancel_Click(object sender, RoutedEventArgs e)
{
 m_cancelationTokenSource.Cancel();
}

Complete source code can be downloaded from link below.

Using Dispatcher in Windows 8.1 Store Apps


If we want to inform the user about operation status which is running in the background by callback method, you have to be aware that the callback call is not in the UI thread. In this situation we cannot show Dialog message as ordinary, because we will go in trouble with cross-thread exception.

If we want to run eg. Dialog Message in Windows Store apps to inform user about operation status we need to run a “safe code”. This means we need to call Dispatcher, which cares that all calls related to UI components have to be from the main thread.

Lets assume we have callback method which gets call when user wants to see the payment status. Process of checking payment is not in UI thread, so the callback method of reporting status will also not be in the UI thread. In that situation, any code which touches UI must be executed with Dispatcher.

The following code  shows how to create MessageDialog and show it in Windows Store app, so that the user get information about payment status.

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PaymentCheckCompleted(object sender, PaymentEventArgs e)
{
    MessageDialog dlg = null;
    if (e == null)
    {
        dlg = new MessageDialog("Status is NULL", "SMS Provider");
    }
    else if (e.status == PaymentStatus.ok)
    {
        dlg = new MessageDialog("Status is OK", "SMS Provider");
    }
    else if (e.status == PaymentStatus.cancelled)
    {
        dlg = new MessageDialog("Status is CANCELED", "SMS Provider");
    }
    else if (e.status == PaymentStatus.failed)
    {
        dlg = new MessageDialog("Status is FAILED", "SMS Provider");
    }
    else if (e.status == PaymentStatus.pending)
    {
        dlg = new MessageDialog("Status is PENDING", "SMS Provider");
    }
    else
    {
        dlg = new MessageDialog("Status is UNKNOWN", "SMS Provider");
    }

    dlg.Commands.Add(new UICommand("OK"));
    dlg.DefaultCommandIndex = 0;
    dlg.CancelCommandIndex = 0;
    dlg.Options = MessageDialogOptions.None;

    this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => dlg.ShowAsync());

}

The last line in the example above shows how to use Dispatcher, and how to show dialog so that we never see cross-thread exception.

Developing Windows Store App Part 2: REST Service implementation


Today’s blog post will discass how to implement REST service by using ASP.NET Web API. To expose data to our Windows Store app, we need to implement some kind of REST or Soap service. For this sample we are going to create Rest service, which will expose basic data operation to our Windows 8 Store client.

1. Open you previous EFModel solution in Visual Studio 2012.

2. Right click at the solution and choose Add New Project

3. Select ASP.NET MVC 4 Web Application, Enter the name of the project.

4. Click OK button.

5. On the next Dialog select Web API, and click OK button.

6. Initial skeleton for RESTService is created.

7. Add Reference of EFModel project.

Now we are going to implement Controller.

8. Right Click on RestService project ->Add New Controller.

9. Enter CExplorer name, and click OK.

Implementation of the controller shows the next listing:

 public class CExplorerController : ApiController
    {
        // GET CExplorer
        [HttpGet]
        public List Place()
        {
            /// return new string[] { "value1", "value2" };
            ///
            try
            {
                using (CExplorerContext ctx = new CExplorerContext())
                {
                    var lst = ctx.Places.ToList();
                    return lst;
                }
            }
            catch (Exception)
            {

                throw;
            }

        }

        // GET CExplorer/5
        [HttpGet]
        public Place Place(int id)
        {
            try
            {
                using (CExplorerContext ctx = new CExplorerContext())
                {
                    return ctx.Places.Where(x => x.PlaceID == id).FirstOrDefault();
                }
            }
            catch (Exception)
            {

                throw;
            }
        }
        // GET CExplorer/5
        [HttpGet]
        public IEnumerable Search(string queryText)
        {
            try
            {
                //queryText = queryText;
                using (CExplorerContext ctx = new CExplorerContext())
                {

                    var lst11 = ctx.Dishes.Where(x => x.Name.ToLower().Contains(queryText.ToLower())).Select(x => x.DishID).ToList();
                    var lst22 = ctx.Towns.Where(x => x.Name.ToLower().Contains(queryText.ToLower())).Select(x => x.TownID).ToList();

                    var lst = ctx.Places.ToList();

                    var ll = from p in ctx.Places
                             where
                             lst11.Contains(p.DishID) ||
                             lst22.Contains(p.TownID) ||
                             p.Name.ToLower().Contains(queryText.ToLower()) ||
                             p.Slogan.ToLower().Contains(queryText.ToLower())

                             select p;

                    var rr = ll.ToList();
                    return rr;
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        // POST CExplorer
        [HttpPost]
        public void Place([FromBody]Place plc)
        {
            try
            {
                if (plc == null)
                    return;
                using (CExplorerContext ctx = new CExplorerContext())
                {
                    if (plc.PlaceID == -1)
                    {
                        ctx.Places.Add(plc);
                        ctx.SaveChanges();
                    }
                    else
                    {
                        var p = ctx.Places.Where(x => x.PlaceID == plc.PlaceID).FirstOrDefault();
                        if (p == null)
                            return;

                        p.Name = plc.Name;
                        p.Slogan = plc.Slogan;
                        p.Description = plc.Description;
                        p.DishID = plc.DishID;
                        p.TownID = plc.TownID;
                        p.Image = plc.Image;
                        ctx.SaveChanges();
                    }
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        // GET Town
        [HttpGet]
        public List Town()
        {
            /// return new string[] { "value1", "value2" };
            ///
            try
            {
                using (CExplorerContext ctx = new CExplorerContext())
                {
                    return ctx.Towns.ToList();
                }
            }
            catch (Exception)
            {

                throw;
            }

        }

        // GET Dish
        [HttpGet]
        public List Dish()
        {
            /// return new string[] { "value1", "value2" };
            ///
            try
            {
                using (CExplorerContext ctx = new CExplorerContext())
                {
                    // var ss= ctx.Dishes.ToString();
                    return ctx.Dishes.ToList();
                }
            }
            catch (Exception)
            {

                throw;
            }

        }
    }

10. Resolve using statement, that you can compile project.

11. Modify App_Start/WebApiConfig.cs file like the following listing:

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                 name: "DefaultApi",
                 routeTemplate: "{controller}/Place/{id}",
                defaults: new { action = "Place", id = RouteParameter.Optional }
             );

            config.Routes.MapHttpRoute(
                name: "DefaultApi1",
                routeTemplate: "{controller}/Town",
               defaults: new { action = "Town" }
            );

            config.Routes.MapHttpRoute(
                name: "DefaultApi2",
                routeTemplate: "{controller}/Dish",
                defaults: new { action = "Dish" }
            );

            config.Routes.MapHttpRoute(
                 name: "DefaultApi3",
                 routeTemplate: "{controller}/Search/{queryText}",
                defaults: new { action = "Search", queryText = RouteParameter.Optional }
             );
        }
    }

Defining connection string. For propery connection string definition you need to provide valid SQL login. You can achive this by creating new Login at SQL Server database, similar like picture below.

12. Add connection string to WebConfig file similar like the following.

<connectionStrings>
  <add name="cexplorer_db" providerName="System.Data.SqlClient" connectionString="Data Source=.\sqlexpress;Initial Catalog=cevap_db;Persist Security Info=True;User ID=testuser;Password=123;"/>
  </connectionStrings>

13. Set RestService as Startup project, and hit F5.

14. When IE appear, enter the following url adress: http://localhost:4636/cexplorer/place, to get all Places from the db.

Note: This is exactly what we inserted in Place Table, while we run EFTest console app from the previos blog post.

Now we have all instrastructure to start developing Windows Store app Ćevap Explorer. Source code for this blog can be found here.

Speaking about The future of Windows 8 desktop application


After unforgettable week in Redmond on MVP Summit 2012, it is time to announce some of my speaking activity. The first conference for this year will be MSNetwork 2 domestic Microsoft conference, which I will be speaking on two sessions. The first session will be Development with ASP.NET Web API and MVC 4.0, together with Damir Dobric , and the second session will be The Future of Windows Desktop Application.

The first session will talk about a new Microsoft project Asp.NET Web API, firstly announced as WCF Web API, which I blog posted already. The reason for changing the name of the API is in short because  WCF is far more than HTTP Web API, so Microsoft team has decided to change the name and include the library in to ASP.NET as a part of the MVC 4.0 beta.

On that way the ASP.NET Web API is finally included in to .NET Framework and ready to use in production when the .NET 4.5 would be released.Damir has also posted several blogs about ASP.NET API so if you want more info about, you can find there. This session brings a lof of demos and samples how to use Web API with routing,using HTML methods GET, POST PUT, standard and custom formatters as well as validators and custom errors. If you are Web developer, or just want to see how to build modern web application with MVC 4.0 and .NET 4.5 come to our session which will start after launch at 14:30 at 4. 4. 2012.

The Future of Windows Desktop application brings a lot of news about Windows 8 Metro style application, like compatible by design, Windows Store and Certification. Windows 8 brings the new future for desktop application and new way of using, developing and promoting desktop applications. Windows 8 also brings a new platform for desktop application, it is Tablet. So when you develop Windows application you can count on different devices like PC or Tablet, and far more different resolution. This is only scratch of the session about new future of the Windows desktop application and technique for development.

We can say the new future is born for Windows Desktop application. The session starts after launch at 14:30 at 5. 4. 2012.

More info about MS Network you can find here.

So much said about introductio of my two sessions on the Network 2 in Mostar. See you there.

Windows 8 Metro Tips and Tricks


Windows 8 Metro Style

It is important to know some key shortcats in order to be productive and efficient when working in Windows 8 specially in Metro style Mode. Since any Metro App does not have Exit option it is important to know how to return back or how to log off or turn off our PC.

Since there is no Exit command in Metro, applications cannot be exited in the traditional way. In fact every Metro style app has three states Active- when it is showed on screen, Suspended- when it is in background and Destroyed- when OS kill the process of your app. When other Windows 8 Metro app is launched, the previous application goes off the screen and becomes suspended. After about 5 seconds application goes to transient state. It is important to know that suspended apps are not removed from memory, but all their threads are suspended. On that way suspended application can be activated and showed on the Metro screen immediately. On the other hand suspended apps don’t consume energy or they consume energy in minimum amount. Suspended apps can be terminated of a low memory condition. This is the case when the application is relaunched as a new run. During relaunching it can be implemented so that the app can restore its state from persistent storage and appear to the user as if it has never been gone.

At the end of this blog post let’s review the shortcuts for some action in Windws 8 Metro:

  • winkey – switch between Desktop and Metro mode
  • winkey+L – Log off from the Window current session
  • winkey+F – Open Metro Search engine for searching different content: Apps, files, settings, etc
  • winkey+P – Change Monitors layout.
  • winkey+any – Starts searching for content.
  •  winkey+ESC – Back to Desktop mode (Windows 7++).
  • winkey+i –    Setting of Desktop, Power, Audio and Network.
  • winkey+o – Lock screen rotation.
  • winkey+d –  Whos Desktop mode (Windows 7++)
  • winkey+h –  Open the share charm
  • winkey+k –   Open the connect share charm
  • winkey+TAB – Toggles between opened apps
  • winkey+SPACE – Toggles input language and keyboard
  • winkey+c –   Open the “charms bar” (share, settings, shutdown)
  • Mouse RClick on App Tile – shows the App Bar with advanced option.
  • ALT+TAB – Switch between apps.
  • Press any key – Unlock screen
  • CTRL+SHIFT+ESC – force to close metro app, since there is no Exit option in app.

Consuming WCF in Windows 8 Metro style app


Asynchronous programming is introduced in a new version of programming languages (C++, C# and JavaScript) which are part of the WinRT and .NET. If you are programming in C# you can program asynchronous by using async and await keyword. In fact when you program with async and await you actually program as ordinary synchronous code. That’s the big thing about this type of programming model.
More information about C# asynchronous programming you can found in my previous posts.
Since we have asynchronous programming model in all languages calling service operations asynchrony is not relevant at all. We can just forget it and start writing code like synchronous. To see hot new pattern is reflected in WCF lets implement simple service and simple metro style app consumer.
Implementation of the WCF Simple Service:

  • Create new ASP.NET Empty Web App
  • Add new Item-> WCF Service
  • Name it as SimpleService.svc


Service Interface looks like the following implementation:

[ServiceContract]
public interface ISimpleService
{
    [OperationContract]
    [WebGet(UriTemplate="AllData",ResponseFormat= WebMessageFormat.Json)]
    List<string> GetSomeData();
}

Implement one operation in the service like the following code implementation:

public class SimpleService : ISimpleService
{
    public List<string> GetSomeData()
    {
        List<string> lst = new List<string>();
        for (int i = 0; i < 10; i++)
        {
            System.Threading.Thread.Sleep(100);
            lst.Add(string.Format("Item number {0}", i + 1));
        }
        return lst;
    }
}

The mentioned operation returns list of string but between populating the collection we sleep the current thread for 0,5 second in order to simulate log running operation.

It is necessary to publish the WCF service on remote host, in order to consume it. I still dont know why WCF service cannot be consumed by Metro app on the localhost. After the service is published on remoter host, we are ready to create Metro style Consumer app.

  • Right click on solution item
  • Add New Project
  • Choose Application template from the Metro Style app
  • Name it WCFConsumer

  • Add service reference to C# Metro Stryle app.
  • Add the GridView and some other input controls (buttons, editbox , etc) that we can test application responsiveness. Add the following XAML code in MainPage.xaml:
<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="151*"/>
        <ColumnDefinition Width="326*"/>
        <ColumnDefinition Width="207*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="74*"/>
        <RowDefinition Height="185*"/>
        <RowDefinition Height="68*"/>
    </Grid.RowDefinitions>
    <GridView x:Name="gridData" Grid.Column="1" Grid.Row="1" />
    <HyperlinkButton Content="HyperlinkButton"   Grid.Column="1" HorizontalAlignment="Left" Height="25" Margin="58,30,0,0" VerticalAlignment="Top" Width="126"/>
    <Button Content="Button" Grid.Column="1" HorizontalAlignment="Left" Height="40" Margin="69,8,0,0" Grid.Row="2" VerticalAlignment="Top" Width="182"/>
    <TextBox Grid.Column="2" HorizontalAlignment="Left" Height="27" Margin="21,79,0,0" Grid.Row="1" Text="TextBox" VerticalAlignment="Top" Width="161"/>
    <TextBox HorizontalAlignment="Left" Height="15" Margin="24,79,0,0" Grid.Row="1" Text="TextBox" VerticalAlignment="Top" Width="102"/>
    <Image Grid.ColumnSpan="2" Grid.Column="1" HorizontalAlignment="Left" Height="100" Margin="312,240,0,-272" Grid.Row="2" VerticalAlignment="Top" Width="100"/>
</Grid>

The picture below shows the example ot the mainPage.

  • Implement Loaded event in to MainPage.xaml and insert the following code.
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
        SimpleServiceNamespace.SimpleServiceClient client = new SimpleServiceNamespace.SimpleServiceClient();
        var servicedata = client.GetSomeDataAsync();
        gridData.ItemsSource = servicedata.Result;
}

Even if GetSomeDataAsync method is asynchronous we don’t implement callback because this operation is implemented based on the async and await C# keyword and no need to do that.
Just assign the result of the servicedata to the GridView.ItemsSource.
If we run the app, we can see that the data is loaded asynchronously and UI is not blocked. We can click on buttons, tipe some texts while data is loading. This is awesome and now we can think about application logic instead of callback service implementation. This programming pattern works not just for Metro style apps, in fact it works for all .NET 4.5 based applications.