"Dream as if you'll live forever, live as if you'll die today (James Dean)"
(ASP).NET - C# - System Architecture - and more...

Unit testing Dispatcher UnhandledException events from a DependencyObject

with 0 Comments
Posted under .NET | Testing | MVVM |

While working on some legacy WPF application, I required a way to unit test the code I attach to the ViewModel’s base Dispatcher.UnhandledException event.

The ViewModel base class derived from the DependencyObject class, which in turn derived from the DispatcherObject class.

[sourcecode language='csharp'  padlinenumbers='true']
public class DependencyObject : DispatcherObject
public abstract class ViewModelBase : DependencyObject, INotifyPropertyChanged, IDisposable, INotifyDataErrorInfo
public class MyViewModel : ViewModelBase
[/sourcecode]


The goal is to reset the IsBusy property in case of any exception that occurs during the ViewModel’s actions.

[sourcecode language='csharp' ]
public MyViewModelBase()
    : base()
{
    this.Dispatcher.UnhandledException += this.HandleException;
}
		
protected virtual void HandleException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    if (!e.Handled)
    {
        //// do any logging if it's not yet done by other registered events.
        e.Handled = true;
    }

    //// Clear the busy indicator after an exception occured.
    this.IsBusy = false;
}

//// Clean up by removing the event handler.		
protected override void Dispose(bool disposing)
{
    if (!this.disposed)
    {
        if (disposing)
        {
            this.Dispatcher.UnhandledException -= this.HandleException;
        }

        this.disposed = true;
    }

    base.Dispose(disposing);
}
[/sourcecode]


There’s a lot of discussions around how to unit test Dispatcher. I agree with the statement that you should not unit test it, but abstract it behind an interface that you can mock. However, this may imply a too large refactoring for the time being.

I took the provided example code failed to make my code execute correctly within the unit test.

That is until I realised I should actually invoke my method through the Dispatcher object.

Note: this implementation works for me, but may not work for anyone else with a slight different problem !

[sourcecode language='csharp' ]
[TestMethod]
public void ValidateExceptionHandlingBusyIndicator()
{
     myViewModel.IsBusy = true;
     new DispatcherUtil().DoEvents(
         async () =>
          await myViewModel.CallMethodThatThrowsExceptionAsync());

     Assert.IsFalse(this.viewModel.IsBusy, "Expect IsBusy to be false.");
 }
[/sourcecode]


Here’s the DispatcherUtil code that I took from here. The changes made are passing in the Action to invoke within the Frame’s Dispatcher object.
 

[sourcecode language='csharp' ]
internal class DispatcherUtil
{
    [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    internal void DoEvents(Action action)
    {
        DispatcherFrame frame = new DispatcherFrame();
        Dispatcher.CurrentDispatcher.Invoke(action);

        Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new DispatcherOperationCallback(this.ExitFrame), frame);
        Dispatcher.PushFrame(frame);                
    }

    internal object ExitFrame(object frame)
    {
        ((DispatcherFrame)frame).Continue = false;
        return null;
    }
}
[/sourcecode]


There are a couple of known issues. for one, I could not make it work by using the async BeginInvoke method.

Stretch the content of a ContentControl

with 0 Comments
Posted under Windows Phone | XAML |

A quick post to a “aha”-moment I just had.

I created a DataTemplate in xaml that contains a StackPanel with an Image and TextBlock in it.

<DataTemplate x:Key="PageHeader">
 <StackPanel Height="50" Background="{StaticResource MySecondStyle}" Orientation="Horizontal">
   <Image Source="/Assets/MyImage.png" />
   <TextBlock Text="{Binding}" Margin="2"
                 Style="{StaticResource MyStyle}" 
                 FontWeight="Bold"
                 HorizontalAlignment="Stretch"/>
 </StackPanel>
</DataTemplate>

In my page, I created a ContentControl with the above DataTemplate as ControlTemplate.

<ContentControl Content="My Title" ContentTemplate="{StaticResource PageHeader}" />

As you can guess, I wanted to stretch the TextBlock over the total width of my page, without success.
I played around with different HorizontalAlignment properties on different levels in the page hierarchy.

Until I stumbled upon the HorizontalContentAlignment property of the ContentControl itself.

<ContentControl HorizontalContentAlignment="Stretch" Content="New" ContentTemplate="{StaticResource PageHeader}" />

Now the whole content container is stretched by default.

Unable to change build platform for an individual project

with 0 Comments
Posted under Visual Studio |

I recently added a new project to a solution that was building for x64. When extending the dropdown, only Any CPU was available.

image

Adding a new Platform resulted in following error

image

I was stunned by it until someone pointed out the checkbox below

image

Since the solution already had an x64 platform configured, this needs to be unchecked.

About Task.WaitAll and Task.WhenAll

with 0 Comments
Posted under .NET | Async | C# |

When starting a number of Tasks in parallel, you then then wait until all the tasks are finished before continuing with your logic.

The most known method, at least to me, is using the Task.WaitAll.

var tasks = new List<Task>();
tasks.Add(StartNewTask());
tasks.Add(StartNewTask());
Task.WaitAll(tasks.ToArray());

This worked fine, until one of my colleagues called this library from within a Windows Form application. Turns out, we ended up with a Task deadlock.

The answer was found on StackOverflow.
In short, WaitAll is a “blocking call” meaning that it will block the application until the execution is finished. If you want to make a true async API, you should make sure never to have any blocking calls anywhere.

It seems there’s another method called Task.WhenAll that

“Creates a task that will complete when all of the supplied tasks have completed.”

Rewriting the above code, this gives us the following

var tasks = new List<Task>();
tasks.Add(StartNewTask());
tasks.Add(StartNewTask());
await Task.WhenAll(tasks);

The advantage is that await will free the calling thread, in this case the UI, will be freed and avoid any deadlocks from happening.

An important thing to keep in mind when creating async API libraries that needs to be consumed by any kind of client. 

Auto scroll a ListBox when SelectedIndex change

with 0 Comments
Posted under MVVM | XAML |

You can easily bind the SelectedIndex property of a ListBox control to a property in the corresponding ViewModel.
However, if you change the selected index through the view model, you’ll see that the ListBox is not scrolling.

There is not clean way to do this using pure your ViewModel because to make it work, you will need a reference to your actual ListBox object.

The best way is just adding an event on the SelectionChanged in your page’s code behind file.

<ListBox ItemsSource="{Binding Items}"
SelectedIndex="{Binding SelectedItemIndex, Mode=TwoWay}"
Width="500" Height="100"
ScrollViewer.VerticalScrollBarVisibility="Auto" 
SelectionChanged="ListBox_SelectionChanged" />

This event is fired every time a selection changes in your ListView. Following code will scroll your ListBox to the new selected item.

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var newSelectedItem = e.AddedItems.FirstOrDefault();
    if(newSelectedItem != null)
    { 
       (sender as ListBox).ScrollIntoView(newSelectedItem);
    }
}

The AddedItems property of the SelectionChangedEventArgs will contain the new selected item. the DeletedItems property contains the previous item.

Note that this code expect that you have only a single selection going on.
With multi-selection active, your AddedItems may contain more than one and you will have to add some logic to decide which item needs to be scrolled to.

Continue a Task with async Continuations

with 0 Comments
Posted under .NET | Async |

What if you want to add a Continuation on a Task that should run synchronous 2 other async methods?

My initial idea was having code like this:

var initialTask = SomeMethodThatReturnsATaskAsync();
...
var completionTask = initialTask.ContinueWith(
    async (task) =>
    {
        await SomeAsyncMethodAsync();
        await AnotherAsyncMethodAsync();
    });

Task.WaitAll(new[]{initialTask, completionTask});

But it turned out that the Task.WaitAll finished before the AnotherAsyncMethodAsync was called.

Basically, I had the same issue that this person had on StackOverflow. And just like him, I found the solution in the answer.

By using the Unwrap method. I led you read for yourself how it works, but this is the final code that does what I expected to do.

var initialTask = SomeMethodThatReturnsATaskAsync();
...
var completionTask = 
    initialTask
        .ContinueWith((task) => SomeAsyncMethodAsync())
        .Unwrap().ContinueWith((task) => AnotherAsyncMethodAsync());

Task.WaitAll(new[]{initialTask, completionTask});

So the first callback is actually returning a Task<Task> object. You need to hook the Continuation to the actual Task object, accessible through the Unwrap method.

Investigate Visual Studio 2013 crash on project loading

with 0 Comments
Posted under Visual Studio |

I ended up re-installing Visual Studio 2013 on a complete new Desktop installation.
After logging in with my Microsoft Account, Visual Studio just crashed every time I wanted to either open an existing Solution/Project or create a new Project. Just… “Stopped working”.

Searching on the web shows me that in most cases this is/may be caused by an installed Visual Studio Extensions. Question is, which one.
Lucky, I never have installed too many of them.

Of course, first let’s verify and run Visual Studio in Safemode. This will disable all extensions (not that it will also break your source control plugins).

devenv.exe /safemode

Since that seemed to work fine, all I have to know now is which extension causes the problem.
Instead of disabling them all and enabling them one by one, I activated the activity log.

devenv.exe /log

After this, you will find an ActivityLog.xml file in the AppData directory of Visual studio

C:\Users\Ronald\AppData\Roaming\Microsoft\VisualStudio\12.0\ActivityLog.xml

It’s xml, but if you just search for ERROR you will get there. In my case, I found some entries like this

321 ERROR Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
          C:\USERS\RONALD\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\12.0\EXTENSIONS\EO1BBWUI.1QL\WebEssentials2013.dll   Microsoft.VisualStudio.CommonIDE.ExtensibilityHosting.VsShellComponentModelHost 2014/06/22 15:10:47.614 
322 ERROR Could not load file or assembly 'Microsoft.JSON.Core, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
          C:\USERS\RONALD\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\12.0\EXTENSIONS\EO1BBWUI.1QL\WebEssentials2013.dll   Microsoft.VisualStudio.CommonIDE.ExtensibilityHosting.VsShellComponentModelHost 2014/06/22 15:10:47.614 
323 ERROR Could not load file or assembly 'Microsoft.JSON.Core, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
          C:\USERS\RONALD\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\12.0\EXTENSIONS\EO1BBWUI.1QL\WebEssentials2013.dll   Microsoft.VisualStudio.CommonIDE.ExtensibilityHosting.VsShellComponentModelHost 2014/06/22 15:10:47.614 
324 ERROR Could not load file or assembly 'Microsoft.JSON.Core, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
          C:\USERS\RONALD\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\12.0\EXTENSIONS\EO1BBWUI.1QL\WebEssentials2013.dll   Microsoft.VisualStudio.CommonIDE.ExtensibilityHosting.VsShellComponentModelHost 2014/06/22 15:10:47.614 
325 ERROR Could not load file or assembly 'Microsoft.JSON.Core, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
          C:\USERS\RONALD\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\12.0\EXTENSIONS\EO1BBWUI.1QL\WebEssentials2013.dll 

I see here some references to WebEssentials2013.dll that can not be loaded. Good to know, WebEssentials 2013 is indeed a plugin that I had installed previously, but not anymore.

Uninstalling this plugin from the manager window fixed the problem.

So what happened? Since Visual Studio 2013 now synchronizes your settings through your Visual Studio account in the cloud, it was still configured to expect this extension. However, I did not re-install this extension when installing Visual Studio this time.

Extend ExpectedException attribute in MsTest

with 0 Comments
Posted under Testing | MsTest |

Quite often you find yourself in a situation to test thrown “expected” exceptions by your code.
Most often test frameworks like NUnit will use an ExpectedException attribute for your Unit Test.

However some frameworks like xUnit move towards a newer way of handling this scenario.

The nice thing with the NUnit attribute is that it will also allow you to specify the expected message to be returned by the exception.
This is one feature that is missing when using Microsoft’s MsTest framework.

But you can extend the attribute to add similar functionalities, and more, to the attribute.

Important note, ExpectedException is sealed, so you cannot directly override from it. But you can implement your own Attribute using the same ExpectedExceptionBaseAttribute class.

public sealed class ExpectedCustomExceptionAttribute : ExpectedExceptionBaseAttribute
{
  ...
}

Define the ExpectedType and ExpectedMessage properties

public Type ExpectedExceptionType { get { return this.expectedExceptionType; } }
public string ExpectedExceptionMessage 
{ 
    get { return this.expectedExceptionMessage; } 
    set { this.expectedExceptionMessage = value; } 
}

And create an appropriate constructor

public ExpectedCustomException(Type expectedType, string expectedMessage) { ... }

The last part is overriding the Verify method from the base class and perform an extra Assert on the message.

protected override void Verify(Exception exception)
{
    Assert.IsNotNull(exception);

    Assert.IsInstanceOfType(exception, this.ExpectedExceptionType);

    if (this.ExpectedExceptionMessage != null)
    {
        Assert.AreEqual(this.ExpectedExceptionMessage, exception.Message);
    }
}

I verify if there is an expected exception message defined. This allows more flexibility in using the attribute.

[ExpectedCustomException(typeof(MyCustomException), ExpectedExceptionMessage="Exception message")]
public void MyExceptionTest() { ... }

[ExpectedCustomException(typeof(NullReferenceException))]
public void MyExceptionTest() { ... }

Of course, you can extend it to test whatever you want on the Exception. Useful if you have custom exceptions with specific data integrated.

Adding a fixed title to a Windows Phone Panorama page

with 0 Comments
Posted under Windows Phone | XAML |

I’m not a designer and this Windows Phone App is also my first real experience with XAML. However, I a successful app is not only based on its functionalities. In some cases I may even think a good functionality is completely unnecessary.

But that beside, I recently saw an app that uses the Panorama page, but where the title is always fixed on top and does not scroll with the panorama items as they do by default.

You have to admit, even for a none-design aware person like me, the default title style looks ugly. So I thought this may be nice for my app as well.

I actually found the solution pretty quick. However I found a solution that makes your XAML look more natural. 

First, devide the main Layout Grid in 2 columns, the first one with an Auto width and the second taking all available space.

<Grid x:Name="LayoutRoot">
  <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
      <RowDefinition Height="*"/>
  </Grid.RowDefinitions>

Next, add in the first Grid row a customized Grid containing an image and the application name

<Grid Height="50" Background="{StaticResource PhoneAccentBrush}"
          VerticalAlignment="Top">    
  <Grid.RowDefinitions>        
    <RowDefinition />    
  </Grid.RowDefinitions>    
  <Grid.ColumnDefinitions>        
    <ColumnDefinition Width="50" />         
    <ColumnDefinition Width="*" />    
  </Grid.ColumnDefinitions>    
  <Image Source="/Assets/ApplicationIcon.png"  />   
  <TextBlock Text="Gluco" Margin="2"
             Grid.Column="1" 
             Style="{StaticResource PhoneTextLargeStyle}" FontWeight="Bold"/>
</Grid>

As last, override the Title Property of the Panorama control and add a custom Grid with Height set to 0.

<phone:Panorama Grid.Row="1">  
  <phone:Panorama.Title>      
    <Grid Height="0"  />  
  </phone:Panorama.Title>   
  <!-- panorama items --> 
</phone:Panorama>

And this is then the final result. Next you can add this Header Grid to other pages to make a consistent look and feel.

image

Access data between pages with ObservableCollection

with 0 Comments
Posted under Data Binding | Windows Phone | MVVM |

Spend some time recently on Collection binding and how data can be shared/accessed/updated between pages.
I short, I would have a page that displays a list of items and a second page that will add new items to it.
When navigating back to the list page, the new items should reflect in it.

Any data that needs to be shared between pages needs to be accessible by them in a global way. Most common would be to define a property in the Application class.

In my App class, I have an ObservableCollection with items that I want to access through multiple pages.

public partial class App : Application
{
    public ObservableCollection<ItemViewModel> Items { get; set; }
    ...
}

To make this accessible I made a ViewModelBase that just forward this property to any ViewModel it derives from.

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public ObservableCollection<ItemViewModel> Items
    {
        get
        {
            return ((App)Application.Current).Items;
        }
    }
    ...
    // INotifyPropertyChanged implementation
}

One of these pages will add new items to this collection. So when I navigate back to my List page, the new item will be reflected in it.

public class AddItemViewModel : ViewModelBase
{
    public ItemViewModel Item { get; set; }

    public AddItemViewModel()
    {
        Item = new ItemViewModel();
    }

    public void SaveItem()
    {
        base.Items.Add(Item);
    }
}

Because the base.Items is actually the ObservableCollection in the App class, it now becomes accessible for all pages that bind to this collection.

Here’s the xaml of my ListPage that binds the Items collection to a LongListSelector

<phone:LongListSelector x:Name="ItemsList"
                        ItemsSource="{Binding Items}"
                        IsGroupingEnabled="False"
                        ItemTemplate="{StaticResources MyItemTemplate}"/>
    

When adding a new item and navigating back to the ListPage, you will see that the list has been updated automatically.

Grouped list

What if you want to display a grouped list, items grouped by day, in your LongListSelector? To display the items grouped, you will need to bind your LongListSelector to a custom created collection class. Examples of that can be easily found on the web through a simple search.

So now in my ListPageViewModel, I create a new property to bind my ListViewSelector to.

public ObservableCollection<KeyedList<string, ItemViewModel>> GroupedItems
{
    get
    {
        var groupedItems =
            from item in base.Items
            orderby item.Date descending
            group item by item.DayString into itemsByDay
            select new KeyedList<string, ItemViewModel>(itemsByDay);
        return new ObservableCollection<KeyedList<string, ItemViewModel>>(groupedItems);
    }
}

However, when adding new items and navigating back this time, the list will no longer be updated.

The reason is that you are binding now to a new ObservableCollection, one that does no longer raise a PropertyChanged event because it’s underlying list has not been changed.

How to fix this? You can hook up the CollectionChanged event of the original Items Collection.
There you can then manually call a NotifyPropertyChanged for the GroupedItems property.

base.Items.CollectionChanged += Items_CollectionChanged;

private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    NotifyPropertyChanged("GroupedItems");
}

What you do here is listening to change events of the underlying collection. These events are automatically triggered when adding or removing items from the collection.
Once you receive one of these events, you will now notify the view that your property has changed as well, allowing the view to “refresh” itself with the new data.

You have to spend some time in understanding collection binding. Best thing is to put breakpoints in all events and see what happens.
Once you start understanding this, life becomes interesting Winking smile

Disclaimer: The opinions expressed herin are my own personal opinions and do not represent my employer's view in any way.
© 2012 Ronald Rosier.     Creative Commons License
Title
content stuff to be said.