Saturday 7 December 2013

Using TPL to avoid callback hell

In this example, we fire off three service calls which individually have a continuation of converting the resultant DTO to a model object.

We then call a fourth service, to get the Spot which only fires once all the previous three service calls have completed and created their model object.

var tasks = new Task[]
{
services.GetAsTask<DTOs.MoneyMarketRate>()
.ContinueWith(t => MoneyMarketRate = Mapper.Map<DTOs.MoneyMarketRate, MoneyMarketRate>(t.Result)),

services.GetAsTask<DTOs.InvestmentBoundaries>()
.ContinueWith(t => InvestmentBoundaries = Mapper.Map<DTOs.InvestmentBoundaries, InvestmentBoundaries>(t.Result)),

services.GetAsTask<DTOs.TradingDate>()
.ContinueWith(t => TradingDate = Mapper.Map<DTOs.TradingDate, TradingDate>(t.Result)),
};

Task.Factory.ContinueWhenAll(
tasks,
ts => services.GetAsTask<DTOs.Spot>()
.ContinueWith(t => Spot = Mapper.Map<DTOs.Spot, Spot>(t.Result)));
You can take a look at my Silverlight source project here:  https://github.com/stevenh77/UsingTasksToAvoidCallbackHell
The problem with this code is that the exceptions are not properly handled.  For that we can leverage async and await:
try 
{
var tasks = new []
{
services.GetAsync<DTOs.MoneyMarketRate, MoneyMarketRate>(x => MoneyMarketRate = x),
services.GetAsync<DTOs.InvestmentBoundaries, InvestmentBoundaries>(x => InvestmentBoundaries = x),
services.GetAsync<DTOs.TradingDate, TradingDate>(x => TradingDate = x),
};

await TaskEx.WhenAll(tasks);
await services.GetAsync<DTOs.Spot, Spot>(x => Spot = x);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}

I also refactored the service executor to use async and await and move the setting to the property to an action that can be passed in.
public class ServiceExecutor
{
const string BaseAddress = "http://localhost:8080/Services/";

public async Task GetAsync<TDto, TModel>(Action<TModel> actionToSetPropertyValue)
{
var client = new WebClient();
var serviceName = typeof(TDto).Name + ".ashx";
var response = await client.DownloadStringTaskAsync(new Uri(BaseAddress + serviceName, UriKind.Absolute));
var dto = JsonConvert.DeserializeObject<TDto>(response);
actionToSetPropertyValue.Invoke(Mapper.Map<TDto, TModel>(dto));
}
}

Refactored source:  https://github.com/stevenh77/UsingTasksToAvoidCallbackHellWithAsyncAndWait/

Saturday 23 November 2013

PropertyListener

Need to react to a property changing but the control doesn’t expose the event?  No problem, you can use the PropertyListener:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace Utilities
{
public class PropertyListener
{
/// <summary>
/// Listens for changes to dependency properties on a given FrameworkElement calls a callback on property change.
/// Usage example: PropertyListener.ListenForChange("IsBusy", BusyIndicator, (d,e) => DoStuff())
/// (may cause memory leaks)
/// </summary>
public void ListenForChange(string propertyName, FrameworkElement element, PropertyChangedCallback callback)
{
var b = new Binding(propertyName) { Source = element };
var prop = DependencyProperty.RegisterAttached(
"ListenAttached" + propertyName,
typeof(object),
typeof(Control),
new PropertyMetadata(callback));
element.SetBinding(prop, b);
}
}
}

RichText in a TextBlock

This project contains examples for Silverlight for providing formatting within a text block, either as a behaviour or attached property.  I would have liked to create custom control that derived from TextBlock but the class is sealed in Silverlight.

Source code:  https://github.com/stevenh77/RichTextBlockExample

image

<UserControl x:Class="RichTextBlockExample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:RichTextBlockExample"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<TextBlock x:Name="TextBlockUsingBehaviour">
<i:Interaction.Behaviors>
<local:RichTextBlockBehaviour/>
</i:Interaction.Behaviors>
</TextBlock>

<TextBlock x:Name="TextBlockUsingAttachedProperty" local:SupportRichText.RichText="" />
</StackPanel>
</Grid>
</UserControl>

namespace RichTextBlockExample
{
public partial class MainPage
{
public MainPage()
{
InitializeComponent();

string output = "Testing <bold>formatted</bold> text <underline>with</underline> a <italic>textblock</italic>";
TextBlockUsingBehaviour.Text = output;
TextBlockUsingAttachedProperty.SetValue(SupportRichText.RichTextProperty, output);
}
}
}

Behaviour


using System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Windows.Documents;
using System.Windows.Interactivity;

namespace RichTextBlockExample
{
public class RichTextBlockBehaviour : Behavior<TextBlock>
{
private PropertyListener propertyListener;
protected override void OnAttached()
{
base.OnAttached();
propertyListener = new PropertyListener();
propertyListener.ListenForChange("Text", this.AssociatedObject, TextBlock_TextChanged);
}

private void TextBlock_TextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var textBlock = sender as TextBlock;
if (textBlock != null)
{
textBlock.Inlines.Clear();
textBlock.Inlines.Add(Traverse(e.NewValue.ToString()));
}
}

protected override void OnDetaching()
{
base.OnDetaching();
}

private static Inline Traverse(string value)
{
// Get the sections/inlines
string[] sections = SplitIntoSections(value);

// Check for grouping
if (sections.Length.Equals(1))
{
string section = sections[0];
string token; // E.g <Bold>
int tokenStart, tokenEnd; // Where the token/section starts and ends.

// Check for token
if (GetTokenInfo(section, out token, out tokenStart, out tokenEnd))
{
// Get the content to further examination
string content = token.Length.Equals(tokenEnd - tokenStart)
? null
: section.Substring(token.Length, section.Length - 1 - token.Length * 2);

switch (token.ToLower())
{
case "<bold>":
return new Run() { Text = content, FontWeight = FontWeights.Bold };

case "<italic>":
return new Run() { Text = content, FontStyle = FontStyles.Italic };

case "<underline>":
return new Run() { Text = content, TextDecorations = TextDecorations.Underline };

case "<linebreak/>":
return new LineBreak();

default:
return new Run() { Text = content };
}
}
else return new Run() { Text = section };
}
else // Group together
{
Span span = new Span();

foreach (string section in sections) span.Inlines.Add(Traverse(section));

return span;
}
}

/// <summary>
/// Examines the passed string and find the first token, where it begins and where it ends.
/// </summary>
/// <param name="value">The string to examine.</param>
/// <param name="token">The found token.</param>
/// <param name="startIndex">Where the token begins.</param>
/// <param name="endIndex">Where the end-token ends.</param>
/// <returns>True if a token was found.</returns>
private static bool GetTokenInfo(string value, out string token, out int startIndex, out int endIndex)
{
token = null;
endIndex = -1;

startIndex = value.IndexOf("<");
int startTokenEndIndex = value.IndexOf(">");

// No token here
if (startIndex < 0) return false;

// No token here
if (startTokenEndIndex < 0) return false;

token = value.Substring(startIndex, startTokenEndIndex - startIndex + 1);

// Check for closed token. E.g. <LineBreak/>
if (token.EndsWith("/>"))
{
endIndex = startIndex + token.Length;
return true;
}

string endToken = token.Insert(1, "/");

// Detect nesting;
int nesting = 0;
int temp_startTokenIndex = -1;
int temp_endTokenIndex = -1;
int pos = 0;
do
{
temp_startTokenIndex = value.IndexOf(token, pos);
temp_endTokenIndex = value.IndexOf(endToken, pos);

if (temp_startTokenIndex >= 0 && temp_startTokenIndex < temp_endTokenIndex)
{
nesting++;
pos = temp_startTokenIndex + token.Length;
}
else if (temp_endTokenIndex >= 0 && nesting > 0)
{
nesting--;
pos = temp_endTokenIndex + endToken.Length;
}
else // Invalid tokenized string
return false;

}
while (nesting > 0);

endIndex = pos;

return true;
}

/// <summary>
/// Splits the string into sections of tokens and regular text.
/// </summary>
/// <param name="value">The string to split.</param>
/// <returns>An array with the sections.</returns>
private static string[] SplitIntoSections(string value)
{
List<string> sections = new List<string>();

while (!string.IsNullOrEmpty(value))
{
string token;
int tokenStartIndex, tokenEndIndex;

// Check if this is a token section
if (GetTokenInfo(value, out token, out tokenStartIndex, out tokenEndIndex))
{
// Add pretext if the token isn't from the start
if (tokenStartIndex > 0) sections.Add(value.Substring(0, tokenStartIndex));

sections.Add(value.Substring(tokenStartIndex, tokenEndIndex - tokenStartIndex));
value = value.Substring(tokenEndIndex); // Trim away
}
else
{
// No tokens, just add the text
sections.Add(value);
value = null;
}
}

return sections.ToArray();
}
}
}

Attached Property


using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace RichTextBlockExample
{
public class SupportRichText
{
public static string GetRichText(DependencyObject obj)
{
return (string)obj.GetValue(RichTextProperty);
}

public static void SetRichText(DependencyObject obj, string value)
{
obj.SetValue(RichTextProperty, value);
}

public static readonly DependencyProperty RichTextProperty =
DependencyProperty.RegisterAttached(
"RichText",
typeof(string),
typeof(SupportRichText),
new PropertyMetadata("", RichTextChanged));

private static Inline Traverse(string value)
{
// Get the sections/inlines
string[] sections = SplitIntoSections(value);

// Check for grouping
if (sections.Length.Equals(1))
{
string section = sections[0];
string token; // E.g <Bold>
int tokenStart, tokenEnd; // Where the token/section starts and ends.

// Check for token
if (GetTokenInfo(section, out token, out tokenStart, out tokenEnd))
{
// Get the content to further examination
string content = token.Length.Equals(tokenEnd - tokenStart)
? null
: section.Substring(token.Length, section.Length - 1 - token.Length * 2);

switch (token.ToLower())
{
case "<bold>":
return new Run() { Text = content, FontWeight = FontWeights.Bold };

case "<italic>":
return new Run() { Text = content, FontStyle = FontStyles.Italic };

case "<underline>":
return new Run() { Text = content, TextDecorations = TextDecorations.Underline };

case "<linebreak/>":
return new LineBreak();

default:
return new Run() { Text = content };
}
}
else return new Run() { Text = section };
}
else // Group together
{
Span span = new Span();

foreach (string section in sections) span.Inlines.Add(Traverse(section));

return span;
}
}

/// <summary>
/// Examines the passed string and find the first token, where it begins and where it ends.
/// </summary>
/// <param name="value">The string to examine.</param>
/// <param name="token">The found token.</param>
/// <param name="startIndex">Where the token begins.</param>
/// <param name="endIndex">Where the end-token ends.</param>
/// <returns>True if a token was found.</returns>
private static bool GetTokenInfo(string value, out string token, out int startIndex, out int endIndex)
{
token = null;
endIndex = -1;

startIndex = value.IndexOf("<");
int startTokenEndIndex = value.IndexOf(">");

// No token here
if (startIndex < 0) return false;

// No token here
if (startTokenEndIndex < 0) return false;

token = value.Substring(startIndex, startTokenEndIndex - startIndex + 1);

// Check for closed token. E.g. <LineBreak/>
if (token.EndsWith("/>"))
{
endIndex = startIndex + token.Length;
return true;
}

string endToken = token.Insert(1, "/");

// Detect nesting;
int nesting = 0;
int temp_startTokenIndex = -1;
int temp_endTokenIndex = -1;
int pos = 0;
do
{
temp_startTokenIndex = value.IndexOf(token, pos);
temp_endTokenIndex = value.IndexOf(endToken, pos);

if (temp_startTokenIndex >= 0 && temp_startTokenIndex < temp_endTokenIndex)
{
nesting++;
pos = temp_startTokenIndex + token.Length;
}
else if (temp_endTokenIndex >= 0 && nesting > 0)
{
nesting--;
pos = temp_endTokenIndex + endToken.Length;
}
else // Invalid tokenized string
return false;

}
while (nesting > 0);

endIndex = pos;

return true;
}

/// <summary>
/// Splits the string into sections of tokens and regular text.
/// </summary>
/// <param name="value">The string to split.</param>
/// <returns>An array with the sections.</returns>
private static string[] SplitIntoSections(string value)
{
var sections = new List<string>();
while (!string.IsNullOrEmpty(value))
{
string token;
int tokenStartIndex, tokenEndIndex;

// Check if this is a token section
if (GetTokenInfo(value, out token, out tokenStartIndex, out tokenEndIndex))
{
// Add pretext if the token isn't from the start
if (tokenStartIndex > 0) sections.Add(value.Substring(0, tokenStartIndex));

sections.Add(value.Substring(tokenStartIndex, tokenEndIndex - tokenStartIndex));
value = value.Substring(tokenEndIndex); // Trim away
}
else
{
// No tokens, just add the text
sections.Add(value);
value = null;
}
}

return sections.ToArray();
}

private static void RichTextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
string value = e.NewValue as string;
TextBlock textBlock = sender as TextBlock;
if (textBlock != null) textBlock.Inlines.Add(Traverse(value));
}
}
}

Property Listener


using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace RichTextBlockExample
{
public class PropertyListener
{
/// <summary>
/// Listens for changes to dependency properties on a given FrameworkElement calls a callback on property change.
/// Usage example: PropertyListener.ListenForChange("IsBusy", BusyIndicator, (d,e) => DoStuff())
/// (may cause memory leaks)
/// </summary>
public void ListenForChange(string propertyName, FrameworkElement element, PropertyChangedCallback callback)
{
var b = new Binding(propertyName) { Source = element };
var prop = DependencyProperty.RegisterAttached(
"ListenAttached" + propertyName,
typeof(object),
typeof(Control),
new PropertyMetadata(callback));
element.SetBinding(prop, b);
}
}
}

Thursday 21 November 2013

DateTimeFormatterConverter for WinRT

With there being no StringFormat on a binding in WinRT yet you can use this converter to leverage the crazy (different) DateTimeFormatter object:

    public class DateTimeFormatterConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var formatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter(parameter.ToString());
return formatter.Format((DateTime)value);
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}

Usage:


<converters1:DateTimeFormatterConverter x:Key="DateTimeFormatterConverter" />

<TextBlock Text="{Binding DealDate,
Converter={StaticResource DateTimeFormatterConverter},
ConverterParameter=day month year}"

Binding visual state manager to a view model

Using an attached property:

using System;
using System.Windows;
using System.Windows.Controls;

namespace StateHelperSL
{
public class VisualStateHelper : DependencyObject
{
public static readonly DependencyProperty VisualStatePropertyProperty = DependencyProperty.RegisterAttached(
"VisualStateProperty",
typeof(string),
typeof(VisualStateHelper),
new PropertyMetadata(VisualStatePropertyChangedCallback));

private static void VisualStatePropertyChangedCallback(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
var ctrl = s as Control;
if (ctrl == null)
throw new InvalidOperationException("This attached property only supports types derived from Control.");

VisualStateManager.GoToState(ctrl, e.NewValue.ToString(), true);
}

public static string GetVisualStateProperty(DependencyObject obj)
{
return (string)obj.GetValue(VisualStatePropertyProperty);
}

public static void SetVisualStateProperty(DependencyObject obj, string value)
{
obj.SetValue(VisualStatePropertyProperty, value);
}
}
}
You can bind your view:
<UserControl x:Class="StateHelperSL.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StateHelperSL"
local:VisualStateHelper.VisualStateProperty="{Binding State, Mode=OneWay}"
mc:Ignorable="d">

<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Gone">
<Storyboard>
<DoubleAnimation To="1000"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="AnimatableButton"
d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackPanel Margin="50">
<Button x:Name="AnimatableButton" Click="ButtonBase_OnClick" Height="30" Content="Click me">
<Button.RenderTransform>
<CompositeTransform/>
</Button.RenderTransform>
</Button>

</StackPanel>
</Grid>
</UserControl>
View code behind:
using System.Windows;

namespace StateHelperSL
{
public partial class MainPage
{
private readonly ViewModel vm;

public MainPage()
{
this.InitializeComponent();
this.vm = new ViewModel();
this.DataContext = this.vm;
}

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
vm.State = "Gone";
}
}
}

To your view model:


namespace StateHelperSL
{
public class ViewModel : PropertyChangedBase
{
private string state;

public ViewModel()
{
State = "Normal";
}

public string State
{
get { return this.state; }
set
{
if (state == value) return;
this.state = value;
NotifyOfPropertyChange("State");
}
}
}
}

Wednesday 20 November 2013

ActualSizeProxy

/// <summary>
/// Allows binding to a container (or other framework element) height or width
///
/// Example:
///     <UserControl.Resources>
///          <utils:ActualSizePropertyProxy Element="{Binding ElementName=SellPanel}"  x:Name="SellPanelSizeProxy"/>
///     </UserControl.Resources>    
///
///     <TextBlock Width="{Binding ElementName=SellPanelSizeProxy, Path=ActualWidthValue}" />
///
/// </summary>
public class ActualSizePropertyProxy : FrameworkElement, INotifyPropertyChanged
{
    public static readonly DependencyProperty ElementProperty = DependencyProperty.Register(
        "Element",
        typeof(FrameworkElement),
        typeof(ActualSizePropertyProxy),
        new PropertyMetadata(null, OnElementPropertyChanged));
    public event PropertyChangedEventHandler PropertyChanged;
    public FrameworkElement Element
    {
        get { return (FrameworkElement)this.GetValue(ElementProperty); }
        set { this.SetValue(ElementProperty, value); }
    }
    public double ActualHeightValue
    {
        get { return this.Element == null ? 0 : this.Element.ActualHeight; }
    }
    public double ActualWidthValue
    {
        get { return this.Element == null ? 0 : this.Element.ActualWidth; }
    }
    private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((ActualSizePropertyProxy)d).OnElementChanged(e);
    }
    private void OnElementChanged(DependencyPropertyChangedEventArgs e)
    {
        var oldElement = (FrameworkElement)e.OldValue;
        var newElement = (FrameworkElement)e.NewValue;
        newElement.SizeChanged += this.ElementSizeChanged;
        if (oldElement != null)
        {
            oldElement.SizeChanged -= this.ElementSizeChanged;
        }
        this.NotifyPropChange();
    }
    private void ElementSizeChanged(object sender, SizeChangedEventArgs e)
    {
        this.NotifyPropChange();
    }
    private void NotifyPropChange()
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs("ActualWidthValue"));
            this.PropertyChanged(this, new PropertyChangedEventArgs("ActualHeightValue"));
        }
    }
}

DataContextProxy

using System.Windows;
using System.Windows.Data;
 
namespace Utilities
{
    /// <summary>
    /// Allows binding to a viewmodel from within a data/contenttemplate that is bound to something else.
    ///
    /// Example:
    ///     <UserControl.Resources>
    ///         <DataContextProxy x:Key="dataContextProxy" />
    ///     </UserControl.Resources>    
    ///     ...
    ///     <DataTemplate>
    ///         <Button Content="Delete"
    ///                 Command="{Binding Source={StaticResource dataContextProxy}, Path=DataSource.DeleteClass}" 
    ///                 CommandParameter="{Binding}" />
    ///     </DataTemplate>
    ///
    /// </summary>
    public class DataContextProxy : FrameworkElement
    {
        public DataContextProxy()
        {
            this.Loaded += OnLoaded;
        }
        public string BindingPropertyName { get; set; }
        public BindingMode BindingMode { get; set; }
        public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", typeof(object), typeof(DataContextProxy), null);
        public object DataSource
        {
            get { return GetValue(DataSourceProperty); }
            set { SetValue(DataSourceProperty, value); }
        }
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            var binding = new Binding();
            if (!string.IsNullOrEmpty(BindingPropertyName))
            {
                binding.Path = new PropertyPath(BindingPropertyName);
            }
            binding.Source = DataContext;
            binding.Mode = BindingMode;
            SetBinding(DataSourceProperty, binding);
            // this.Loaded -= this.OnLoaded;
        }
    }
}

Sunday 3 November 2013

AppBar Wizard buttons

I like how Telerik use an App bar, which is always visible, to allow navigation through the application.

image

image

Saturday 2 November 2013

Fluid Dialog Wizard for Silverlight

My Fluid Dialog Wizard is a copy from Visual Studio 2012 setup dialog:

Features plenty of cool stuff: my Modern UI tab control, plenty of visual state manager examples with storyboards, animations, render transforms and transitions, behaviours, draggable dialog, styles, a clip attached property (that forces a panel to clip it’s contents),

Source:    https://github.com/stevenh77/FluidDialogWizard

Clean.bat

dir /B /S "bin" /AD >a.list & for /F "delims=" %%a in (a.list) DO (attrib -H "%%a" & rd /Q /S "%%a")

dir /B /S "obj" /AD >b.list & for /F "delims=" %%a in (b.list) DO (attrib -H "%%a" & rd /Q /S "%%a")

dir /B /S "_ReSharper*" /AD >c.list & for /F "delims=" %%a in (c.list) DO (attrib -H "%%a" & rd /Q /S "%%a")

dir /B /S "Debug" /AD >d.list & for /F "delims=" %%a in (d.list) DO (attrib -H "%%a" & rd /Q /S "%%a")

dir /B /S "x64" /AD >e.list & for /F "delims=" %%a in (e.list) DO (attrib -H "%%a" & rd /Q /S "%%a")

dir /B /S "AppPackages" /AD >f.list & for /F "delims=" %%a in (f.list) DO (attrib -H "%%a" & rd /Q /S "%%a")

dir /B /S "ipch" /AD >g.list & for /F "delims=" %%a in (g.list) DO (attrib -H "%%a" & rd /Q /S "%%a")

attrib -H /S *.suo
del /Q /S *.suo
attrib -H /S *.*sdf
del /Q /S *.*sdf

rem GOTO EOF

del a.list
del b.list
del c.list
del d.list
del e.list
del f.list
del g.list

:EOF

ModernUI Tab Control

This control gives you a ModernUI look and feel for a menu with animated slide in effect when the menu changes.

Source available here:  https://github.com/stevenh77/ModernUITabControl/

Sunday 27 October 2013

Mongoose Web Server

If you ever need a lightweight web server then Mongoose is worth a look:  http://cesanta.com/downloads.html

Just download then run the executable and the directory that it resides in becomes accessible in the browser.

It’s simple and it just works!

Polymer: The future of HTML5

It seems in many ways HTML is moving closer and closer to XAML. 

Through the use of Web Components, Google have come up with a project that allows developers to write HTML web pages that make use of data binding through Node.bind(), custom controls using HTML Imports and modularity with the Shadow DOM - very very cool stuff! 

http://www.polymer-project.org/

https://github.com/polymer/polymer

Webcast introducing Polymer (from May 2013): 

Polymer webcast from Google

Architectual diagram:

platform.js is a poyfill to bring all modern browsers up to a base line allowing devs to be able to use polymer.js.

It is believed that over time the size of platform.js will reduce as browsers catch up.  That said it’s still only 32KB when gzipped.

The team have created a set of controls/elements for app development, built on top of the framework such as:

image

Everything is an element.  The composability of business applications will lead to much faster development time, enabling programmers to focus on solving business problems and not battling away with boilerplate code.

The future looks incredibly fun for developers.

Saturday 26 October 2013

Windows To Go

image

You can now create a Windows 8.1 image stored and run on a USB device.

Here’s how to set it up.  From the Control Panel select “Windows To Go”:

image

Insert your USB key:                                  

Choose the USB you want to use for Windows To Go

Select the Windows ISO image:

The Windows To Go wizard will scan local drives

You're now ready to create your Windows To Go disk

Enter a BitLocker password:

Encrypt Windows To Go with BitLocker

Create:                                 

The USB drive is partioned just like a normal drive

In the Choose a boot option screen, select a boot (startup) option. If you tap or click Yes, the Windows Boot Manager configuration will be modified to automatically boot from your Windows To Go device when it is connected to this host computer:

Windows 8 will now load the right drivers for your device

NOTE If you want to change the boot option after running the wizard, in the Windows 8 Start screen, type Change Windows To Go Startup Options, tap or click Settings to change the search scope, and then tap or click the Change Windows To Go Startup Options app to open it.

When provisioning is complete, tap or click Save and restart to restart the host computer:

clip_image004

 

Full instructions can be found here:  http://www.microsoft.com/en-us/download/details.aspx?id=36184

Friday 25 October 2013

Path Markup Syntax

Taken from:  http://msdn.microsoft.com/en-us/library/ms752293.aspx

M= Start point

L = Creates a line to this end point

H = Creates a horizontal line between the current point and the specified x-coordinate. H 90 is an example of a valid horizontal line command.

V = Creates a vertical line between the current point and the specified y-coordinate. v 90 is an example of a valid vertical line command.

Z = Close

Tuesday 22 October 2013

Wednesday 16 October 2013

How to serialize an Expression

Download (or use NuGet):  https://github.com/esskar/Serialize.Linq

using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Serialize.Linq.Serializers;
using Serialize.Linq.Tests.Internals;
using System;
using System.Linq.Expressions;

namespace Serialize.Linq.Tests
{
public class FilmDto
{
public string Name { get; set; }
public DateTime ReleaseDate { get; set; }
}

[TestClass]
public class HowToSerializeAnExpressionTests
{
public TestContext TestContext { get; set; }

private static IQueryable<FilmDto> GetFilms()
{
return new List<FilmDto>
{
new FilmDto { Name = "Gravity", ReleaseDate = new DateTime(2013, 10, 15) },
new FilmDto { Name = "Blade Runner", ReleaseDate = new DateTime(1975, 2, 28) },
new FilmDto { Name = "Superman", ReleaseDate = new DateTime(1985, 6, 6) },
}
.AsQueryable();
}

[TestMethod]
public void BasicExpressionSerialization()
{
var predicate = (Expression<Func<FilmDto, bool>>)(film => film.Name.ToLower().Contains("n"));
var serializer = new ExpressionSerializer(new BinarySerializer());
var bytes = serializer.SerializeBinary(predicate);
var predicateDeserialized = serializer.DeserializeBinary(bytes);
this.TestContext.WriteLine("{0} serializes to bytes with length {1}", predicate, bytes.Length);

ExpressionAssert.AreEqual(predicate, predicateDeserialized);

var films = GetFilms();
var expectedCount = films.Where(predicate).Count();

// a simple example of executing an expression, leveraging IEnumerable
var actualCount = films.Where((Expression<Func<FilmDto, bool>>)predicateDeserialized).Count();
Assert.AreEqual(expectedCount, actualCount);

// constructing the same call using more Expressions
Expression whereMethodCall = Expression.Call(
typeof(Queryable),
"Where",
new[] { films.ElementType },
films.Expression,
Expression.Quote(predicateDeserialized));

// executing the expression, leveraging IQueryable
actualCount = films.Provider.CreateQuery<FilmDto>(whereMethodCall).Count();
Assert.AreEqual(expectedCount, actualCount);
}
}

// Bear in mind this issue with .NET 45: http://forums.asp.net/t/1864636.aspx
// reproducible if you use: (film => film.ReleaseDate < new DateTime(1990, 01, 01))
// (which is fixed with .NET 451!)
// For finer grain support:
// http://msdn.microsoft.com/en-us/library/vstudio/bb882637.aspx
}


image



If you want to swap out the BinarySerializer for Json, this would be the payload:

{
"__type":"L:#Serialize.Linq.Nodes",
"NT":18,
"T":{
"G":[
{
"N":"Serialize.Linq.Tests.FilmDto"
},
{
"N":"System.Boolean"
}
],
"N":"System.Func`2"
},
"B":{
"__type":"MC:#Serialize.Linq.Nodes",
"NT":6,
"T":{
"N":"System.Boolean"
},
"A":[
{
"__type":"C:#Serialize.Linq.Nodes",
"NT":9,
"T":{
"N":"System.String"
},
"V":"n"
}
],
"M":{
"D":{
"N":"System.String"
},
"M":8,
"S":"Boolean Contains(System.String)"
},
"O":{
"__type":"MC:#Serialize.Linq.Nodes",
"NT":6,
"T":{
"N":"System.String"
},
"A":[

],
"M":{
"D":{
"N":"System.String"
},
"M":8,
"S":"System.String ToLower()"
},
"O":{
"__type":"M:#Serialize.Linq.Nodes",
"NT":23,
"T":{
"N":"System.String"
},
"E":{
"__type":"P:#Serialize.Linq.Nodes",
"NT":38,
"T":{
"N":"Serialize.Linq.Tests.FilmDto"
},
"N":"film"
},
"M":{
"D":{
"N":"Serialize.Linq.Tests.FilmDto"
},
"M":16,
"S":"System.String Name"
}
}
}
},
"P":[
{
"__type":"P:#Serialize.Linq.Nodes",
"NT":38,
"T":{
"N":"Serialize.Linq.Tests.FilmDto"
},
"N":"film"
}
]
}


If you want to swap it out for the XmlSerializer, this would be the payload:

<?xml version="1.0" encoding="UTF-8"?>
<E xmlns="http://schemas.datacontract.org/2004/07/Serialize.Linq.Nodes" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:type="L">
<NT>Lambda</NT>
<T>
<G>
<T>
<N>Serialize.Linq.Tests.FilmDto</N>
</T>
<T>
<N>System.Boolean</N>
</T>
</G>
<N>System.Func`2</N>
</T>
<B i:type="MC">
<NT>Call</NT>
<T>
<N>System.Boolean</N>
</T>
<A>
<E i:type="C">
<NT>Constant</NT>
<T>
<N>System.String</N>
</T>
<V xmlns:a="http://www.w3.org/2001/XMLSchema" i:type="a:string">n</V>
</E>
</A>
<M>
<D>
<N>System.String</N>
</D>
<M>Method</M>
<S>Boolean Contains(System.String)</S>
</M>
<O i:type="MC">
<NT>Call</NT>
<T>
<N>System.String</N>
</T>
<A />
<M>
<D>
<N>System.String</N>
</D>
<M>Method</M>
<S>System.String ToLower()</S>
</M>
<O i:type="M">
<NT>MemberAccess</NT>
<T>
<N>System.String</N>
</T>
<E i:type="P">
<NT>Parameter</NT>
<T>
<N>Serialize.Linq.Tests.FilmDto</N>
</T>
<N>film</N>
</E>
<M>
<D>
<N>Serialize.Linq.Tests.FilmDto</N>
</D>
<M>Property</M>
<S>System.String Name</S>
</M>
</O>
</O>
</B>
<P>
<E i:type="P">
<NT>Parameter</NT>
<T>
<N>Serialize.Linq.Tests.FilmDto</N>
</T>
<N>film</N>
</E>
</P>
</E>

Project().To<T>: Lightweight mapper

Found this very cool code today:

http://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access-code
// This is the kind of projection code that we are replacing

//var students = from s in context.Students
// select new StudentSummary
// {
// FirstName = s.FirstName,
// LastName = s.LastName,
// TutorName = s.Tutor.Name,
// CoursesCount = s.Courses.Count
// };


// The line below performs exactly the same query as the code above.

var students = context.Students.Project().To<StudentSummary>();

Which is all down to the following code:

public static class QueryableExtensions
{
public static ProjectionExpression<TSource> Project<TSource>(this IQueryable<TSource> source)
{
return new ProjectionExpression<TSource>(source);
}
}

public class ProjectionExpression<TSource>
{
private static readonly Dictionary<string, Expression> ExpressionCache = new Dictionary<string, Expression>();

private readonly IQueryable<TSource> _source;

public ProjectionExpression(IQueryable<TSource> source)
{
_source = source;
}

public IQueryable<TDest> To<TDest>()
{
var queryExpression = GetCachedExpression<TDest>() ?? BuildExpression<TDest>();

return _source.Select(queryExpression);
}

private static Expression<Func<TSource, TDest>> GetCachedExpression<TDest>()
{
var key = GetCacheKey<TDest>();

return ExpressionCache.ContainsKey(key) ? ExpressionCache[key] as Expression<Func<TSource, TDest>> : null;
}

private static Expression<Func<TSource, TDest>> BuildExpression<TDest>()
{
var sourceProperties = typeof(TSource).GetProperties();
var destinationProperties = typeof(TDest).GetProperties().Where(dest => dest.CanWrite);
var parameterExpression = Expression.Parameter(typeof(TSource), "src");

var bindings = destinationProperties
.Select(destinationProperty => BuildBinding(parameterExpression, destinationProperty, sourceProperties))
.Where(binding => binding != null);

var expression = Expression.Lambda<Func<TSource, TDest>>(Expression.MemberInit(Expression.New(typeof(TDest)), bindings), parameterExpression);

var key = GetCacheKey<TDest>();

ExpressionCache.Add(key, expression);

return expression;
}

private static MemberAssignment BuildBinding(Expression parameterExpression, MemberInfo destinationProperty, IEnumerable<PropertyInfo> sourceProperties)
{
var sourceProperty = sourceProperties.FirstOrDefault(src => src.Name == destinationProperty.Name);

if (sourceProperty != null)
{
return Expression.Bind(destinationProperty, Expression.Property(parameterExpression, sourceProperty));
}

var propertyNames = SplitCamelCase(destinationProperty.Name);

if (propertyNames.Length == 2)
{
sourceProperty = sourceProperties.FirstOrDefault(src => src.Name == propertyNames[0]);

if (sourceProperty != null)
{
var sourceChildProperty = sourceProperty.PropertyType.GetProperties().FirstOrDefault(src => src.Name == propertyNames[1]);

if (sourceChildProperty != null)
{
return Expression.Bind(destinationProperty, Expression.Property(Expression.Property(parameterExpression, sourceProperty), sourceChildProperty));
}
}
}

return null;
}

private static string GetCacheKey<TDest>()
{
return string.Concat(typeof(TSource).FullName, typeof(TDest).FullName);
}

private static string[] SplitCamelCase(string input)
{
return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim().Split(' ');
}
}

Friday 13 September 2013

Setting format for Telerik RadDatePicker

First up remember there are two date pickers the RadDatePicker and the RadDateTimePicker.

You can specialise with your date hardcoded, or have a property that lets the developer set the value:

public class RadDatePickerWithSwissDates : RadDatePicker
{
public RadDatePickerWithSwissDates()
{
var ci = new CultureInfo("")
{
DateTimeFormat = { ShortDatePattern = "dd.MM.yyyy" }
};

this.Culture = ci;
}
}

Or you can use this approach:

public class TelerikDateFormatWorkaround
{
public CultureInfo CultureWithSwissFormat
{
//Hack to get around the fact that there is no custom date format in the Telerik DatePicker
//http://www.telerik.com/community/forums/wpf/datepicker/changing-dateformat.aspx
get
{
var tempCultureInfo = (CultureInfo)CultureInfo.CurrentCulture.Clone();
tempCultureInfo.DateTimeFormat.ShortDatePattern = "dd.MM.yyyy";
return tempCultureInfo;
}
}
}

// add it to the usercontrol resources in the usual way and then...

<Style TargetType="telerik1:RadDatePicker">
<Setter Property="Culture" Value="{Binding Source={StaticResource TelerikDateFormatWorkaround}, Path=CultureWithSwissFormat}"/>
</Style>

BooleanToVisibilityConverterMarkupExtension

public class BooleanToVisibilityConverterMarkupExtension : MarkupExtension, IValueConverter
{
private static BooleanToVisibilityConverterMarkupExtension converter;

public override object ProvideValue(IServiceProvider serviceProvider)
{
return converter ?? (converter = new BooleanToVisibilityConverterMarkupExtension());
}

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var v = (bool?)value;
return v.HasValue && v.Value ? Visibility.Visible : Visibility.Collapsed;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var v = (Visibility)value;
return v == Visibility.Visible;
}
}

<!-- usage in xaml -->
Visibility="{Binding IsVisible, Converter={converters:BooleanToVisibilityConverterMarkupExtension}}">>

Wednesday 28 August 2013

How to find absolute position of control

The following code from MSDN come in very handy today, just change “this” to your control and it’ll give your the absolute position of your control on the page:

GeneralTransform gt = this.TransformToVisual(Application.Current.RootVisual as UIElement);
Point offset = gt.Transform(new Point(0, 0));
double controlTop = offset.Y;
double controlLeft = offset.X;

Thursday 15 August 2013

How to flip a path in xaml

For those with Blend installed simply select the path and set the transform properties:

image

If you don’t have Blend then you can use on the following properties:

<Path Width="50" 
Height="50"
Data="F1M1719.66,218.12L1735.66,246.166 1751.66,274.21 1719.66,274.21 1687.66,274.21 1703.66,246.166 1719.66,218.12z"
Fill="Red"
Stretch="Uniform"
RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<CompositeTransform Rotation="-180"/>
</Path.RenderTransform>
</Path>

Wednesday 31 July 2013

List<string> to string

var strings = new List<string> { "blah", "de", "hoo", "ha" };

var result = strings.Aggregate((i, j) => i + " " + j);

Console.Write(result);
image001

And with a complex type, where a response has a collection of messages, each with a text property:

var messages = this.Response
.Messages
.Select(m => m.Text)
.Aggregate((i, j) => i + " " + j);

Friday 19 July 2013

Sequential vs Parallel Service Requests

Sequential

image
public async Task<HttpResponseMessage> DownloadWithHttpClient()
{
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "http://stevenhollidge.com/sample.json?" + DateTime.Now.Ticks);
var response = await httpClient.SendAsync(request);
return response;
}

private async void HttpClientGoButton_OnClick(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 9; i++)
{
await DownloadWithHttpClient();
}
}

Parallel


image
public async Task<HttpResponseMessage> DownloadWithHttpClient()
{
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "http://stevenhollidge.com/sample.json?" + DateTime.Now.Ticks);
var response = await httpClient.SendAsync(request);
return response;
}

private async void HttpClientGoButton_OnClick(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 9; i++)
{
DownloadWithHttpClient();
}
}

Saturday 6 July 2013

C# client for Server Side Events (EventSource)

Examples of one way streaming from server to client can be found on the web but it’s pretty much always JavaScript clients.  Here is a working example using the .NET stack, with WebAPI as the server and a C# console application as the client.

Download and run this WebAPI chat application which emits Server Side Events:

https://github.com/filipw/html5-push-asp.net-web-api/

I then open Visual Studio running as admin, update the code to use IIS with my machine name (Zeus) and a virtual directory, clicking the create virtual directory button, so I can track requests using Fiddler:

image

Then update the JavaScript within the app to use the same path:

image

The create a Console application, using NUGET add Json.NET and paste this code in:

using System;
using System.IO;
using System.Net;
using System.Text;
using Newtonsoft.Json;

namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
new WebClientWrapper();
Console.ReadKey();
}
}

public class WebClientWrapper
{
WebClient wc { get; set; }

public WebClientWrapper()
{
InitialiseWebClient();
}

// When SSE (Server side event) occurs this fires
private void OnOpenReadCompleted(object sender, OpenReadCompletedEventArgs args)
{
using (var streamReader = new StreamReader(args.Result, Encoding.UTF8))
{
var cometPayload = streamReader.ReadLine();
var jsonPayload = cometPayload.Substring(5);
var message = JsonConvert.DeserializeObject<Message>(jsonPayload);
Console.WriteLine("Message received: {0} {1} {2}", message.dt, message.username, message.text);
InitialiseWebClient();
}
}

private void InitialiseWebClient()
{
wc = new WebClient();
wc.OpenReadAsync(new Uri("http://zeus/chatapp/api/chat/"));
wc.OpenReadCompleted += OnOpenReadCompleted;
}
}

public class Message
{
public string username { get; set; }
public string text { get; set; }
public string dt { get; set; }
}
}


You’ll need to update the code for your machine name.


Now run Fiddler, the WebAPI project and the console app and add a message in the chat window:


image


In Fiddler, select the request your console just made and select Raw, you’ll see nothing.  Now right click and select COMETPeek and you’ll see the payload that was streamed.


image

Calling a WCF service over SSL with a certificate

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="binding_Default" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="endpointBehavior">
<clientCredentials>
<clientCertificate storeLocation="CurrentUser"
storeName="My"
findValue="28dfc90a0d22763ca41bb937e91925e10f9de7a4"
x509FindType="FindByThumbprint"/>
<serviceCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="https://SERVERNAME/SERVICENAME"
binding="basicHttpBinding"
bindingConfiguration="binding_Default"
contract="NAMESPACE.INTERFACE"
name="MyServiceEndpoint"
behaviorConfiguration="endpointBehavior">
</endpoint>
</client>
</system.serviceModel>
</configuration>

image

Wednesday 3 July 2013

WebApi.SelfHost

using System.Web.Http;
using System.Web.Http.SelfHost;

namespace Workflow.Console
{
class Program
{
static void Main(string[] args)
{
var config = new HttpSelfHostConfiguration("http://localhost:8080");

config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });

using (var server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
System.Console.WriteLine("Press Enter to quit.");
System.Console.ReadLine();
}
}
}
}
using System.Collections.Generic;
using System;
using System.Web.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Workflow.Console
{
public class DocumentUploadController : ApiController
{
public Guid Post([FromBody] DocumentRequest reportData)
{
var id = Guid.NewGuid();
Task.Factory.StartNew(() => CreateReport(id.ToString(), reportData.Parameter1));
return id;
}

private void CreateReport(string key, string documentData)
{
Thread.Sleep(5000);
DocumentDownloadController.Cache.Add(key, "GENERATED DOCUMENT: " + documentData);
}
}

public class DocumentDownloadController : ApiController
{
public static Dictionary<string, string> Cache = new Dictionary<string, string>();

public DocumentResponse Get(string id)
{
string document;
var response = new DocumentResponse { Id = id };
if (Cache.TryGetValue(id, out document))
{
response.IsAvailable = true;
response.Document = document;
}
else
{
response.IsAvailable = false;
}
return response;
}
}

public class DocumentRequest
{
public string Parameter1 { get; set; }
}

public class DocumentResponse
{
public string Id { get; set; }
public bool IsAvailable { get; set; }
public string Document { get; set; }
}
}
image

image


image


image


With XML:


image


or add this line to Program Main and you can remove the namespace from the xml:

config.Formatters.XmlFormatter.UseXmlSerializer = true;

image