Ilya Verbitskiy

Digging Deep into Windows
posts - 8 , comments - 14 , trackbacks - 0

Monday, May 6, 2013

How to change Windows Store App’s Start Page?

 

Finally I have had a chance to start developing Windows 8 applications. I have started with C#/XAML applications. The reason is obvious: I had done a lot of WPF development in the last three years. I have been surprised how easy it is to start building the applications. I have started with Professional Windows 8 Programming: Application Development with C# and XAML and write the code.

Today I’d like to show you one trick which is not obvious for Windows 8 beginners. How can you change Windows 8 Apps’ Start Page?

Let’s create a blank Windows Store Application and show a “Hello Windows 8!” on its Start Screen. Start Screen is MainPage.xaml by default. Open it and add this code.

  1: <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
  2:         <TextBlock Text="Hello Windows 8!"
  3:                    FontSize="40"
  4:                    VerticalAlignment="Center"
  5:                    HorizontalAlignment="Center" />
  6: </Grid>

 

Let’s add another page to the application, e.g. NewStartup.xaml, and show “Hello World!” message there, like this:

  1: <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
  2:         <TextBlock Text="Hello World!"
  3:                    FontSize="40"
  4:                    VerticalAlignment="Center"
  5:                    HorizontalAlignment="Center" />
  6: </Grid>

 

Now we can start with the tricky part. All Windows Store Applications have a manifest file Package.appxmanifest. This is the place where you can set you app’s logos, startup image, default language, etc. You can also specify you application capabilities, e.g. access to a web-cam or Internet. But this is another story.

Manifest

You can see Entry point value on the screen. This class the class which runs when the app is activated. But it is not the same as you app’s Start Page. Let’s take a look what we have there.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.IO;
  4: using System.Linq;
  5: using Windows.ApplicationModel;
  6: using Windows.ApplicationModel.Activation;
  7: using Windows.Foundation;
  8: using Windows.Foundation.Collections;
  9: using Windows.UI.Xaml;
 10: using Windows.UI.Xaml.Controls;
 11: using Windows.UI.Xaml.Controls.Primitives;
 12: using Windows.UI.Xaml.Data;
 13: using Windows.UI.Xaml.Input;
 14: using Windows.UI.Xaml.Media;
 15: using Windows.UI.Xaml.Navigation;
 16: 
 17: // The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
 18: 
 19: namespace Blog1
 20: {
 21:     /// <summary>
 22:     /// Provides application-specific behavior to supplement the default Application class.
 23:     /// </summary>
 24:     sealed partial class App : Application
 25:     {
 26:         /// <summary>
 27:         /// Initializes the singleton application object.  This is the first line of authored code
 28:         /// executed, and as such is the logical equivalent of main() or WinMain().
 29:         /// </summary>
 30:         public App()
 31:         {
 32:             this.InitializeComponent();
 33:             this.Suspending += OnSuspending;
 34:         }
 35: 
 36:         /// <summary>
 37:         /// Invoked when the application is launched normally by the end user.  Other entry points
 38:         /// will be used when the application is launched to open a specific file, to display
 39:         /// search results, and so forth.
 40:         /// </summary>
 41:         /// <param name="args">Details about the launch request and process.</param>
 42:         protected override void OnLaunched(LaunchActivatedEventArgs args)
 43:         {
 44:             Frame rootFrame = Window.Current.Content as Frame;
 45: 
 46:             // Do not repeat app initialization when the Window already has content,
 47:             // just ensure that the window is active
 48:             if (rootFrame == null)
 49:             {
 50:                 // Create a Frame to act as the navigation context and navigate to the first page
 51:                 rootFrame = new Frame();
 52: 
 53:                 if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
 54:                 {
 55:                     //TODO: Load state from previously suspended application
 56:                 }
 57: 
 58:                 // Place the frame in the current Window
 59:                 Window.Current.Content = rootFrame;
 60:             }
 61: 
 62:             if (rootFrame.Content == null)
 63:             {
 64:                 // When the navigation stack isn't restored navigate to the first page,
 65:                 // configuring the new page by passing required information as a navigation
 66:                 // parameter
 67:                 if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))
 68:                 {
 69:                     throw new Exception("Failed to create initial page");
 70:                 }
 71:             }
 72:             // Ensure the current window is active
 73:             Window.Current.Activate();
 74:         }
 75: 
 76:         /// <summary>
 77:         /// Invoked when application execution is being suspended.  Application state is saved
 78:         /// without knowing whether the application will be terminated or resumed with the contents
 79:         /// of memory still intact.
 80:         /// </summary>
 81:         /// <param name="sender">The source of the suspend request.</param>
 82:         /// <param name="e">Details about the suspend request.</param>
 83:         private void OnSuspending(object sender, SuspendingEventArgs e)
 84:         {
 85:             var deferral = e.SuspendingOperation.GetDeferral();
 86:             //TODO: Save application state and stop any background activity
 87:             deferral.Complete();
 88:         }
 89:     }
 90: }
 91: 

This code is automatically generated by Visual Studio 2012. the answer to our questions is in line 67.

Code

Frame.Navigate method accepts you Start Page’s type and show it when you application has started. What you should do now if to change MainPage to NewStartup, save the file and run the application.

I had been skeptical about Windows 8 as a platform for applications development, but I changed my opinion now. It is great platform and it is really easy to start with. I hope I will have time to write my about my adventures in new Windows world in the future.

Posted On Monday, May 6, 2013 7:15 AM | Comments (0) | Filed Under [ Windows Store ]

Friday, April 26, 2013

Recovering unallocated space of a USB flash drive.

Today I played with the latest SUSE Linux Live. I had not have a DVD drive and used USB flash drive instead. I wanted to reformat my flash drive, but suddenly found it that it had not been possible. The most of the disk space had been unallocated, and my Windows 8 did not allow me to use it.

Unallocated

Unfortunately Windows does not support Fdisk anymore. But there is another good command line tool to solve this problem. The tool’s name is DiskPart. I would say it is the next generation of Fdisk tool. DiskPart provides you information about your partitions and volumes, allows you to delete and create partitions, extend NTFS volumes, etc.

Let’s remove unallocated space. First of all run Windows command line and type diskpart in the command prompt. Windows will ask you for Administrator permissions to run the tool. Then run list disk command to find your USB flash disk’s number. It should be the same as disk’s number in Computer Management tool. It was 1 in my case. Next you should chose the disk to work with. Type select disk <disk number> command, e.g. select disk 1. The next step is to clean all volumes and partitions on the disk. Use clean command to do that. The last step is to create a primary partition. You can do that using create partition primary command. That’s all. You should be able to format your flash disk now.

This is how I removed unallocated space on my machine:

Microsoft DiskPart version 6.2.9200

Copyright (C) 1999-2012 Microsoft Corporation.
On computer: COMPUTER

DISKPART> list disk

  Disk ###  Status         Size     Free     Dyn  Gpt
  --------  -------------  -------  -------  ---  ---
  Disk 0    Online          298 GB      0 B
  Disk 1    Online         7509 MB  6619 MB

DISKPART> select disk 1

Disk 1 is now the selected disk.

DISKPART> clean

DiskPart succeeded in cleaning the disk.

DISKPART> create partition primary

DiskPart succeeded in creating the specified partition.

DISKPART> exit

Posted On Friday, April 26, 2013 5:19 AM | Comments (13) |

Sunday, April 21, 2013

Using the <base> tag

 

I have an interesting call this morning. One of our customers copy-pasted an email from his email client to our CMS. All links on the page were screwed up, all links on the page had been pointed out to a web-site. The cause of the problem was simple. Email client added the <base> tag to the page to force all links in the email to point out to a third party web-site. It was the first time I had heard about <base> tag.

The <base> tag is used to specify the base URL to use for all relative URLs contained within a page. It means you can use absolute URLs to avoid the issue I had. The tag has two attributes:

  • href. The base URL to be used throughout the document for relative URL addresses.

  • target. A name or keyword indicating the default location to display the result when hyperlinks or forms cause navigation, for elements that do not have an explicit target reference.

You may find very good <base> tag definition on Mozilla Developer Network.

Let’s see two use cases. First of all, I will use the <base> tag without target attribute.

   1:  <!DOCTYPE html>
   2:  <html>
   3:      <base href="http://geekswithblogs.net/ilich/archive/" />
   4:      <ul>
   5:          <li><a href="2013/01/22/wpf-how-to-find-control-location.aspx">WPF: How to Find Control Location.</a></li>
   6:          <li><a href="2012/11/10/wpf-timers.aspx">WPF: Timers.</a></li>
   7:      </ul>
   8:  </html>

All links on the page are pointed to http://geekswithblogs.net/ilich/archive. You will open then in the same browser window.

Now let’s try to use target _blank.

   1:  <base href="http://geekswithblogs.net/ilich/archive/" target="_blank" />

Now you can see the differences. Links pop up in new window.

There is an obvious question. Should I use this tag? There is an obvious answer to this question. It depends… Personally, I would try to avoid using this tag, because it may overcomplicate page maintenance: all relative links will be pointed out to one absolute location. Usually the latest think what a developer will do, when he sees the bug mentioned above,  is to look for a <base> tag. From the other side, <base> tag might be useful in page templates. You can set the base page location and simplify the rest of links in your template. There are pros and cons, and it is up to you either you will use it or not.

Posted On Sunday, April 21, 2013 5:59 PM | Comments (0) |

Tuesday, January 22, 2013

WPF: How to Find Control Location.

Hello everyone! Unfortunately I do not have enough time for blogging this winter. I hope the situation will change pretty soon, and I will find the time to write something here.

Anyway. You know that WPF does UI layout itself and usually you should not specify the exact place for your controls. But sometimes you need to know the exact location of the control. Windows Forms solution is easy: just use Control.Location property which returns you the upper-left corner of the control relative to the upper-left corner of its container. You can achieve the same functionality using Visual.PointToScreen method. It requires one parameter – a Point. The Point is the current coordinates system. It is usually the window’s upper-left corner (0, 0).

 

   1:  element.PointToScreen(new Point(0, 0));

 

Let’s create a simple window with a few buttons. Each button will show it’s screens location when use clicks it. This is our Window.

 

   1:  <WrapPanel>
   2:      <Button>Button 1</Button>
   3:      <Button>Button 2</Button>
   4:      <Button>Button 3</Button>
   5:      <Button>Button 4</Button>
   6:      <Button>Button 5</Button>
   7:      <Button>Button 6</Button>
   8:      <Button>Button 7</Button>
   9:      <Button>Button 8</Button>
  10:      <Button>Button 9</Button>
  11:      <Button>Button 10</Button>
  12:  </WrapPanel>

 

I am using the same UIElement.MouseDown event’s handler for all these buttons. The easiest way to do this is using EventManager.RegisterClassHandler method. It allows you to register a class handler for a particular routed event. This is the code I have added to the Window’s class constructor.

 

   1:  EventManager.RegisterClassHandler(typeof(Button), MouseDownEvent, new RoutedEventHandler(OnMouseDown));

 

The rest of the application is easy: get a button and show its location.

 

   1:  private void OnMouseDown(object sender, RoutedEventArgs e)
   2:  {
   3:      var element = sender as ContentControl;
   4:      if (element != null)
   5:      {
   6:          ShowLocation(element);
   7:      }
   8:  }
   9:   
  10:  private void ShowLocation(ContentControl element)
  11:  {
  12:      var location = element.PointToScreen(new Point(0, 0));
  13:      MessageBox.Show(string.Format(
  14:                                      "{2}'s location is ({0}, {1})", 
  15:                                      location.X, 
  16:                                      location.Y, 
  17:                                      element.Content));
  18:  }

 

And this is it. You may find the example on GitHub.

Posted On Tuesday, January 22, 2013 10:37 PM | Comments (0) |

Saturday, November 10, 2012

WPF: Timers

I believe, once your WPF application will need to execute something periodically, and today I would like to discuss how to do that.

There are two possible solutions. You can use classical System.Threading.Timer class or System.Windows.Threading.DispatcherTimer class, which is the part of WPF.

I have created an application to show you how to use the API.

 

Timer

 

Let’s take a look how you can implement timer using System.Threading.Timer class. First of all, it has to be initialized.

 

   1:  private Timer timer;
   2:   
   3:  public MainWindow()
   4:  {
   5:      // Form initialization code 
   6:      
   7:      timer = new Timer(OnTimer, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
   8:  }

 

Timer’s constructor accepts four parameters. The first one is the callback method which is executed when timer ticks. I will show it to you soon. The second parameter is a state which is passed to the callback. It is null because there is nothing to pass this time. The third parameter is the amount of time to delay before the callback parameter invokes its methods. I use System.Threading.Timeout helper class to represent infinite timeout which simply means the timer is not going to start at the moment. And the final fourth parameter represents the time interval between invocations of the methods referenced by callback. Infinite timeout timespan means the callback method will be executed just once.

Well, the timer has been created. Let’s take a look how you can start the timer.

 

   1:  private void StartTimer(object sender, RoutedEventArgs e)
   2:  {
   3:      timer.Change(TimeSpan.Zero, new TimeSpan(0, 0, 1));
   4:   
   5:      // Disable the start buttons and enable the reset button.
   6:  }

 

The timer is started by calling its Change method. It accepts two arguments: the amount of time to delay before the invoking the callback method and the time interval between invocations of the callback. TimeSpan.Zero means we start the timer immediately and TimeSpan(0, 0, 1) tells the timer to tick every second.

There is one method hasn’t been shown yet. This is the callback method OnTimer which does a simple task: it shows current time in the center of the screen. Unfortunately you cannot simple write something like this:

 

   1:  clock.Content = DateTime.Now.ToString("hh:mm:ss");

 

The reason is Timer runs callback method on a separate thread, and it is not possible to access GUI controls from a non-GUI thread. You can avoid the problem using System.Windows.Threading.Dispatcher class.

 

   1:  private void OnTimer(object state)
   2:  {
   3:      Dispatcher.Invoke(() => ShowTime());
   4:  }
   5:   
   6:  private void ShowTime()
   7:  {
   8:      clock.Content = DateTime.Now.ToString("hh:mm:ss");
   9:  }

 

You can build similar application using System.Windows.Threading.DispatcherTimer class. The class represents a timer which is integrated into the Dispatcher queue. It means that your callback method is executed on GUI thread and you can write a code which updates your GUI components directly.

 

   1:  private DispatcherTimer dispatcherTimer;
   2:   
   3:  public MainWindow()
   4:  {
   5:      // Form initialization code 
   6:   
   7:      dispatcherTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 1) };
   8:      dispatcherTimer.Tick += OnDispatcherTimer;
   9:  }

Dispatcher timer has nicer and cleaner API. All you need is to specify tick interval and Tick event handler. The you just call Start method to start the timer.

 

private void StartDispatcher(object sender, RoutedEventArgs e)
{
    dispatcherTimer.Start();
    
    // Disable the start buttons and enable the reset button.
}

And, since the Tick event handler is executed on GUI thread, the code which sets the actual time is straightforward.

 

   1:  private void OnDispatcherTimer(object sender, EventArgs e)
   2:  {
   3:      ShowTime();
   4:  }

We’re almost done. Let’s take a look how to stop the timers.

It is easy with the Dispatcher Timer.

 

   1:  dispatcherTimer.Stop();

And slightly more complicated with the Timer. You should use Change method again.

 

   1:  timer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);

What is the best way to add timer into an application?

The Dispatcher Timer has simple interface, but its advantages are disadvantages at the same time. You should not use it if your Tick event handler executes time-consuming operations. It freezes your window which it is executing the event handler method. You should think about using System.Threading.Timer in this case.

The code is available on GitHub.

Posted On Saturday, November 10, 2012 12:28 AM | Comments (0) |

Tuesday, October 16, 2012

WPF: Running code when Window rendering is completed

WPF is full of surprises. It makes complicated tasks easier, but at the same time overcomplicates easy  task as well. A good example of such overcomplicated things is how to run code when you’re sure that window rendering is completed. Window Loaded event does not always work, because controls might be still rendered. I had this issue working with Infragistics XamDockManager. It continued rendering widgets even when the Window Loaded event had been raised. Unfortunately there is not any “official” solution for this problem.

But there is a trick. You can execute your code asynchronously using Dispatcher class.

 

Dispatcher.BeginInvoke(new Action(() => Trace.WriteLine("DONE!", "Rendering")), DispatcherPriority.ContextIdle, null);

 

This code should be added to your Window Loaded event handler. It is executed when all controls inside your window are rendered.

I created a small application to prove this idea. The application has one window with a few buttons. Each button logs when it has changed its actual size. It also logs when Window Loaded event is raised, and, finally, when rendering is completed.

Window’s layout is straightforward.

 

   1:  <Window x:Class="OnRendered.MainWindow"
   2:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:          Title="Run the code when window rendering is completed." Height="350" Width="525"
   5:          Loaded="OnWindowLoaded">
   6:      <Window.Resources>
   7:          <Style TargetType="{x:Type Button}">
   8:              <Setter Property="Padding" Value="7" />
   9:              <Setter Property="Margin" Value="5" />
  10:              <Setter Property="HorizontalAlignment" Value="Center" />
  11:              <Setter Property="VerticalAlignment" Value="Center" />
  12:          </Style>
  13:      </Window.Resources>
  14:      <StackPanel>
  15:          <Button x:Name="Button1" Content="Button 1" SizeChanged="OnSizeChanged" />
  16:          <Button x:Name="Button2" Content="Button 2" SizeChanged="OnSizeChanged" />
  17:          <Button x:Name="Button3" Content="Button 3" SizeChanged="OnSizeChanged" />
  18:          <Button x:Name="Button4" Content="Button 4" SizeChanged="OnSizeChanged" />
  19:          <Button x:Name="Button5" Content="Button 5" SizeChanged="OnSizeChanged" />
  20:      </StackPanel>
  21:  </Window>

 

SizeChanged event handler simply traces that the event has happened.

 

   1:  private void OnSizeChanged(object sender, SizeChangedEventArgs e)
   2:  {
   3:      Button button = (Button)sender;
   4:      Trace.WriteLine("Size has been changed", button.Name);
   5:  }

 

Window Loaded event handler is slightly more interesting. First it scheduler the code to be executed using Dispatcher class, and then logs the event.

 

   1:  private void OnWindowLoaded(object sender, RoutedEventArgs e)
   2:  {
   3:      Dispatcher.BeginInvoke(new Action(() => Trace.WriteLine("DONE!", "Rendering")), DispatcherPriority.ContextIdle, null);
   4:      Trace.WriteLine("Loaded", "Window");
   5:  }

 

As the result I had seen these trace messages.

 

   1:  Button5: Size has been changed
   2:  Button4: Size has been changed
   3:  Button3: Size has been changed
   4:  Button2: Size has been changed
   5:  Button1: Size has been changed
   6:  Window: Loaded
   7:  Rendering: DONE!

 

You can find the solution in GitHub.

Posted On Tuesday, October 16, 2012 9:34 PM | Comments (0) |

Wednesday, October 10, 2012

A few unpleasant facts about Visual Studio 2012.

I have been playing with Visual Studio 2012 for the last couple of days. New IDE is pretty good, but, unfortunately, I found a few unpleasant facts.
First of all, new release is coming without Visual Studio setup projects. I am disappointed, because I am using it for my pet project – Easy Shutdown. The tool is a small widget-like application which allows you to reboot, log out or shut down you PC. I have not done any decision yet, but I would probably migrate to WiX.

The second surprise is Microsoft will not add Visual Studio macros to the next release. Since I am lazy guy, I like small hacks using macros. For example I have macros to refresh all projects or attach to IIS.  The only way how to solve the problem is to convert your macros to Visual Studio plugin. I have not tried it yet, but I will definitely do in the nearest future.

The third fact, I do not like, is Visual Studio default themes. May be somebody like it, but they are hard to adopt after Visual Studio 2010. Fortunately there is a solution. Matthew Johnson released Visual Studio 2012 Color Theme Editor. It comes with a few predefined themes. I really like the Blue one.

VS_2012_Blue_Theme

Posted On Wednesday, October 10, 2012 10:18 PM | Comments (1) |

Tuesday, October 9, 2012

Welcome!

Hello everyone! I am a Software Consultant, specializing in the Microsoft ecosystem and High Load Application, and this is my first blog.

The decision to start it was pretty easy. I had woken up one day and decided to start doing something outside my daily job. I have to reasons to start the blog. The first one is I would like to learn from community. There are a lot of really good people here. The second reason is I need a place where I can share some tricks, hacks and useful pieces of code with the others.

I will be glad to see if my blog helps somebody.

Welcome on board!

Posted On Tuesday, October 9, 2012 8:44 PM | Comments (0) |

Powered by: