Thursday, September 23, 2010

Visual studio designer hangs and fails to load ToolStripControlHost derived class

I found a problem using a ToolStripControlHost derived class when the class is being built in the same solution as the form that uses the component.

When performing a rebuild the designer would freeze and wouldn't redraw the toolbar. The fix I discovered solves the problem where the designer disposes the object and then attempts to access it after the rebuild.

public class CustomButtonToolStripHost : ToolStripControlHost
{
public CustomButtonToolStripHost ()
: base(CustomToolStripButton())
{
}
/// Used to overcome a designer error when rebuilding the project.
private class CustomToolStripButton : Button // Replace with your control
{
/// Override CreateHandle to avoid exception if called when object is disposed.
/// This occurs when the designer updates after a rebuild.

protected override void CreateHandle()
{
if (!IsDisposed)
{
base.CreateHandle();
}
}
}
}

.Net button that doesn't take/steal focus

This is a simple solution that I've came up with after some thinking:

public class MyButton : Button
{
public MyButton()
{
if (!DesignMode)
{
SetStyle(ControlStyles.Selectable, false);
}
}
}

Much easier than trying to handle mouse activation messages etc...

Tuesday, March 23, 2010

Isolation from database

So I'm working on a legacy project and quite intent to re-factor the heck out of it. One of my goals was to make the code testable and to do that I had to rip out the dependency on the database/DataSet implementation.

To do this I created a data provider class and then implemented an iterator block and used the yield statement.

public override IEnumerable MyDataObjects
{
get
{
using (var connection = new SqlConnection(ConnectionString))
{
connection.Open();
using (var command = new SqlCommand{CommandText = "...", Connection = connection })
{
using (var reader = command.ExecuteReader())
{
while (reader != null && reader.Read())
{
yield return new MyDataObject
{
//extract the column values
};
}
}
}
}
}
}


Now the consumer of the data doesn't know where the data is coming from and that's just fine!

foreach(var myData in provider.MyDataObjects)
{
//do stuff with the object
}

Wednesday, November 4, 2009

Get Facebook user's permission

In using the Facebook developer toolkit it was necessary to ask the user for extended permission to publish to their wall server side.

The FbPermissions class is initialized with the required permissions. Calling the GetPermissionFromUser will display the facebook permissions dialog.

If all permissions were granted the dialog will not be invoked next time. This prevents a momentary flash of the permissions dialog if you're using AJAX to make server requests.


<script type="text/javascript">
function FbPermissions(options){
 this.requiredPermissions = options["RequiredPermissions"]; 
}

FbPermissions.prototype.callback = function(e, successCallback, failureCallback){
 if(e === false){
  if(failureCallback != null)
   failureCallback();
 }
 else if(e == null || e === ""){
  if(failureCallback != null)
   failureCallback();
 }
 else{
  if(successCallback != null)
   successCallback();
  
  //Simple length check should be sufficient 
  if(this.requiredPermissions.split(',').length == e.split(',').length)
   this.requiredPermissions = "";
 }  
}

FbPermissions.prototype.GetPermissionFromUser = function(successCallback, failureCallback)
{
 var me = this;
 if(this.requiredPermissions != null && this.requiredPermissions.length != 0)
  FB.Connect.showPermissionDialog(this.requiredPermissions, function(e){me.callback(e, successCallback, failureCallback);});
 else
  successCallback();    
}


Usage


Using the class is simple. Just initialize the FbPermissions with the required permissions using a server side script block. Then invoke the GetPermissionFromUser function with a success and failure callback method.

var permissions = new FbPermissions({RequiredPermissions : '<%= Model.RequiredFacebookPermissions %>'});

function PostToWall(message) {
   permissions.GetPermissionFromUser(
   function(){/*Call your facebook application here*/},
   function(){alert('You must grant permission');})  
  }
</script>

<a href="#" onclick="PostToWall('hi'); return false;">click me</a>

Tuesday, September 15, 2009

Selenium RC timing issues

Even the best Selenium test will fall victim to timing issues which will cause tests to fail some what randomly.

This class attempts to isolate the test from timing issues by performing an automatic retry.

public static class SeleniumRetry
 {
  public static void Invoke<TArg>(Action<TArg> action, TArg arg)
  {
   Invoke(() => action.Invoke(arg));
  }
  
  public static void Invoke<TArg1, TArg2>(Action<TArg1, TArg2> action2, TArg1 arg1, TArg2 arg2)
  {
   Invoke(() => action2.Invoke(arg1, arg2));    
  }
  
  public static void Invoke(Action action)
  {
   var attempt = 0;
   const int maxAttempts = 5;
   while (true)
   {
    try
    {
     action.Invoke();
     break;
    }
    catch (Exception e)
    {
     Console.WriteLine(e.Message);

     if (++attempt > maxAttempts)
      throw;

     Thread.Sleep(500);
    }
   }
  }
 }


Using the class is simple:
This scenario shows how to automate a dynamically loaded login form that is created when the PopupLogon link is clicked.

SeleniumRetry.Invoke(Browser.Click, "PopupLogon");

SeleniumRetry.Invoke(Browser.Type, "input_email", "fake@email.com");
SeleniumRetry.Invoke(Browser.Type, "password", "12345");

//First click selects the button, second performs action.
SeleniumRetry.Invoke(Browser.Click, "submitBtn");
SeleniumRetry.Invoke(Browser.Click, "submitBtn");

Thursday, September 10, 2009

Automatically start and stop SeleniumRC with NUnit

You can use NUnit and SeleniumRC to run automated functional tests of your website. This is a simple class that starts selenium at the beginning of a unit test suite and shuts it down when done.


using System.Diagnostics;
using System.Net;
using NUnit.Framework;

[SetUpFixture]
public class SeleniumRcSetup
{
private readonly Process SeleniumRC = new Process();
[SetUp]
public void StartSelniumRc()
{
const string pathRelativeToProjBinDebug = @"path to your selenium installation";
SeleniumRC.StartInfo.FileName = "java";
SeleniumRC.StartInfo.Arguments = string.Format("-jar {0}selenium-server.jar", pathRelativeToProjBinDebug);
SeleniumRC.Start();
}
[TearDown]
public void StopSeleniumRc()
{
var r = WebRequest.Create("http://localhost:4444/selenium-server/driver/?cmd=shutDown");
r.GetResponse();
SeleniumRC.WaitForExit(5000);
SeleniumRC.Close();
}
}

Wednesday, September 9, 2009

Using XmlSerializer without rendering document declaration or namespace

Using xmlSerializer to serialize an object will by default add the xml namespace and document declaration. <strong>Example</strong>:

<?xml version="1.0" encoding="Windows-1252"?>
<node xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" uID="12345">
...
</node>

But if all you want is to write out the xml fragment like:
<node uid="12345">
...
</node>

You need to configure the serializer before you use it. The following code will not render the document declaration or namespace.

public void SerializeWithNoDeclarationNoNamespace<T>(TextWriter writer, T theObject)
{
var settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineHandling = NewLineHandling.Replace,
NewLineChars = Environment.NewLine,
OmitXmlDeclaration = true
};

using (var xmlWriter = XmlWriter.Create(writer, settings))
{
var xmlnsEmpty = new XmlSerializerNamespaces();
xmlnsEmpty.Add("", "");

new XmlSerializer(typeof(T)).Serialize(xmlWriter, theObject, xmlnsEmpty);
}

writer.WriteLine("");
}