Jul 2, 2009

p&p Acceptance Test Engineering Guide

Patterns & Practices J.D. Meier and his team just released a beta of a 209 pages paper about Acceptance testing ("...acceptance testing is the planned evaluation of a system by customers and customer proxies to assess to what degree it satisfies their expectations"). Very important topic.

See here.

Jul 1, 2009

Windows Mobile 6 with C# (compass control)

Actually the textual representation did not look to great. So I decided to look for a free .NET mobile compass control - which I did not find.

Let's hack some dirty user control drawing code:

/// <summary>

/// Paints the control.

/// </summary>

/// <param name="e"></param>

protected override void OnPaintBackground(PaintEventArgs e)

{

    base.OnPaintBackground(e);

 

    int penWidth = 5;

    using (Graphics g = this.CreateGraphics())

    using (Pen penBlackThin = new Pen(Color.Black, penWidth - 3))

    using (Pen penBlack = new Pen(Color.Black, penWidth))

    using (Pen penDarkGray = new Pen(Color.DarkGray, penWidth))

    using (Pen penRed = new Pen(Color.Red, penWidth + 3))

    using (Pen penWhite = new Pen(Color.WhiteSmoke, penWidth + 3))

    using (Brush brushDarkGray = new SolidBrush(Color.DarkGray))

    using (Brush brushWhite = new SolidBrush(Color.White))

    using (Brush brushLightGray = new SolidBrush(Color.LightGray))

    using (Brush brushRed = new SolidBrush(Color.Red))

    {

        double radius = (this.ClientRectangle.Width - 50) / 2;

        double radiusInner = (this.ClientRectangle.Width - 70) / 2;

        int xcenter = this.ClientRectangle.Width / 2;

        int ycenter = this.ClientRectangle.Height / 2;

        float halfFont = this.Font.Size / 2;

 

        // g.Clear(this.BackColor);

 

        // draw circles

        g.FillEllipse(brushLightGray, penWidth, penWidth, this.ClientRectangle.Width - 2 * penWidth, this.ClientRectangle.Height - 2 * penWidth);

        g.DrawEllipse(penDarkGray, penWidth, penWidth, this.ClientRectangle.Width - 2 * penWidth, this.ClientRectangle.Height - 2 * penWidth);

        g.DrawEllipse(penBlack, 2 * penWidth, 2 * penWidth, this.ClientRectangle.Width - 4 * penWidth, this.ClientRectangle.Height - 4 * penWidth);

 

        // draw separator lines

        for (int l = 0; l < 16; l++)

        {

            double angle = l * 22.5 + this.Heading;

            double xout = Math.Sin(this.ToRadian(angle)) * radiusInner;

            double yout = Math.Cos(this.ToRadian(angle)) * radiusInner;

            double xin = Math.Sin(this.ToRadian(angle)) * (radiusInner - 2 * this.Font.Size);

            double yin = Math.Cos(this.ToRadian(angle)) * (radiusInner - 2 * this.Font.Size);

            g.DrawLine(penBlackThin, (int)xout + xcenter, (int)yout + ycenter, (int)xin + xcenter, (int)yin + ycenter);

        }

 

        // draw N, W, E, S

        double x = Math.Sin(this.ToRadian(this.Heading)) * radius;

        double y = Math.Cos(this.ToRadian(this.Heading)) * radius;

        g.DrawString("N", this.Font, brushRed, (float)(xcenter - x) - halfFont, (float)(ycenter - y) - halfFont);

        g.DrawString("S", this.Font, brushRed, (float)(xcenter + x) - halfFont, (float)(ycenter + y) - halfFont);

        g.DrawString("W", this.Font, brushRed, (float)(xcenter - y) - halfFont, (float)(ycenter + x) - halfFont);

        g.DrawString("E", this.Font, brushRed, (float)(xcenter + y) - halfFont, (float)(ycenter - x) - halfFont);

 

        // draw needle

        g.DrawLine(penWhite, xcenter, ycenter, xcenter, this.ClientRectangle.Height - 50);

        g.DrawLine(penRed, xcenter, 50, xcenter, ycenter);

 

        // draw digital heading

        g.FillRectangle(brushWhite, (int)(xcenter - 11 * halfFont), (int)(ycenter - 5 * halfFont), (int)(22 * halfFont), (int)(11 * halfFont));

        g.DrawString(string.Format("{0,3:000}°", this.Heading), this.Font, brushRed, xcenter - 4 * halfFont, ycenter - 5 * halfFont);

 

        // draw height above sea level

        g.DrawString(string.Format("{0,4:0000.0}m", this.Height), this.Font, brushRed, xcenter - 10 * halfFont, ycenter);

    }

}



which looks about this on the device:


Needs some adjustments, especially to look great on other screen resolutions too. Maybe later ...

Windows Mobile 6 with C# (GPS)

It's been some time since my last fun project. So after getting my brand new HTC Touch Diamond 2 I thought about ending this period and digging somewhat into C#.NET mobile device development.

As I am new to this platform I first browsed through the Mobile SDK samples to get an idea about the slighty restricted framework capabilities. An initial MyApp application was easily created using the older Visual Studio 2005. Changing the main form to my special 800x480 screen resolution did not work properly, so the designer does not represent my device screen.

The fact that my HTC has a built-in GPS device fascinated me very much. So I had a closer look at the GPS application GPS sample and copied some classes into MyApp. Instantiating goes like this:

   55 this.gps = new Gps();

   56 gps.DeviceStateChanged += new DeviceStateChangedEventHandler(gps_DeviceStateChanged);

   57 gps.LocationChanged += new LocationChangedEventHandler(gps_LocationChanged);



getting a GpsPosition class instance with the following major fields:

//** Position + heading related

internal double dblLatitude = 0.0;            // Degrees latitude.  North is positive

internal double dblLongitude = 0.0;           // Degrees longitude.  East is positive

internal float flSpeed = 0.0f;                // Speed in knots

internal float flHeading = 0.0f;              // Degrees heading (course made good).  True North=0

internal double dblMagneticVariation = 0.0;   // Magnetic variation.  East is positive

internal float flAltitudeWRTSeaLevel = 0.0f;  // Altitute with regards to sea level, in meters

internal float flAltitudeWRTEllipsoid = 0.0f; // Altitude with regards to ellipsoid, in meters



After a couple of seconds running the application I got my first position. Output formatted as string was fine ... for the first day ;-)

Jun 12, 2009

Team Foundation Error: You are not logged in to Windows Live Messenger

You may know BizTalk or Sharepoint or PerformancePoint Server to be a cacophony of technologies.

Team Foundation Server seems to be no better, or how do you read this:



;-)

Feb 17, 2009

WPF Validation

Up until recently the mechanisms that Windows Presentation Foundation provided to implement validation were quite unsatisfying.

Starting with .NET 3.0 there was a way to do simple field validation:

<Binding Path="SemanticId" UpdateSourceTrigger="PropertyChanged">

    <Binding.ValidationRules>

        <XyValidationRule/>

    </Binding.ValidationRules>

</Binding>



For most applications this is not enough, however. Usually several fields from an entity are bound to several elements on a form and they have to be validated as a whole to be consistent.

A new approach came with .NET 3.5 where an POCO entity could implement an interface to be used by :


public class Contact : IDataErrorInfo



What I don't like is messing up my entities with validation code. I would prefer a separated (aspect-oriented? and) configurable way.

Rather unnoticed yet another approach came with 3.5 SP1, where you can group several element bindings to one or more entities and define validation rules for this named group:

<Grid.BindingGroup>

    <BindingGroup Name="TrainValidationGroup">

        <BindingGroup.ValidationRules>

            <my:TrainValidationRule ValidationStep="CommittedValue"/>

        </BindingGroup.ValidationRules>

    </BindingGroup>

</Grid.BindingGroup>



It is used in each binding

<TextBox Text="{Binding Path=SemanticId, BindingGroupName=TrainValidationGroup, ValidatesOnDataErrors=true}"/>



Not to forget to explicitely calling

RootElement.BindingGroup.CommitEdit();



Check out the excellent posts I had as source:
MSDN blog
Vincent Sibal

Feb 2, 2009

WCF behaviors on callback channel

Adding behaviors to a WCF channel is widely used and easy.

For an IEndpointBehavior the following code can be used:

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)

{

    // add endpoint behavior to service side

    endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);

}



A less documented way is to add the same behavior to the callback of a duplex channel:

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)

{

    // add endpoint behavior to callback

    clientRuntime.CallbackDispatchRuntime.MessageInspectors.Add(this);

}



You just need to know ...

Jan 30, 2009

Expression evaluation, thinking again

I recently discussed .NET runtime expression evaluation. Integrating some sample code into your productive applications may have some smells; so this may not be your prefered way to solve simple business logic expression evaluation issues.

Reading a blog from Brad Abrams about Avoiding Custom Delegates explaining

Expression<…> represents function definitions that can be compiled and subsequently invoked at runtime but can also be serialized and passed to remote processes. Continuing with our example:

            Expression<Func<int, int, double>> expression = (x, y) => (double)x / (double)y;

            Func<int, int, double> divide = expression.Compile();

            Console.WriteLine(divide(2, 3));

Microsoft .NET Services (Azure .NET Service Bus) samples and relay bindings

After some initial issues getting a Microsoft .NET Services invitation code and creating a solution on partially non-working servers I finally wanted to run some samples from the SDK.

Being behind a NAT/firewall infrastructure (no open custom ports other than 80/443) of our organisation (yes, indeed the net.tcp samples all failed starting the service) I tried to get wsHttpRelayBinding sample working.

The service is quite simple:


        static void Main(string[] args)


        {


            string serviceBusSolutionName = GetServiceBusSolutionName();


            Uri address = new Uri(String.Format("http://{0}/services/{1}/EchoService/", ServiceBusEnvironment.DefaultRelayHostName, serviceBusSolutionName));


 


            ServiceHost host = new ServiceHost(typeof(EchoService), address);


            host.Open();


 


            Console.WriteLine("Service address: " + address);


            Console.WriteLine("Press [Enter] to exit");


            Console.ReadLine();


 


            host.Close();


        }




with the following username/password configuration:


<?xml version="1.0" encoding="utf-8" ?>


<configuration>


  <system.serviceModel>


    <behaviors>


      <endpointBehaviors>


        <behavior name="UserNamePasswordCredentials">


          <transportClientEndpointBehavior credentialType="UserNamePassword">


            <clientCredentials>


              <userNamePassword userName="solution" password="password" /> 


            </clientCredentials>


          </transportClientEndpointBehavior>


        </behavior>


      </endpointBehaviors>


    </behaviors>


 


    <bindings>


      <!-- Application Binding -->


      <wsHttpRelayBinding>


        <binding name="default">


          <security mode="None"/>


        </binding>


      </wsHttpRelayBinding>


    </bindings>


 


    <services>


      <!-- Application Service -->


      <service name="Microsoft.ServiceBus.Samples.EchoService">


        <endpoint name="RelayEndpoint"


                  contract="Microsoft.ServiceBus.Samples.IEchoContract"


                  binding="wsHttpRelayBinding"


                  bindingConfiguration="default"


                  behaviorConfiguration="UserNamePasswordCredentials"


                  address="" />


      </service>


    </services>


 


  </system.serviceModel>


</configuration>




Checking the code looks like HTTP communication to me, that should pass our security perimeter infrastructure. Getting the following exception mentioning about net.tcp gives me some thinking.

System.ServiceModel.EndpointNotFoundException was unhandled
Message="Could not connect to net.tcp://servicebus.windows.net:828/services/solution/UserNameAuthenticationService/. The connection attempt lasted for a time span of 00:00:21.0021000. TCP error code 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 65.55.54.16:828. "
Source="Microsoft.ServiceBus"
StackTrace:
at Microsoft.ServiceBus.RelayedOnewayTcpClient.Connect()
at Microsoft.ServiceBus.RelayedOnewayTcpClient.EnsureChannel()
at Microsoft.ServiceBus.RelayedOnewayTcpClient.OnOpen(TimeSpan timeout)
at Microsoft.ServiceBus.Channels.CommunicationObject.Open(TimeSpan timeout)
at Microsoft.ServiceBus.Channels.CommunicationObject.Open()
at Microsoft.ServiceBus.RelayedOnewayTcpListener.OnOpen(TimeSpan timeout)
...

Using TCP port 828...

Is there some probing going on, even when specifying a HTTP binding? Trying again from home.

Jan 23, 2009

C# runtime expression evaluation

I recently found out about a XAML declarative value converter for WPF which is based on a Visual Studio Linq lambda expression sample called DynamicQuery (Dynamic.cs is bundled with VS2008 as part of \Samples\1033\CSharpSamples.zip).



For a rule evaluation (engine) investigation I created a simple application that accepts a list of expression parameters and calculates the result of a formula:



Takes a couple of [ms] the first time but performs great after the initial hit.

Jan 19, 2009

WebBrowser in WPF


Sketching a very simple RSS reader for a demo today, I just faced the question on how to display HTML in the Windows Forms WebBrowser control in a WPF application.

You just need to wrap it into a WindowsFormsHost element:




<DockPanel Grid.Column="1" Margin="10" TextBlock.FontFamily="Verdana" >


    <TextBlock FontSize="16" FontWeight="Bold" x:Name="RssTitle" DockPanel.Dock="Top"/>


    <WindowsFormsHost>


        <wf:WebBrowser x:Name="RssBrowser" />


    </WindowsFormsHost>


</DockPanel>




Setting the namespace for wf to

xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"




and then call

this.RssBrowser.DocumentText = syndicationItem.Summary.Text;



from code. Does anybode know how to set the font family, by the way?