Paging Made Easy with ASP.NET MVC 5, Entity Framework 6 and PageList.Mvc

Preface

In former days, implementing paging sometimes took a little bit of time. That was independent from the used platform, native Windows Client or Web or whatever.

Fortunately, that was then and this is now. Implementing paging in an ASP.NET MVC 5 Entity Framework 6 application really became simple. Just a few lines of code, and you’re done.

The Basics

The basics of paging in ASP.NET MVC are described by the Getting Started with EF 6 using MVC 5 tutorial Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application.

As the title says, you need EF 6 and MVC 5. The author Tom Dykstra suggests to use PagedList.Mvc. NuGet Must Haves lists this package on top of the Top 20 packages for paging. So I thought I’ll give it a try.

Using PagedList.Mvc

The usage is simple. As described by the ASP.NET tutorial, the package needs to be installed. I used the menu: Tools / NuGet Package Manager / Manage NuGet Packages for Solution….

Changing the View

The model of the view that should contain paging needs to be changed from IEnumetablle<MyModel> to PagedList.IPagedList<MyModel>. Also, the using of PagedList.Mvc and a link to the PagedList stylesheet needs to be added. After changing the code, the first tree lines of the view look like this:

@model PagedList.IPagedList<MyModel>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" 
  type="text/css" />

In case you want to show the current page and the total number of pages, add something like this to the appropriate place.

Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
 of @Model.PageCount

The last change is adding the paging buttons into the view.

@Html.PagedListPager(Model, 
  page => Url.Action("Index", new { page }) )

Changing the Controller

Because the view expects a different kind of model, the controller has to generate it. And because we need to return the content of different pages, the requested page is passed as a parameter. Given that db.MyModels returns something of type MyModel, the controller might look like this:

public ActionResult Index
  (
    int? page
  )
{
  var items = for item in db.MyModels select item;

  return (View(items.ToPagedList(pageNumber: page ?? 1, 
    pageSize: 10)));
}

That's really simple, isn't it.

Paging Extended

The code above works really good. But I want to extend the paging a little bit.

Let the User Choose

The number of items shown per page is fix in the sample above. I do not like that. So I added a dropdown list to the view to let the user choose how many items per page will be displayed.

The list of items shown by the dropdown list is generated by a helper method to make it reuseable.

public static class DefaultValues
{
  ...
  public static SelectList ItemsPerPageList 
    { 
      get 
      { return (new SelectList(new List { 5, 10, 25, 50, 100 }, 
        selectedValue: 10)); 
      } 
    }
  ...
}

To use this list, the view defines a local variable.

SelectList itemsPerPageList = DefaultValues.ItemsPerPageList;

And the dropdown list is placed wherever I like using the HtmlHelper

@Html.DropDownList("ItemsPerPage", itemsPerPageList, 
  new { @id = "ItemsPerPageList" })

To have the correct number of items per page shown when the user switches the page, we need to pass the current number of items to the controller. Therefor the HtmlHelper for the paging buttons needs to be extended.

@Html.PagedListPager(Model, page => Url.Action(ActionNames.Index,
  new { page, itemsPerPage = ViewBag.CurrentItemsPerPage }));

As you can see by this code, the controller needs some changes too.

public ActionResult Index
  (
    int? itemsPerPage,
    int? page
  )
{
  ViewBag.CurrentItemsPerPage = itemsPerPage;

  var items = for item in db.MyModels select item;

  return (View(items.ToPagedList(pageNumber: page ?? 1, 
    pageSize: itemsPerPage ?? 10)));
}

Handling an Empty List

From what I noticed, the Model of the view is null in case the list itself does not contain any items.

The extension method PagedListPager is not able to handle that. And of course, when showing the current page and the total number of pages, accessing a null reference leads to an exception too.

To avoid these exceptions, some more code is required.

@if (Model != null
  && Model.PageCount > 0)
  {
    <div>
      Page @(Model.PageCount < Model.PageNumber 
             ? 0 : Model.PageNumber) 
      of @Model.PageCount
    </div>
  }
@if (Model != null)
  {
    @Html.DropDownList("ItemsPerPage", itemsPerPageList, 
      new { @id = "ItemsPerPageList" })
}

Minor Stylesheet Additions

In my ASP.NET MVC application, I have a footer defined in the _Layout.cshtml file. In some cases I saw that the paging buttons partly were overlapped by the footer. To avoid this, I added a bottom margin to the pagination container style and put this into the Content/Site.css file:

.pagination-container {
  margin-bottom:25px;
}

Conclusion

Even with these small additions, paging is made really easy. What I was not looking at is the performance of the database access. For web applications with small databases, this does not seem to be important from my point of view. In case you do have a large database and complex database requests where performance is an issue, I think it's worth to check out the impact of this implementation.

Links

ASP.NET Tutorial: Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application

PagedList.Mvc on NuGet

NuGet Must Haves Top 20 NuGet packages for paging

Position the PopupMenu for Drag And Drop Operations in Windows Store Apps

Preface

Sometimes it is helpful to open a PopupMenu when the user drops items on a destination, e.g. to ask the user if the items should be copied or moved.

I’d like to open the PopupMenu exactly where the user released the mouse / finger, means put the upper left corner to this point on the screen.

The DragEventArgs, passed by the Drop event, do not provide the absolute coordinates, but the drop point that is relative to an UIElement.

Get the Position of a UIElement

Having the relative position of the drop point, we just need the absolute position of an UIElement – i.e. the drop destination, e.g. a ListView – to be able to calculate the absolute position of the PopupMenu.

Unfortunately, UIElement does not have a Position property or a GetPosition method. But it offers a method to “return a transform object that can be used to transform coordinates from the UIElement to the specified object“: UIElement.TransformToVisual.

To be honest, from reading the docs I would not have found out how to get the absolute position of a control. Because the docs do not mention that it is possible to pass null as a parameter.

The MSDN Context Menu Sample helped me out. Using this sample, I created an extension method for UIElement:

/// <summary>
/// Returns the position of the element.
/// </summary>
/// <param name="instance">The instance to be used.</param>
/// <returns>The position of the element.</returns>
public static Point GetPosition
  (
  this UIElement instance
  )
{
  // Return the position.
  return (instance.TransformToVisual(null)
          .TransformPoint(new Point()));
}

Add a Little Helper

Now that we have the absolute position of the drop destination, we just need to add the relative position of the drop point to the get the place where to open the PopupMenu.

Because Point does not offer an add operator, I created another extension method to keep the code tidy:

/// <summary>
/// Add the summand to the point.
/// </summary>
/// <param name="instance">The instance to be used.</param>
/// <param name="summand">The summand to be added.</param>
/// <returns>A new instance with the sum.</returns>
public static Point Add
  (
  this Point instance,
  Point summand
  )
{
  // Add the coordinates.
  return (new Point(instance.X + summand.X, instance.Y + summand.Y));
}

Use the Extentions

Using these extensions, the handling of the Drop event of a ListView and positioning of the PoupMenu at the drop point might look something like this:

private async void OnListViewDropAsync
  (
  object sender,
  DragEventArgs args
  )
{
  // The sender has to be a UIElement
  UIElement uiElement = sender as UIElement;

  if (uiElement == null)
  {
    return;
  }
  
  // Get the drop point in relation to the sender
  Point relativeDropPoint = args.GetPosition(uiElement);

  // Calculate the absolute position of the popup, 
  // using the extensions
  Point dropPoint = uiElement.GetPosition().Add(relativeDropPoint);

  // Create a popup
  PopupMenu menu = new PopupMenu();
  menu.Commands.Add(new UICommand("Copy"));
  menu.Commands.Add(new UICommand("Move"));
  menu.Commands.Add(new UICommand("Cancel"));

  // Show it at the drop point
  await menu.ShowAsync(dropPoint);

  // Do something depending on the user's selection.
}

Links

Context Menu Sample

VisualTreeHelper Extensions for Windows Store Apps

Preface

The VisualTreeHelperprovides utility methods that can be used to traverse object relationships (along child-object or parent-object axes) in the visual tree of your app.

In this post I will show two extensions to VisualTreeHelper. Since you cannot create an instance of VisualTreeHelper, these are not extension methods from a technical point of view. But they do extend the functionality, so I call them extensions here.

FindChildByName Extension

This extension searches a child element in the visual tree by its name. Of course, there are other ways to find a control by its name, e.g. FrameworkElement.FindName.

I needed to find a control that was created during runtime. I had a ListView with an ItemsSource bound to an ObservableCollection<T>. An ItemTemplate was defined, containing several controls. And I needed to access one particular control inside of this generated ListViewItem. FrameworkElement.FindName did not found it, even though a x:Name was defined in the DataTemplate.

This lead to the first extension.

// Implemented by VisualTreeHelperExtensions
/// <summary>
/// Searches a child element in the visual tree by its name.
/// </summary>
/// <param name="parent">
/// The parent of the element.
/// </param>
/// <param name="name">
/// The name of the child to search for.
/// </param>
/// <param name="child">
/// Set to the child if found, otherwise <c>null</c>.
/// </param>
/// <returns>
/// <c>true</c> if the child was found, otherwise <c>false</c>.
/// </returns>
/// <remarks>
/// This method walks the visual tree recursively!
/// </remarks>
public static bool FindChildByName
  (
  DependencyObject parent,
  string name,
  out FrameworkElement child
  )
{
  // [Input parameter validation omitted]
  // Set the output first
  child = null;

  // Walk the tree
  int childrenCount = VisualTreeHelper.GetChildrenCount(parent);

  for (int childIndex = 0; childIndex < childrenCount; ++childIndex)
  {
    // Get the child
    DependencyObject childObject 
      = VisualTreeHelper.GetChild(parent, childIndex);

    // Convert it into a framework element
    FrameworkElement childElement 
      = childObject as FrameworkElement;

    // if successfull, check the name
    if (childElement != null
      && childElement.Name.Equals(name))
    {
      // We found it
      child = childElement;
      // get out
      return (true);
    }

    // If the child contains the element, get out
    if (VisualTreeHelperExtensions
        .FindChildByName(childObject, name, out child))
    {
      return (true);
    }
  }

  // if we got here, we hadn't found the child
  return (false);
}

As you can see from the code, the class that implements this method is called VisualTreeHelperExtensions. In case you like to use this extension too, make sure to give your extension class the same name. In case you want to give it another name, please change the call of VisualTreeHelperExtensions.FindChildByName at the end of the method to TheNameOfYourClass.FindChildByName.

FindFirstChildByType Extension

In another scenario, I needed to find the first child of a given type, independent from its name.

// Implemented by VisualTreeHelperExtensions
/// <summary>
/// Searches the first child element in the visual tree by its type.
/// </summary>
/// <param name="parent">
/// The parent of the element.
/// </param>
/// <param name="type">
/// The type of the child to search for.
/// </param>
/// <param name="child">
/// Set to the child if found, otherwise <c>null</c>.
/// </param>
/// <returns>
/// <c>true</c> if the child was found, otherwise <c>false</c>.
/// </returns>
/// <remarks>
/// This method walks the visual tree recursively!
/// </remarks>
public static bool FindFirstChildByType
  (
  DependencyObject parent,
  Type type,
  out FrameworkElement child
  )
{
  // [Input parameter validation omitted]
  // Set the output first
  child = null;

  // Walk the tree
  int childrenCount 
    = VisualTreeHelper.GetChildrenCount(parent);

  for (int childIndex = 0; childIndex < childrenCount; ++childIndex)
  {
    // Get the child
    DependencyObject childObject 
      = VisualTreeHelper.GetChild(parent, childIndex);

    // Convert it into a framework element
    FrameworkElement childElement 
      = childObject as FrameworkElement;

    // if successfull, check the type
    if (childElement != null
      && childElement.GetType() == type)
    {
      // We found it
      child = childElement;
      // get out
      return (true);
    }

    // If the child contains the element, get out
    if (VisualTreeHelperExtensions
      .FindFirstChildByType(childObject, type, out child))
    {
      return (true);
    }
  }

  // if we got here, we hadn't found the child
  return (false);
}

As said above, the class that implements this method is called VisualTreeHelperExtensions. In case you like to use this extension too, make sure to give your extension class the same name. In case you want to give it another name, please change the call of VisualTreeHelperExtensions.FindChildByName at the end of the method to TheNameOfYourClass.FindFirstChildByType.

Links

VisualTreeHelper class

Extension Methods (C# Programming Guide)

FrameworkElement.FindName

Discover Properties of Storage Items in Windows Store Apps

Preface

Sometimes it is helpful to discover some or all properties of storage items (StorageFile, StorageFolder).

These classes implement the interfaces IStorageItem and IStorageItemProperties.

IStorgeItem.GetBasicPropertiesAsync gets an object that provides access to the basic properties of an item. IStorageItemProperties.Properties gets an object that provides access to the content-related properties of an item.

To get the properties themselves, you need to call BasicProperties.RetrievePropertiesAsync respectively StorageItemContentProperties.RetrievePropertiesAsync. Both methods expect a list of property names to retrieve. But, at the time of writing this post, the docs do not give a hint on the question:

Which Properties are Available?

The complete list of possible property names can be found here.

But the list does not tell you which property is available on which storage item type. Images might have some other properties like text files or folders. Luckily, there is an undocumented way (undocumented at the time of writing) to get a list of all possible properties: Just pass an empty list. This returns a list of all properties of the current storage item both for basic and content-related properties.

Exceptions

Using the empty-list approach I noticed that there is at minimum one exception to the rule. Having a StorageFolder object of the root directory of a drive, e.g. c:\, the properties “System.ItemType” and “System.ItemTypeText” are not contained in the returned dictionary.

On the other hand, calling StorageItemContentProperties.RetrievePropertiesAsync(new string[] { "Type" }) on such a storage item, the result contains one entry with the key “System.ItemTypeText” with the value “Local Disk” (or “Network Drive”). Please notice that there is no property named “Type” contained in the list of available properties. The behavior is the same on Windows 8.1 Preview.

Discovering

Putting this together, one might think that the combination of basic and content-related properties gives the sum of all properties. Well, it does. But from what I saw during my tests, both lists contain the items. There is no difference between the basic and the content-related list. So you are free to use one of them (observed this on Windows 8.1 Preview too).

Tracing Basic Properties

To trace out all the properties using the basic interface, one might use this code:

private static async Task TraceBasicPropertiesAsync
  (
  IStorageItem storageItem
  )
{
  Debug.WriteLine(
    "{0}Tracing basic properties of storage item >{1}< / >{2}<", 
    Environment.NewLine, storageItem.Name, storageItem.Path);

  BasicProperties basicProperties 
    = await storageItem.GetBasicPropertiesAsync();

  Debug.WriteLine(String.Format(CultureInfo.InvariantCulture, 
    "DateModified {0:u} (UTC), ItemDate {1:u} (UTC), Size {2}", 
    basicProperties.DateModified, basicProperties.ItemDate, 
    basicProperties.Size));

  IDictionary<string, object> basicPropertyList 
    = await basicProperties.RetrievePropertiesAsync(new string[] { });

  foreach (KeyValuePair<string, object> property 
    in basicPropertyList.OrderBy(item => item.Key))
  {
    Debug.WriteLine("BasicProperty >{0}<: >{1}<", 
      property.Key, property.Value);
  }

  if (basicPropertyList.ContainsKey("System.Kind"))
  {
    foreach (string kind 
      in (string[]) basicPropertyList["System.Kind"])
    {
      Debug.WriteLine("BasicProperty kind >{0}<", kind);
    }
  }
}

Tracing Content-Related Properties

The code to trace all the content-related properites looks very similar:

private static async Task TraceContentRelatedPropertiesAsync
  (
  IStorageItem storageItem
  )
{
  Debug.WriteLine(
    "{0}Tracing content-related properties of storage item >{1}< / >{2}<",
    Environment.NewLine, storageItem.Name, storageItem.Path);

  // We need a different interface to access the 
  // content-related properties.
  IStorageItemProperties storageItemProperties 
    = storageItem as IStorageItemProperties;

  if (storageItemProperties == null)
  {
    Debug.WriteLine("IStorageItemProperties not implemented",
      Environment.NewLine);
    return;
  }

  IDictionary<string, object> propertyList 
    = await storageItemProperties.Properties
      .RetrievePropertiesAsync(new string[] { });

  foreach (KeyValuePair<string, object> property 
    in propertyList.OrderBy(item => item.Key))
  {
    Debug.WriteLine("Property >{0}<: >{1}<", 
      property.Key, property.Value);
  }

  if (propertyList.ContainsKey("System.Kind"))
  {
    foreach (string kind 
      in (string[]) propertyList["System.Kind"])
    {
      Debug.WriteLine("Property kind >{0}<", kind);
    }
  }

  // Handle missing properties for root directories.
  if (!propertyList.ContainsKey("System.ItemTypeText"))
  {
    IDictionary<string, object> missingList
      = await storageItemProperties.Properties
        .RetrievePropertiesAsync(
          new string[] { "System.ItemType", "System.ItemTypeText" });

    foreach (KeyValuePair<string, object> property 
      in missingList.OrderBy(item => item.Key))
    {
      Debug.WriteLine("Property >{0}<: >{1}<", 
        property.Key, property.Value);
    }
  }
}

There is an extra loop on the “System.Kind” property becaus it contains a string array.

Links

Windows Property System that can be set on Windows files

MessageBox for Windows Store Apps in C# / XAML

Preface

The replacement of MessageBox for Windows Store apps is the class MessageDialog.

This class is fine as long as you do not need more than three options the user can choose from. In technical words, MessageDialog allows only up to three commands. At the time of writing, this is not mentioned in the documentation of the Commands property, but in Quickstart: Adding a message dialog (Windows Store apps using JavaScript and HTML). In case you try to add more commands, an exception will be thrown: “The operation attempted to access data outside the valid range (Exception from HRESULT: 0x8000000B)

Of course, I do have the need for more than three commands. But the new control should not differ much from MessageDialog.

This results in the following requirements:

  • Show the message box by calling a ShowAsync method
  • Dynamically add IUICommand-based commands with a button label, an optional Action that will be executed when the user selects the command, and an optional id
  • Define a default cancel and default focus command
  • Show a message, an optional title, and an optional symbol
  • Reset the focus when the message box closes

ShowAsync & Dynamic Number of Buttons

This part was the most challenging one – and the funniest one too 🙂

The approach in the sample is this:

  • Have a popup torso, ready to be filled with title, message, symbol, and command buttons
  • Create one button per command, and attach a ManualResetEvent to each button
  • Start a new thread and let it wait for of one these wait handles to be signaled, i.e. wait for the user to push one of the buttons
  • Map the signaled wait handle to the corresponding action
  • Meanwhile, await the completion of the new thread
  • Execute the action by the main (UI) thread
  • Return the selected command
  • Reset the focus

Add Commands To Popup

Before it makes sense to bring up the message box, the buttons for the commands have to be added. And there needs to be some kind of connection between the buttons and the ManualResetEvents that are required for async usage. Here is the implementation.

// Implemented by MessageBox
private void AddCommandsToPopup()
{
  // In case no commmand is set, 
  // add a continue command without an action.
  if (CommandList.Count == 0)
  {
    CommandList.Add(new UICommand("Continue"));
  }

  // Remove exiting buttons 
  // in case ShowAsync was called more than once.
  ControlStackPanel.Children.Clear();

  // Create the delegate command used when a button is pressed
  DelegateCommand<ManualResetEvent> delegateCommand
    = new DelegateCommand(OnButtonPressed);

  // Iterate over the list of commands.
  foreach (IUICommand command in CommandList)
  {
    // Create a new wait handle for the command
    ManualResetEvent waitHandle = new ManualResetEvent(false);

    // Add it to the list.
    WaitHandleList.Add(waitHandle);

    // Create the button and attach the wait handle.
    Button button = new Button()
    {
      Command = delegateCommand,
      CommandParameter = waitHandle,
      Content = command.Label,
      Style = (Style)Application.Current.Resources["ButtonStyle"]
    };
    
    // Add the button to the popup
    ControlStackPanel.Children.Add(button);
  }
}

Handling Button Pressed

This command handler is really simple. The only intention is to let the waiting thread know that a button was pressed. This is done by signal the ManualResetEvent that is associated to button as the CommandParameter. That’s it.

// Implemented by MessageBox
private void OnButtonPressed
  (
  ManualResetEvent waitHandle
  )
{
  // Just signal the wait handle.
  waitHandle.Set();
}

Open the Message Box and Wait For User Input

Now that everything is prepared, we can go on and show the message box.

// Implemented by MessageBox
public async Task ShowAsync()
{
  // Add all commands to the command bar 
  // and create the matching wait handles.
  AddCommandsToPopup();

  // Keeps the index of the signaled wait handle.
  int signaledHandle = -1;

  // Find the control currently having the focus
  Control focusedControl 
    = FocusManager.GetFocusedElement() as Control;

  // Start the thread to wait for user input.
  Task waitForUserInputTask = Task.Run(() =>
  {
    // Wait for a handle to be signaled.
    signaledHandle 
      = ManualResetEvent.WaitAny(WaitHandleList.ToArray());
  });

  // Open the message box with a popup.
  Popup popup = PopupHelper.CreateFullScreenWithChild(this);

  // Set the focus on the defined button
  if (FocusCommandIndex >= 0
    && FocusCommandIndex < CommandList.Count)
  {
    ((Button)(ControlStackPanel.Children[FocusCommandIndex]))
      .Focus(FocusState.Programmatic);
  }

  // Wait for the wait thread to finish 
  // (one of the events to be signaled)
  await Task.WhenAny(new Task[] { waitForUserInputTask });

  // Free all wait handles.
  while (WaitHandleList.Count > 0)
  {
    WaitHandleList[0].Dispose();
    WaitHandleList.RemoveAt(0);
  }

  try
  {
    // Invoke the event handler of the selected command 
    // in case it is defined.
    if (CommandList[signaledHandle].Invoked != null)
    {
      CommandList[signaledHandle].Invoked
        .Invoke(CommandList[signaledHandle]);
    }
  }
  catch (Exception)
  {
    // re-throw any exception caused by the event handler.
    throw;
  }
  finally
  {
    // Make sure the popup will be closed.
    popup.IsOpen = false;

    // Release the message box from the popup
    popup.Child = null;

    // Reset the focus
    if (focusedControl != null)
    {
      focusedControl.Focus(FocusState.Programmatic);
    }
  }

  // Return the selected command
  return (CommandList[signaledHandle]);
}

That’s all the “magic” behind the async call. The very important implementation detail is that the sequence of the list of commands and wait handle have to be the same. Because ManualResetEvent.WaitAny returns the index of the signaled wait handle, it is very simple to call the corresponding event handler.

UI Controls Must Not Have Multiple Parents

To be able to call ShowAsync more than once on the same MessageBox instance, it is important to “release” the instance from its containing Popup. This is done by setting the Popup.Child to null.

In case the MessageBox is not released, an exception will be thrown when it is set as the child of a newly created Popup. The exception’s message is “Value does not fall within the expected range.” It is thrown by Popup.put_Child, means the setter of the Child property.

Well, the message does not seem very helpful to me. But after all, it makes sense that a UI control cannot have multiple parents. This is why the local Popup‘s Child is set to null after it is closed.

Using the MessageBox

In case the implementation details are a little bit confusing to you: relax. You don’t have to implement it yourself 😉 Focus on the usage. This should look very familiar to all users of MessageDialog.

// Implemented by MainPage
private async Task ShowInformationAsync()
{
  // Create the message box.
  MessageBox messageBox 
    = new MessageBox("This is an information.", 
        "Showing information", MessageBoxSymbol.Information);

  // Add the commands
  messageBox.CommandList.Add(new UICommand("OK", 
    action: null, commandId: "Confirmed"));
  messageBox.CommandList.Add(new UICommand("Abort", 
    action: null, commandId: "Aborted"));

  // Set the index of the focus and cancel command
  messageBox.FocusCommandIndex =
  messageBox.CancelCommandIndex = 1;

  // Show the message box
  string selectedCommandId 
    = (string)(await messageBox.ShowAsync()).Id;

  // Show the value selected
  ResultTextBlock.Text = selectedCommandId;
}

This sample uses the id of the selected command. The code contains samples using the event handler (action) and just the command too.

Please notice that the MessageBox implementation allows you to add a symbol. There is a definition for information, warning, and error included in the sample. In case you need some more, feel free to extent the code.

Disable AppBars

The MessageBox suppresses the opening of app bars, caused by a right click, as long as it is open. This is implemented by MessageBox by handling the RightTapped event. The Handled property of the event arguments is set to true.

It does not prevent the app bar from being opened when the user swipes in from the lower edge. There is no simple event to be handled for this gesture. One idea might be to handle the Opened event of the AppBar. When a MessageBox is open, the event handler should close the AppBar immediately.

Popup Dialog Basics

Please refer to BusyIndicator for Windows Store Apps in C# / XAML for details on popup dialog basics, like disabling the user to interact with the app.

For details on command delegates, please refer to Simple and Generic ICommand Implementation for Usage in XAML.

The Sample

… can be found here.

Information MessageBox

Warning MessageBox

Error MessageBox

Links

Quickstart: Adding a message dialog (Windows Store apps using JavaScript and HTML)

BusyIndicator for Windows Store Apps in C# / XAML

Simple and Generic ICommand Implementation for Usage in XAML

Threading Objects and Features

BusyIndicator for Windows Store Apps in C# / XAML

Preface

The BusyIndicator for Windows Store apps is a variation of the Busy-Indicating Dialog for Windows Store apps.

The motivation for creating such a control is almost the same. No such a control is available. And I want to make sure the user cannot start a new task while a running one has not finished, without blocking the UI thread or fiddling around with flags and disabled controls.

In contrast to the busy-indicating dialog, the busy indicator should not offer the ability to cancel the operation. This is because the underlying operation can’t be canceled too. And it cannot show progress, because the underlying operation is an indeterminate task.

This leads to the following requirements:

  • Disable user interaction (‘lock’ the app)
  • Give visual feedback to let the user know interaction is disabled
  • Do not block the UI thread
  • Show some progress indication

Also, it should comply with these Windows 8 user experience guidelines for indeterminate tasks:

  • If the task is modal — it blocks interaction until its completion — use the indeterminate progress ring style
  • Provide status text to the right of the progress ring
  • Make the progress ring the same color as its status text
  • Disable controls that user shouldn’t interact with while the task is running (matches with the first item of the requirements list above)

Disable User Interaction

Disabling the user to interact with the app is quite simple. Rob Caplan gave me the initial idea in his answer on how one might implement a modal popup. He suggested to use a full screen popup with a similar look to the MessageDialog.

Creating a full screen popup, or better say a popup having the current size of the app, disables the interaction with the app. No matter if the user clicks, taps, or uses the pen.

The first requirement is (almost) fulfilled.

Disable Keyboard Interaction

The reason for the ‘almost’ above is this. When you enable keyboard shortcuts in your app like this sample does, you still need some flag fiddling.

The BusyIndicator only disables interaction via the screen (mouse, touch, pen), but not via the keyboard. This is because there is no control embedded into the BusyIndicator that will handle keyboard input. I tried to handle the KeyDown events, but hadn’t received any.

So the bad news is, one has to set a flag when an indeterminate task starts, and evaluate that flag when another task should be started.

The busy-indicating dialog does not have that issue, because it contains a button to cancel the operation. This button captures the keyboard input.

Give Visual Feedback

Depending on how the full screen popup is implemented, the user might not recognize that the interaction is disabled.

Looking at MessageDialog, one might notice that the area that is not covered by the dialog itself is dimmed out.

To achieve this, a UserControl is implemented. In the sample code, this user control is named BusyIndicator and can be found in UI/Xaml/Popups.

BusyIndicator contains one Grid without any content. This Grid has a black background and an opacity of 0.4.

Setting an instance of BusyIndicator as the child of the Popup, the app’s window gets dimmed out when the Popup is opened. The second requirement is fulfilled.

Do Not Block the UI Thread

Because common UI controls are used, this requirement can be fulfilled without any additional effort.

Of course, one has to take care that the operation to be performed is non-blocking. Means it should be implemented in an asynchronous way. But this is independent from the implementation of the BusyIndicator.

Show Some Progress Indication

Now, the user sees that the interaction is disabled. But there is no information about what is going on. This might lead to the impression that the app has stopped working.

To show that there is something going on in the background, BusyIndicator contains a second Grid. It is something like a modal dialog, showing processing information. This Grid contains a ProgressRing and aTextBlock.

The ProgressRing is what the guidelines demands for indeterminate tasks. The TextBlock makes the control comply with the guideline to provide some status text.

The text will be set when the BusyIndicator is created. There is no binding required, since the text will not change while the BusyIndicator is active.

Make the Progress Ring the Same Color as Its Status Text

To comply with this UX guideline, the file Assets/ApplicationStyles.xaml contains the following SolidColorBrush definition:

<SolidColorBrush x:Key="IndicatorTextBrush" Color="#383838"/>

This brush is used by the TextBlock and the ProgressRing of the indicator to set the Foreground property.

Creating the Busy Indicator

The following code snippet shows all the steps that needs to be done to show the busy indicator.

// Implemented by BusyIndicator
public static BusyIndicator Start
  (
  string title
  )
{
  // Create a popup with the size of the app's window.
  Popup popup = new Popup()
  {
    Height = Window.Current.Bounds.Height,
    IsLightDismissEnabled = false,
    Width = Window.Current.Bounds.Width
  };

  // Create the BusyIndicator as a child, 
  // having the same size as the app.
  BusyIndicator busyIndicator = new BusyIndicator(title)
  {
    Height = popup.Height,
    Width = popup.Width
  };

  // Set the child of the popop
  popup.Child = busyIndicator;

  // Postion the popup to the upper left corner
  popup.SetValue(Canvas.LeftProperty, 0);
  popup.SetValue(Canvas.TopProperty, 0);

  // Open it.
  popup.IsOpen = true;

  // Return the BusyIndicator
  return (busyIndicator);
}

Prepare the Indeterminate Task

Because there are several steps to be done before an indeterminate task can start, this is encapsulated in a separate method.

// Implemented by MainPage
private BusyIndicator PrepareIndeterminateTask
  (
  string title
  )
{
  // Disable the app bar
  BottomAppBar.IsEnabled = false;

  // Lock the screen by starting the BusyIndicator
  BusyIndicator busyIndicator = BusyIndicator.Start(title);

  // Set the flag
  IsTaskInProgress = true;

  // return the indicator
  return (busyIndicator);
}

Please notice the fact that the app bar is disabled explicitly. The popup does not ‘block’ the app bar.

Cleanup

When the indeterminate task has finished, some cleanup is required.

// Implemented by MainPage
private void CleanUpIndeterminateTask
  (
  BusyIndicator busyIndicator
  )
{
  // close the BusyIndicator
  busyIndicator.Close();

  // Reset the flag
  IsTaskInProgress = false;

  // Enable the app bar
  BottomAppBar.IsEnabled = true;
}

Consider Windows Store App Lifecycle

In the article ‘The Windows Store App Lifecycle‘, Rachel Appel points out that “Windows 8 is changing how and when applications run”. In fact, it does!

Unlike desktop applications, Windows 8 suspends Windows Store apps (after a few seconds) when the user switches to another app. No matter what the app is currently doing. You cannot keep the app ‘alive’.

One should be aware of this. It means the user has to wait for long running operation to complete, and should not switch to another app meanwhile. This is kind of ‘blocking’ the device. Keeping this in mind, one should think twice before using Windows Store apps to execute long running operations, e.g. copy gigabytes of data.

Yes, there are background tasks available. But you cannot trigger them from within your app. So the usage is limited.

The Sample

… can be found here.

Screenshot

Screenshot

Links

Busy-Indicating Dialog for Windows Store apps

Forum question Modal popup

Download Windows 8 User Experience Guidelines for Windows Store apps

The Windows Store App Lifecycle

Background Tasks

Forum question ‘Trigger background task manually

Busy-Indicating Dialog for Windows Store Apps in C# / XAML

Preface

Some of you might know the BusyIndicator from the WPF Toolkit or from Silverlight.

I was using this control in Silverlight to disable user interaction while the application was performing some long running operations. This makes it really easy to make sure the user will not start a new task while another has not yet finished. And – very important – it does not block the UI thread, so the application does not seem to be unresponsive to the operation system.

Microsoft does not offer such a control for Windows Store apps. But even in a Windows Store app I needed to make sure the user ‘waits’ for the completion of a task, before a new is started. And I do not wanted to implement this by adding a flag telling no new task can be started (and/or disable controls based on that flag, …).

So what I wanted was a control that meets the following requirements:

  • Disable user interaction (‘lock’ the app)
  • Give visual feedback to let the user know interaction is disabled
  • Do not block the UI thread
  • Show some progress indication
  • Enable the user to cancel the operation

Disable User Interaction

Disabling the user to interact with the app is quite simple. Rob Caplan gave me the initial idea in his answer on how one might implement a modal popup. He suggested to use a full screen popup with a similar look to the MessageDialog.

Creating a full screen popup, or better say a popup having the current size of the app, and setting the focus to that popup, no interaction with the app is possible any more. No matter if the user clicks, taps, or uses the keyboard or pen.

The first requirement is fulfilled.

Give Visual Feedback

Depending on how the full screen popup is implemented, the user might not recognize that the interaction is disabled.

Looking at MessageDialog, one might notice that the area that is not covered by the dialog itself is dimmed out.

To achieve this, a UserControl is implemented. In the sample code, this user control is named BusyIndicatingDialog and can be found in UI/Xaml/Popups.

BusyIndicatingDialog contains one Grid without any content. This Grid has a black background and an opacity of 0.4.

Setting an instance of BusyIndicatingDialog as the child of the Popup, the app’s window gets dimmed out when the Popup is opened. The second requirement is fulfilled.

Do Not Block the UI Thread

Because common UI controls are used, this requirement can be fulfilled without any additional effort.

Of course, one has to take care that the operation to be performed is non-blocking. Means it should be implemented in an asynchronous way. But this is independent from the implementation of the BusyIndicatingDialog.

Show Some Progress Indication

Now, the user sees that the interaction is disabled. But there is no information about what is going on. This might lead to the impression that the app has stopped working.

To show that there is something going on in the background, BusyIndicatingDialog contains a second Grid. It is something like a modal dialog, showing the current processing state. It contains some TextBlocks and a ProgressBar.

These controls are bound to a view model, implemented by BusyIndicatingViewModel. This class can be found in ViewModels.

BusyIndicatingViewModel implements an event handler, OnItemProcessed. The class that implements the long-running operation, MainPage in this sample, needs to fire an appropriate event every time an item is processed (or when an update of the progress should be displayed). This event is implemented by MainPage.ItemProcessed.

And because BusyIndicatingViewModel implements the INotifyPropertyChanged interface (via its base class BindableBase), setting the properties in OnItemProcessed updates all the controls of the dialog.

Cancel the Operation

So far, we are able to stop user interaction with the app, give visual feedback on this, do not block the UI thread, and show how the operation proceeds. But maybe the user wants to cancel that operation, for whatever reason.

To enable the user to do this, a cancel button is added to the BusyIndicatingDialog. Pressing this button, the Cancel event is fired by the BusyIndicatingViewModel. This is implemented by binding the Command property of the Button control to the CancelOperationCommand of the view model.

Of course, just firing an event does not stop anything at all. The class that implements the long-running operation, MainPage in this sample, has to register an event handler on this event. The event handler (OnCancelOperation) sets a flag. This flag is evaluated on each iteration of the long-running operation. When it is set, the operation stops.

This feature makes the BusyIndicatingDialog ready to use.

Creating the Busy-Indicating Dialog

The following code snippet shows all the steps that needs to be done to show the busy-indicating dialog.

// Implemented by BusyIndicatingDialog
public static BusyIndicatingDialog LockScreen
  (
  int numberOfItemsToProcess
  )
{
  // Create a popup with the size of the app's window.
  Popup popup = new Popup()
  {
    Height = Window.Current.Bounds.Height,
    IsLightDismissEnabled = false,
    Width = Window.Current.Bounds.Width
  };

  // Create the busy-indicating dialog as a child, 
  // having the same size as the app.
  BusyIndicatingDialog dialog 
    = new BusyIndicatingDialog(numberOfItemsToProcess)
  {
    Height = popup.Height,
    Width = popup.Width
  };

  // Set the child of the popop
  popup.Child = dialog;

  // Postion the popup to the upper left corner
  popup.SetValue(Canvas.LeftProperty, 0);
  popup.SetValue(Canvas.TopProperty, 0);

  // Open it.
  popup.IsOpen = true;

  // Set the focus to the dialog
  dialog.Focus(FocusState.Programmatic);

  // Return the dialog
  return (dialog);
}

Prepare the Long Running Operation

Because there are several steps to be done before the long running operation can start, this is encapsulated in a separate method.

// Implemented by MainPage
private BusyIndicatingDialog PrepareLongRunningOperation
  (
  int numberOfItemsToProcess
  )
{
  // Disable the app bar
  BottomAppBar.IsEnabled = false;

  // Lock the screen
  BusyIndicatingDialog indicatorDialog 
    = BusyIndicatingDialog.LockScreen(numberOfItemsToProcess);

  // Set the view model as the event handler for processed items
  ItemProcessed += indicatorDialog.ViewModel.OnItemProcessed;

  // Set the handler for the cancel event.
  indicatorDialog.ViewModel.Cancel += OnCancelOperation;

  // Reset the flag for canceling the operation.
  CancelOperation = false;

  // return the dialog
  return (indicatorDialog);
}

Please notice the fact that the app bar is disabled explicitly. The popup does not ‘block’ the app bar.

Cleanup

When the long running operation has finished, some cleanup is required.

// Implemented by MainPage
private void CleanUpLongRunningOperation
  (
  BusyIndicatingDialog indicatorDialog
  )
{
  // Operation has finished => deregister the event handler 
  // so the garbage collector can release the dialog
  ItemProcessed 
    -= indicatorDialog.ViewModel.OnItemProcessed;

  // close the dialog
  indicatorDialog.Close();

  // Enable the app bar
  BottomAppBar.IsEnabled = true;
}

Additional Considerations

I consider this implementation to be useful in cases where many items (or tasks) should be processed sequentially, while the processing of each single item does not take too long. Having one task that takes very long, no progress can be displayed and no cancelation is possible. If you have to cover such a scenario, I think you need to find another solution.

One thing really important is to give the UI thread a chance to update the dialog control and react on user input. To do so, you should add an await Task.Delay(1); between the processing of each item. Otherwise, in case the processing of the single item is really fast, the dialog might not be updated and(!) pressing the cancel button does not have any effect.

Consider Windows Store App Lifecycle

In the article “The Windows Store App Lifecycle“, Rachel Appel points out that “Windows 8 is changing how and when applications run”. In fact, it does!

Unlike desktop applications, Windows 8 suspends Windows Store apps (after a few seconds) when the user switches to another app. No matter what the app is currently doing. You cannot keep the app ‘alive’.

One should be aware of this. It means the user has to wait for long running operation to complete, and should not switch to another app meanwhile. This is kind of ‘blocking’ the device. Keeping this in mind, one should think twice before using Windows Store apps to execute long running operations, e.g. copy gigabytes of data.

Yes, there are background tasks available. But you cannot trigger them from within your app. So the usage is limited.

The Sample

can be found here.

Main screen

Processing

Links

Forum question Modal popup

Simple and Generic ICommand Implementation for Usage in XAML

The Windows Store App Lifecycle

Background Tasks

Forum question ‘Trigger background task manually

Simple and Generic ICommand Implementation for Usage in XAML

Preface

The Commanding Overview says “Commanding is an input mechanism in Windows Presentation Foundation (WPF) which provides input handling at a more semantic level than device input. Examples of commands are the Copy, Cut, and Paste operations found on many applications.

Well, one should extent the definition and mention Windows Store apps too. Commanding is not limited to WPF.

When looking for a sample implementation that could be used in Windows Store apps too, I found this forum post: ICommand and MVVM.

The implementation looked quite easy to me, but lacks of type safeness from my point of view.

So I extended the DelegateCommand class from this post to be more typesafe.

Generic ICommand Implementation

/// <summary>
/// Generic implementation of <see cref="ICommand"/>.
/// </summary>
/// <typeparam name="T">
/// Type of the parameter the command expects.
/// </typeparam>
/// <remarks>
/// Copied from http://social.msdn.microsoft.com/Forums/en-US/f457c906-56d3-49c7-91c4-cc35a6ec5d35/icommand-and-mvvm
/// </remarks>
public class DelegateCommand<T> : ICommand
{
  #region Private Properties

  /// <summary>
  /// Gets / sets the action to be executed.
  /// </summary>
  private Action<T> ExecuteAction { get; set; }

  #endregion Private Properties


  #region Public Events

  /// <summary>
  /// Occurs when changes occur that affect whether 
  /// the command should execute.
  /// </summary>
  public event EventHandler CanExecuteChanged;

  #endregion Public Events


  #region Public Constructors

  /// <summary>
  /// Initializes a new instance of <see cref="DelegateCommand"/>
  /// with the action to be executed.
  /// </summary>
  /// <param name="executeAction">
  /// Action to be executed.
  /// </param>
  public DelegateCommand
    (
    Action<T> executeAction
    )
  {
    ExecuteAction = executeAction;
  }

  #endregion Public Constructors


  #region Public Methods

  /// <summary>
  /// Determines whether the command can execute in its current state.
  /// </summary>
  /// <param name="parameter">Data used by the command.</param>
  /// <returns>
  /// <c>true</c> if this command can be executed; 
  /// otherwise, <c>false</c>.
  /// </returns>
  public bool CanExecute
    (
    object parameter
    )
  {
    return true;
  }

  /// <summary>
  /// Invokes the method to be called.
  /// </summary>
  /// <param name="parameter">Data used by the command.</param>
  public void Execute
    (
    object parameter
    )
  {
    ExecuteAction((T) Convert.ChangeType(parameter, typeof(T)));
  }

  #endregion Public Methods
}

Usage

This class is used something like this:

public class MyViewModel
{
  …
  public ICommand SomeMethodCommand { get; private set; }
  …
    public MyViewModel ()
    {
      // Set the command.
      SomeMethodCommand = new DelegateCommand(SomeMethod);
    }
  …
    public void SomeMethod
      (
      bool value
      )
    {
      // Do something
    }
}

The usage in XAML is like this:

<Button Content="Invoke SomeMethod" 
  Command="{Binding SomeMethodCommand}" 
  CommandParameter="true"/>

where the DataContext of the page is set to an instance of MyViewModel.

Limitations of the Implementation

As said, this is a simple implementation of ICommand.

It does not evaluate the value passed to CanExecute. And it does not fire an event in case the CanExecute state changes (which is not implemented here too).

Links

Commanding Overview

Forum Post ICommand and MVVM

Home-made Private Accessor for Visual Studio 2012+

Why Home-made?

Short answer: Starting with Visual Studio 2012, private accessors cannot be created any more by the IDE.

It seems that this does not bother too many people. The ‘Bring Back Private Accessor’ suggestion on UserVoice has not found any supporters right now.

Nevertheless, I still need access to private members of classes for testing purposes. And I do not want to declare them as internal because these members should not be (mis)used from within the same assembly.

Update 2013-11-09

Axel Mayer noted in the MSDN forums post How to create private accessors in VS 2012 that one can use the command line tool publicize.exe to create private accessors too. See Use Publicize.exe to Create Private Accessors for Visual Studio 2012+ for a detailed description.

The Goals

Just a few things:

  • Type safety
  • Protect from typos
  • Easy to handle when rename is required
  • Encapsulate / hide the use of PrivateObject

Use of PrivateObject

Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject is the base class to build up our own private accessor infrastructure. Well, infrastructure is such a big word. As you will see later, this infrastructure is really lightweight.

The direct use of PrivateObject has some disadvantages. You always have to use strings as parameters to invoke a method or get / set the value of a property. So there is a good chance the call of a method fails because I mistyped the method name. Some casting issues come up too. And using async / await in .NET 4.5, the direct use of PrivateObject.Invoke does not look really funny.

The direct use of PrivateObject looks like this

// Create an instance of the class to be tested.
ClassToBeTested instance = new ClassToBeTested ();

// Create a PrivateObject to access private methods of instance.
PrivateObject privateObject = new PrivateObject(instance);

// Create parameter values
object[] args = new object[] { "SomeValue" };

// Call the method to be tested via reflection, 
// and pass the parameter, and cast the result
int result = (int) privateObject.Invoke("PrivateMethod", args);

// Do some validation stuff

Create an Accessor Class

The first step to get away from this unpleasant and code inflating use of PrivateObject is to create an accessor class inside the unit test assembly.

This accessor class will hide the usage of PrivateObject. It gives type safety and helps to avoid typos on method- and property names. In case a member of the tested class is renamed, there is one single place to change in the test assembly. All other changes in the unit test can be done by Visual Studio renaming support.

A short version of the accessor to ClassToBeTested might look like this:

internal ClassToBeTestedAccessor
{
  private PrivateObject PrivateObject { get; set; }

  internal ClassToBeTestedAccessor()
  {
    PrivateObject = new PrivateObject(new ClassToBeTested());
  }

  internal int PrivateMethod
    (
    string parameter
    )
  {
    return ((int) PrivateObject
      .Invoke("PrivateMethod", new object[] { parameter }));
  }
}

And the test method using the accessor changes to this:

// Create an instance of the accessor.
ClassToBeTestedAccessor accessor = new ClassToBeTestedAccessor ();

// Call the method to be tested
int result = accessor.PrivateMethod("SomeValue");

// Do some validation stuff

Now the test method itself already looks the way I like it.

Make Accessor Reusable

Let’s assume there is the need for more than one accessor class in the test assembly. Then it might make sense to put some functionality into a base class for reuse purposes.

The base class should keep the instance of the tested class and the PrivateObject to access it. This means it have to be generic to get a type safe implementation.

This will be the starting point:

internal abstract class PrivateAccessorBase<T>
{
  private PrivateObject PrivateObject { get; set; }

  public T TestInstance 
    { get { return ((T)PrivateObject.Target); } }

  internal PrivateAccessorBase
      (
      T instance
      )
    {
      PrivateObject = new PrivateObject(instance);
    }
}

Please notice the public property TestInstance. This proporty gives access to the instance that is encapsulated by the private accessor. In case the unit test method needs to access public members of the tested class too, use this proporty.

What is common in my unit tests is to get or set the value of a property and to call a method. Therefore, the base class should offer the ability to do that.

Property Access

To get a property value, one might implement a method like this:

protected TReturnValue GetPropertyValue<TReturnValue>
  (
    string propertyName
  )
{
  return ((TReturnValue)PrivateObject
    .GetProperty(propertyName, null));
}

But this implementation still requires to pass the name of the property as a string. This can be avoided by using the call stack (in case you are using .NET 4.5 or higher, please have a look below to avoid StackFrame usage):

protected TReturnValue GetPropertyValue<TReturnValue>()
{
  // Need to remove the "get_" prefix from the caller's name
  string propertyName 
    = new StackFrame(1, true).GetMethod().Name
      .Replace("get_", String.Empty);

  return ((TReturnValue)PrivateObject
    .GetProperty(propertyName, null));
}

Setting a property value looks quite similar:

protected void SetPropertyValue
  (
  object value
  )
{
  // Need to remove the "set_" prefix from the caller's name
  string propertyName 
    = new StackFrame(1, true).GetMethod().Name
      .Replace("set_", String.Empty);

  PrivateObject.SetProperty(propertyName, value, new object[] { });
}

Having this base class, we can implement the ClassToBeTestedAccessor like this:

internal ClassToBeTestedAccessor
  : PrivateAccessorBase<ClassToBeTested>
{
  internal ClassToBeTestedAccessor ()
    : base(new ClassToBeTested())
  {
  }

  internal int PrivateProperty
  {
    get { return (GetPropertyValue<int>()); }
    set { SetPropertyValue(value); }
  }
}

The usage of the property by the test class does not differ from the usage of ‘normal’ properties:

// Create an instance of the accessor.
ClassToBeTestedAccessor accessor = new ClassToBeTestedAccessor ();

// Set the value
accessor.PrivateProperty = 231;

Debug.WriteLine("PrivateProperty: >{0}<", accessor.PrivateProperty); 

Method Access

Based on this, it is simple to implement the access of non-public methods in the accessor base class.

// Implemented by PrivateAccessorBase
protected TReturnValue Invoke<TReturnValue>
  (
   params object[] parameter
  )
{
  return ((TReturnValue)PrivateObject.Invoke(
    new StackFrame(1, true).GetMethod().Name, parameter));
}

The accessor class uses this method like this:

// Usage by ClassToBeTestedAccessor
internal int PrivateMethod
  (
  string parameter
  )
{
  return (Invoke(parameter));
}

Using the PrivateAccessorBase together with a derived accessor class, the typo danger is eliminated. We got type safety, the accessor implementation does not contain PrivateObject usage, and there is a single place to be changed when some property or method names of the tested class will change.

Preconditions

There is only one precondition: The properties and methods names of the accessor class have to match 100 percent with the corresponding members of the tested class!

Avoid Inlining

One thing really important when using the StackFrame is to make sure the caller's name will not change. How might this happen? When the JIT compiler thinks it should optimize the code by inlining methods.

This would be fatal when using the call stack to get the name of the original caller. As soon as a method is inlined, the call stack changes.

Sample: Assume ClassToBeTestedAccessor.PrivateMethod will be optimized, because it only contains the call to PrivateAccessorBase.Invoke. In this case, the name of the caller in PrivateAccessorBase.Invoke won't be 'PrivateMethod' any more, but the name of the method that called ClassToBeTestedAccessor.PrivateMethod. Using this name, let's assume it is 'TestPrivateMethod', as the method name parameter of PrivateObject.Invoke, the test will fail with an exception, telling the method 'TestPrivateMethod' was not found.

Even if unit tests normally run in debug mode (the 'Optimize code' option is not set in the project's build configuration), one should be aware of this. To make sure the JIT compiler does not inline a method, set the [MethodImpl(MethodImplOptions.NoInlining)] attribute. The sample solution shows how and where.

Changes in .NET 4.5

In case you can use .NET 4.5 or above, you don't have to care about inline optimization 🙂

.NET 4.5 introduced the class CallerMemberNameAttribute. Using this class, there is no need to worry about these things. The attribute is processed by the C# compiler when it produces the IL code. Optimization is done by the JIT compiler later on (see forum post CallerMemberNameAttribute and Inlining).

For the .NET 4.5 implementation, the usage of MethodImpl and StackFrame is obsolete. The PrivateAccessorBase changes to this:

// Implemented by PrivateAccessorBase
protected TReturnValue GetPropertyValue<TReturnValue>
  (
  [CallerMemberName] string callerName = null
  )
{
  return ((TReturnValue)PrivateObject.GetProperty(callerName, null));
}

protected void SetPropertyValue
  (
  object value,
  [CallerMemberName] string callerName = null
  )
{
  PrivateObject.SetProperty(callerName, value, new object[] { });
}

protected TReturnValue Invoke<TReturnValue>
  (
  [CallerMemberName] string callerName = null,
  params object[] parameter
  )
{
  return ((TReturnValue)PrivateObject.Invoke(callerName, parameter));
}

Please notice that even the removal of the 'get_' / 'set_' prefix is not required any more.

The ClassToBeTestedAccessor has to name the parameter passed to PrivateAccessorBase.Invoke to make sure the first parameter is not interpreted as the caller method name.

// Implemented by ClassToBeTestedAccessor
internal string ProtectedMethod
  (
  string parameterValue
  )
{
  // Need to name the parameter, 
  // otherwise the first parameter will be 
  // interpreted as caller's name.
  return (Invoke(parameter: parameterValue));
}

Test Static Member

To access static class members, no class instance or PrivateObject is required. The PrivateAccessorBase collects all properties and methods the type defines, using the static constrcutor.

// Implemented by PrivateAccessorBase
private static IEnumerable DeclaredProperties { get; set; }

private static IEnumerable DeclaredMethods { get; set; }
…
static PrivateAccessorBase()
{
  TypeInfo typeInfo = typeof(T).GetTypeInfo();

  PrivateAccessorBase<T>.DeclaredProperties 
    = typeInfo.DeclaredProperties;

  PrivateAccessorBase<T>.DeclaredMethods 
    = typeInfo.DeclaredMethods;
}

One have to search for the property / method having the matching name, and invoke it.

// Implemented by PrivateAccessorBase
protected static TReturnValue GetStaticPropertyValue<TReturnValue>
  (
  [CallerMemberName] string callerName = null
  )
{
  return ((TReturnValue)PrivateAccessorBase<T>
    .DeclaredProperties
      .Single(info => info.Name.Equals(callerName))
        .GetValue(null));
}

protected static void SetStaticPropertyValue
  (
  object value,
  [CallerMemberName] string callerName = null
  )
{
  PrivateAccessorBase<T>.DeclaredProperties
    .Single(info => info.Name.Equals(callerName))
      .SetValue(null, value);
}

protected static void InvokeStatic
  (
  [CallerMemberName] string callerName = null,
  params object[] parameter
  )
{
  PrivateAccessorBase<T>.DeclaredMethods
    .Single(info => info.Name.Equals(callerName))
      .Invoke(null, parameter);
}

Please note that this is the .NET 4.5 implementation. For .NET version < 4.5, please refer to the sample solution.

Test Async Methods

Having the above in place, and putting it together with the description of the post Unit-Testing of Private Async Methods with Visual Studio, it is easy to extend the base class to be ready for calling async methods.

// Implemented by PrivateAccessorBase
protected async Task<TReturnValue> InvokeAsync<TReturnValue>
  (
  [CallerMemberName] string callerName = null,
  params object[] parameter
  )
{
  TReturnValue returnValue 
    = await (Task<TReturnValue>)PrivateObject
      .Invoke(callerName, parameter);

  return (returnValue);
}

The derived class uses it like this:

// Implemented by ClassToBeTestedAccessor
internal async Task<double> PrivateMethodWithReturnValueAsync
  (
  int millisecondsDelay,
  string outputText
  )
{
  double returnValue 
    = await InvokeAsync<double>
      (parameter: new object[] { millisecondsDelay, outputText });

  return (returnValue);
}

And the testing class uses the accessor this way:

// Implemented by ClassToBeTestedTest
[TestMethod]
public async Task TestPrivateMethodWithReturnValueAsync()
{
  int millisecondsDelay = 300;
  string testValue = "method unit test";

  ClassToBeTestedAccessor accessor 
    = new ClassToBeTestedAccessor();

  double result 
    = await accessor
      .PrivateMethodWithReturnValueAsync(millisecondsDelay, testValue);

  // Do validation stuff
}

Not Complete

The intention of this post and the sample solution is to give you an idea on how to create a home-made private accessor, and what to take care of when doing so.

The intention is not to offer a complete substitute of Visual Studio's Private Accessor Creation feature.

Accordingly, not all possible unit test scenarios are covered. Please feel free to extend the code for your needs and share your solutions and ideas with us by adding comments describing it.

Conclusion

Having this accessor base class, the creation of private accessors should be quite easy. Of course, not as easy as clicking a menu item, but better than fiddling around with PrivateObject.

The code snippets in this post might look a little bit complex and / or confusing. In this case, try to focus on the test class and accessor. Forget about the PrivateAccessorBase.

I hope you agree that both the creation of the accessor and the usage by the test class will be very comfortable and straightforward, having PrivateAccessorBase in place.

The Sample Solution

The sample solution contains four projects:

  • ConsoleApplication contains the class to be tested, based on .NET 4.0.
  • ConsoleApplication.4.5 contains the class to be tested, based on .NET 4.5.
  • ConsoleApplication.Test contains the PrivateAccessorBase, the accessor class, and the unit test class for ConsoleApplication, based on .NET 4.0.
  • ConsoleApplication.Test.4.5 contains the PrivateAccessorBase, the accessor class, and the unit test class for ConsoleApplication.4.5, based on .NET 4.5.

The class that is tested is ClassWithNonPublicMembers, located in the ConsoleApplication… projects.

You need Visual Studio 2012 or higher to build the solution.

Here you can download the code.

Test Explorer Output

Links

Upgrading Unit Tests from Visual Studio 2010

'Bring Back Private Accessor' suggestion on UserVoice

Eric Gunnerson's Compendium: Why doesn't C# have an 'inline' keyword?

CallerMemberNameAttribute

Forum question CallerMemberNameAttribute and Inlining

MSDN forum post How to create private accessors in VS 2012

Use Publicize.exe to Create Private Accessors for Visual Studio 2012+

Microsoft Advertising Services AdControl Error Handling in XAML/C#

Preface

The Do’s + Don’ts of the Advertising SDK say “DO plan for times when no ads are available.” The links of that item leads to the ErrorCode enumeration and a rudimentarily error handling sample, writing text to debug output.

In this post, I will show an error handling where the AdControl is replaced by a TextBlock when an error occurs. Of course, this is still not a high sophisticated error handling. But it might give an idea what to do when no ad is available.

Ian Ferreira suggests in his blog post Keep Users First By Using These Resources For Ad Control Error Handling to hard code a house ad into the real-estate where an ad will appear.

Error Handling by Convention

The error handling is based on naming conventions. What it does is looking for a TextBlock having a name matching the naming pattern.

Following the convention, the name of the TextBlock has to be the name of the AdControl to be replaced, extended by ErrorTextBlock.

Sample: The name of the AdControl receiving an error is AdControlBottom. According to the naming convention, the name of the TextBlock to handle the error is AdControlBottomErrorTextBlock.

This makes it easy to implement a search for the correct replacement control. No additional properties need to be defined for the AdControl. And it follows MVC’s “Convention instead of Configuration” approach.

When an error occurs, the AdControl is made invisible, while the TextBlock at the same position will become visible. To make sure the design of the page does not change, the control that replaces the AdControl must have the same size as the AdControl.

In the sample app, just the name of the error-causing control, the reason, and the error text is displayed, no matter what the error code is. In real world scenarios, one should handle different errors differently. For example, just because an ad cannot be refreshed, I would not replace the existing one.

Here is how the handler is implemented:

protected virtual void OnAdControlErrorOccurred
  (
  object sender,
  AdErrorEventArgs args
  )
{
  AdControl adControl = sender as AdControl;

  // If event is not thrown by an Ad Control, do nothing
  if (adControl == null)
  {
    return;
  }

  // Just write out an error message.
  Debug.WriteLine("AdControl error (" + adControl.Name + "): " 
    + args.Error + " ErrorCode: " + args.ErrorCode.ToString());

  // Replace adControl by TextBlock showing error message.
  // Find the TextBlock by naming conventions. 
  // The name of the TextBlock is the name of the AdControl plus "ErrorTextBlock".
  TextBlock textBlock = FindName(
    String.Format("{0}ErrorTextBlock", adControl.Name)) 
  as TextBlock;

  if (textBlock == null)
  {
    return;
  }

  // Hide the AdControl
  adControl.Visibility = Visibility.Collapsed;

  // Show the TextBlock and copy properties.
  textBlock.Visibility = Visibility.Visible;

  textBlock.Height = adControl.Height;

  textBlock.Width = adControl.Width;

  // Set some text.
  textBlock.Text = String.Format("Sorry!{0}"
    + "Can't show AdControl '{1}'.{0}{0}ErrorCode: {2}{0}{0}ErrorMessage: {3}", 
    Environment.NewLine, adControl.Name, args.ErrorCode, args.Error.Message);
}

Please have a look at the sample code to see the XAML implementation. You can look at SubPages/SamplePage300x250.xaml, SubPages/SamplePage300x600.xaml, or SubPages/ SamplePageMultiple.xaml.

Sample Code

The sample code is part of the post Configure Microsoft Advertising Services’ AdControl using XAML/C#.

Links

Ads in Apps for Windows 8

AdControl Error Handling

AdControl ErrorCode Enumeration