mar 27 2012

Clearing a WPF Combo box

One of the application’s I’m working on sports a number of Combo Boxes. One of the bad things about binding a Combo box in WPF is that once selected, the value can’t be cleared. After a little research I found this nice post which shows how to use an Attached Property for adding the null-ability.

So I borrowed the code but I made a couple of changes which I believe make the intention of the code clearer:

  1. Use a System.Windows.Interactivity.Behavior instead of an Attached Property
  2. When the Delete Command is invoked on the Combo box, set its Selected Item to null instead of setting the index to –1.

The behavior then looks like this:

public class AllowNulls : Behavior<ComboBox>
{
    private static readonly CommandBinding DeleteCommandBinding = new CommandBinding(ApplicationCommands.Delete, HandleExecuteDeleteCommand);

    private static void HandleExecuteDeleteCommand(object sender, ExecutedRoutedEventArgs e)
    {
        var combo = e.Source as ComboBox;
        if (combo != null)
            combo.SelectedItem = null;
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        if (!AssociatedObject.CommandBindings.Contains(DeleteCommandBinding))
            AssociatedObject.CommandBindings.Add(DeleteCommandBinding);
    }
}

And here’s how to use it xaml

 

...
xmlns:Behaviors="clr-namespace:Invoicing.Client.Wpf.Behaviors"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
...

<ComboBox Binding="{..}">
    <i:Interaction.Behaviors>
        <Behaviors:AllowNulls/>
    </i:Interaction.Behaviors>
</ComboBox>

Update

Setting the style of all the Combo Boxes in an application can be quite cumbersome when using Behaviors. In that case I’d rather use an Attached Property

dic 09 2011

Setting the Keyboard Focus in WPF

There’s nothing more annoying that trying to fill a form and having to reach the mouse and click on a text box.  I’m currently working on an invoicing application in which the user has to manually input a lot of info in a wizard-like screens workflow. Should she had to grab the mouse when a new screen loads and click on the first text box, she’d be (deservedly) cursing me more often than not.

So I decided to create an attached property which sets the keyboard focus on the specified element:

namespace Invoices.Client.Wpf.Behaviors
{
    using System.Windows;
    using System.Windows.Input;

    public static class KeyboardFocus
    {
        public static readonly DependencyProperty OnProperty;

        public static void SetOn(UIElement element, FrameworkElement value)
        {
            element.SetValue(OnProperty, value);
        }

        public static FrameworkElement GetOn(UIElement element)
        {
            return (FrameworkElement)element.GetValue(OnProperty);
        }

        static KeyboardFocus()
        {
            OnProperty = DependencyProperty.RegisterAttached("On", typeof(FrameworkElement), typeof(KeyboardFocus), new PropertyMetadata(OnSetCallback));
        }

        private static void OnSetCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var frameworkElement = (FrameworkElement)dependencyObject;
            var target = GetOn(frameworkElement);

            if (target == null)
                return;

            frameworkElement.Loaded += (s, e) => Keyboard.Focus(target);
        }
    }
}

And here’s how to use it in xaml:

<UserControl mlns:behaviors="clr-namespace:Invoices.Client.Wpf.Behaviors"            >
    <Grid behaviors:KeyboardFocus.On="{Binding ElementName=TextBoxToFocus}">
        <TextBox x:Name="TextBoxToFocus" />
    </Grid>
</UserControl>

This will definitely help your user doing her job quicker and easier. And don’t forget to set the IsDefault and IsCancel properties in your form’s default buttons. That’ll make a difference for shortcut freaks like me!

oct 26 2011

Testing .Net assemblies with IronRuby and Cucumber (Part 1: IronRuby)

Note: all the code samples for this series can be downloaded from bitbucket

Some colleagues have playing around with the ideas of behavior driven development and acceptance tests a while. Fortunately we’ve decided to give it try using Cucumber and I’ve been tasked with setting up the tests for .Net assemblies. I’ll record all the steps here in hopes that they might be helpful for others.

The first installment of the series details how to install IronRuby and run Ruby scripts in Visual Studio 2010.

IronRuby is hosted in Codeplex and in a single download you get the runtime and the Visual Studio 2010 tools.

After installing the package, there’s a new set of templates available in Visual Studio 2010.

image

Let’s just choose the Console Application template and create our AppTest project:

image

The application under test is a console application App which depends on a Logger and a ConsoleWriter

image

Here’s the app

namespace App
{
    class Program
    {
        static void Main(string[] args)
        {
            var logger = new Logger.Logger(new ConsoleWriter.Writer());
            logger.Log("Hello");
            Console.ReadLine();
        }
    }
}

The logger

namespace Logger
{
    public interface IWriter
    {
        void Write(String toWrite);
    }

    public class Logger
    {
        private readonly IWriter _writer;

        public Logger(IWriter writer)
        {
            _writer = writer;
        }

        public void Log(String message)
        {
            _writer.Write(message);
        }
    }
}

And the ConsoleWriter implementation

namespace ConsoleWriter
{
    public class Writer : IWriter
    {
        public void Write(string toWrite)
        {
            Console.WriteLine(toWrite);
        }
    }
}

Let’s edit the Program.rb script in order to exercise the code under test

require 'Logger'
require 'ConsoleWriter'
writer = ConsoleWriter::Writer.new
logger = Logger::Logger.new(writer)
logger.log "hello"
gets

The first two lines import the Logger.dll and ConsoleWriter.dll assemblies. For this to work we have to set the Search Path in the IronRuby project to point to the folder containing the assemblies:

image

Then a writer is created,

writer = ConsoleWriter::Writer.new

Notice we’re providing the namespace qualified name of the writer and calling the new method, which calls the Writer’s constructor.

Then we repeat the process for the Logger, this time passing the instance of the writer to the constructor

logger = Logger::Logger.new(writer)

Finally we call the Log method passing a “hello” string

logger.log "hello"

and call gets which has the same behaviour as Console.ReadLine

 

In this post we’ve covered how to install the IronRuby tools and how to call .Net code from an IronRuby script. In future issues, we’ll discuss how to integrate Cucumber and IronRuby.

oct 20 2011

Thousands generator

A typical need on my tests is to create collections of items. Specifying the size of the collection becomes somewhat error prone when moving onto thousands:

private readonly Int32 _tenThousand = 100000;

Did I write ten thousand or one hundred thousand? It’s actually quite easy to get it wrong, which is specially dangerous when writing Database tests

Therefore I created this class for generating numbers in multiples of one thousand

public class Thousands
    {
        private const Int32 OneThousand = 1000;
        private readonly Int32 _number;

        private Thousands(Int32 number)
        {
            _number = number;
        }

        public static Thousands Times(Int32 times)
        {
            return new Thousands(OneThousand * times);
        }

        public static implicit operator Int32(Thousands thousands)
        {
            return thousands._number;
        }
    }

Now creating the right number becomes as simple as

private readonly Int32 _tenThousand = Thousands.Times(10);
mar 03 2009

Sharing resource files between multiple assemblies in a Silverlight package

Silverlight allows you to share resource files between the assemblies included in your application package. Here I’ll show the steps for accessing an XML file from a couple of assemblies

1) On visual studio add the XML file to the main application project. In the properties change the build action to ‘content’ for that file. This will include the XML file in the application’s package instead of in the application’s assembly

2) Use the Application.GetResourceStream static method
here’s an example:

StreamResourceInfo sri = Application.GetResourceStream(new Uri("XMLFile1.xml",
UriKind.Relative));
Stream fs = sri.Stream;
XmlReader xr = XmlReader.Create(fs);
XDocument xd = XDocument.Load(xr);

If you try to use GetManifestResourceStream you’ll soon get in trouble:

1) You have to change your xml file build action to "embedded resource" which is discouraged by the MSDN(see this article)

2) In order to use this method you will need an instance of the application’s RootVisual.

For instance if your main application creates an instance of a User Control from a separated assembly and that User Control needs to access the XML file in the application’s package, it will need a reference to the application’s root object:

public MyUserControl(Object o)
{
    Assembly a = o.GetType().Assembly;
    Stream fs = a.GetManifestResourceStream("MainAssemblyName.XMLFile1.xml");
    …
}

This clearly complicates interfaces and defeats the purpose of modularization.

Summing up: use Application.GetResourceStream and forget about GetManifestResourceStream

feb 25 2009

Simplifying Silverlight DataBinding

In his article First Look at Using Expression Blend with Silverlight 2, Scott Guthrie shows a method for populating a user control with fake data for a better design time experience in blend. This method requires binding the controls to a local resource.

While this is really helpful for designing custom user controls, it may create some problems with the final application. Let’s take the digg client presented in this article as an example. For a better design time experience with Expression Blend I’ve modified the DiggStory class’ constructor to feed the control some fake data on design time:

public DiggStory()
{
    if (!HtmlPage.IsEnabled)
    {
        this.Title = "La página de Juan Agüí";
        this.Description = "Lorem ipsum ...";
        this.NumDiggs = 1000;
        this.UserName = "Juan";
        this.Thumbnail = "foto.jpg";
        this.HrefLink = new Uri("http://juanagui.com");
    }
}

For this trick to work, we have to add a local resource to our custom user control StoryDetailsView.xaml:


     

And bind the controls to the local resource, for instance


Now if you try to set the DataContext property of an instance of the StoryDetailsView.xaml user control with an instance of the DiggStory class, you will get a NotImplemented exception, because the DiggStory class does not implement the INotifyPropertyChanged interface.

If we’re going to implement that interface in our class, we’ll have to call the PropertyChange event whenever we set any property of our class, see Jesse Liberty’s tutorial on data binding. I’m showing the implementation of the UserName property here:

public string UserName
{
    get
    {
        return this.username;
    }
    set
    {
        this.username = value; 
        NotifyChanges("UserName");
    }
}  
void NotifyChanges(string propertyName)
{
    if (null != this.PropertyChanged)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

If you have many properties in your class, writing all the notification code can clearly becomes pretty tiresome and repetitive. We could do best with a base class for bindable objects.

The idea is pretty simple:

  • all your bindable classes shall inherit from the BindableBase class
  • mark all your bindable properties with the [Bindable] attribute
  • when you have to change the data source of your control, use the methods SetAllValues and SetValue provided by the BindableBase class

The code of the BindingBase class follows:

using System;
using System.ComponentModel;
using System.Reflection;
    [System.AttributeUsage(AttributeTargets.Property,AllowMultiple=true,Inherited=true)]
    public class BindableAttribute : System.Attribute {}
    
    public class BindableBase : INotifyPropertyChanged
    {
   
        public void SetAllValues(BindableBase classInstance)
        {
            Type classType = classInstance.GetType();
            PropertyInfo[] properties = classType.GetProperties();
            foreach (PropertyInfo propertyInfo in properties)
            {
                this.SetValueInternal(propertyInfo, propertyInfo.GetValue(classInstance, null));
            }
        }
        public void SetValue(String propertyName, object value)
        {
            Type classType = this.GetType();
            PropertyInfo propertyInfo = classType.GetProperty(propertyName);
            this.SetValueInternal(propertyInfo, value);
        }
        private void SetValueInternal(PropertyInfo propertyInfo, object value)
        {
            object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(BindableAttribute), true);
            if ( customAttributes.Length > 0 )
            {
                if (propertyInfo.CanWrite)
                {
                    propertyInfo.SetValue(this, value, null);
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
                }
            }
        }
        
      public event PropertyChangedEventHandler PropertyChanged;
}

And here’s an example on how to use the class: when the user clicks an item on the digg stories list, our user control pops up and is filled with new data:

void StoriesList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    DiggStory story = (DiggStory)this.StoriesList.SelectedItem;
((DiggStory)this.StoryDetail.Resources["DiggStory"]).SetAllValues(story);
    this.StoryDetail.Visibility = Visibility.Visible;
}

The SetAllValues method uses reflection for copying all the properties’ values from the new object to the user control’s data source and will trigger the PropertyChanged event for each property change.

Additionally the SetValue method will set only a property:

((DiggStory)StoryDetail.Resources["DiggStory"]).SetValue("UserName", "juan agui");
feb 05 2009

Using ApplicationSettingsBase for custom configuration

Code download

Typically, Windows Forms applications store their configuration settings in Settings files. These designer files are translated by Visual Studio into classes that inherit from ApplicationSettingsBase. Additionally, Visual Studio will persist the initial values of ApplicationSettings and UserSettings in the applications app.config file.

This approach will be valid for most cases, but may fail for some others. In those cases you will have to handle application configuration yourself by extending the ApplicationSettingsBase class. Let’s see how to do it.

We’re going to create a class tha will handle our application’s Font settings:

class ColorSettings : ApplicationSettingsBase
{
   [ApplicationScopedSetting()]
   [DefaultSettingValue("Red")]
   public Color AppColor
   {
      get { return (Color)(this["AppColor"]); }
      //Should be readonly
      set { this["AppColor"] = value; }
   }

   [UserScopedSetting()]
   [DefaultSettingValue("Pink")]
   public Color UserColor
   {
      get { return (Color)(this["UserColor"]); }
      set { this["UserColor"] = value; }
   }
}

Forget the details for now and see how to use this class:

ColorSettings colors = new ColorSettings();
Console.WriteLine("user color {0}", colors.UserColor.ToString());
Console.WriteLine("app color {0}",colors.AppColor.ToString());

You may have noticed that there’s two kinds of properties in a settings class, ApplicationScoped and UserScoped. There are several differences between them:

  • ApplicationScoped properties are readonly whereas UserScoped are readwrite. Although we’ve defined appColor as a readwrite property (implements both get and set), the set accesor won’t have any effect.
  • UserScoped properties are persisted in user.config files.
  • ApplicationScoped properties are not persisted in any file.
    There’s a generalized misconception that ApplicationScoped properties are stored in the application.exe.config file. In fact, given that they’re readonly, they’re self contained in our class’ definition. In other words: there’s no need for an app.config file when you’re extending ApplicationSettingsBase.

Regarding file locations, you may easily find where’s your application storing your settings. For instance add this code to the the class definition:

public ColorSettings()
{
   Configuration conf = ConfigurationManager.OpenExeConfiguration(
         ConfigurationUserLevel.None);
   Console.WriteLine(conf.FilePath);
   conf = ConfigurationManager.OpenExeConfiguration(
         ConfigurationUserLevel.PerUserRoaming);
   Console.WriteLine(conf.FilePath);
   conf = ConfigurationManager.OpenExeConfiguration(
         ConfigurationUserLevel.PerUserRoamingAndLocal);
   Console.WriteLine(conf.FilePath);
}

For the sake of clarity you can split your settings into Groups. Let’s say you want to store Font settings as well. You could add new properties to your existing ColorSettings class, but that can quickly turn your class in a bloated mess. A better approach is to create a new wrapper class for you Font settings:

[SettingsProvider("System.Configuration.LocalFileSettingsProvider")]
[SettingsGroupName("fonts")]
class FontSettings : ApplicationSettingsBase
{
   [UserScopedSetting()]
   [DefaultSettingValue("Arial")]
   public Font UserFont
   {
      get { return (Font)(this["UserFont"]); }
      set { this["UserFont"] = value; }
   }
}

You will notice a couple of new attributes added to the class definition.The SettingsProvider is the class responsible for accessing your settings’ storage. By default any class inheriting from ApplicationSettingsBase will use the LocalFileSettingsProvider, which writes and read your settings from the aforementioned user.config files. You can provide your own implementation of the settings provider, for instance a RegistrySetttingsProvider that will use the Windows registry. In this case I’m using the default Settings Provider, but I’ve included the attribute for completeness.

When you’re using different wrappers of the ApplicationSettingsBase, their settings will be stored in the config file in different sections. By default, the name of the class will be used for naming each section. You can change this by setting the SettingsGroupName to your name of choice. For instance this is how the ColorSettings (default) and FontSettings ([SettingsGroupName (“fonts”)]) are stored in the user.config file:

;






Wheat




Courier New, 8pt




Another interesting feature is that you can use different instances of the same wrapper class. This is helpful when you want to store different settings for different controls within your application. Let’s imagine that we have a mainWindow control and a sidebar control in our application and that we want to store independent Font settings for both. We will need to uniquely identify the settings for each control so we must change our FontSettings class constructor to look like this:

public FontSettings(string settingsKey)
: base(settingsKey)
{ }

The settingsKey parameter will identify which settings are accessed. See in this example how to create different settings for the mainWindow and the sidebar controls and how to save new values to the config file:

FontSettings fonts = new FontSettings("mainWindow");
Console.WriteLine("{0} user font {1}", fonts.SettingsKey, fonts.UserFont.Name);
fonts.UserFont = new Font(FontFamily.GenericSerif, 12);
fonts.Save();

fonts = new FontSettings("sidebar");
Console.WriteLine("{0} user font {1}", fonts.SettingsKey, fonts.UserFont.Name);
fonts.UserFont = new Font(FontFamily.GenericMonospace, 8);
fonts.Save();

This is how the config file will look after saving the settings:








Times New Roman, 12pt




Courier New, 8pt




Wheat




Hope this post will help you better understanding how to use the ApplicationSettingsBase.

ene 23 2009

RegisterWaitForSingleObject ignores ThreadPool.SetMaxThreads

The static method SetMaxThreads lets you set the maximum threads available in your application’s thread pool.

This works OK while using ThreadPool.QueueUserWorkItem for executing a method. Assuming that you set the maximum number of thread pool threads to THREADPOOL_MAX_THREADS, the threadpool will only execute concurrently as many as THREADPOOL_MAX_THREADS threads.

However this limit is not observed while using RegisterWaitForSingleObject. See the following code snippet:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ThreadPooling
{
class Program
{
static Semaphore sem;
const int SEMAPHORE_SLOTS = 5;
const int THREADPOOL_MAX_THREADS = 2;
const int WORKER_THREADS = 50;
const int TOUT = 1000;
static int threadCount = 0;

static void Main(string[] args)
{
sem = new Semaphore(0, SEMAPHORE_SLOTS);

//Configure thread pool
ThreadPool.SetMaxThreads(THREADPOOL_MAX_THREADS, 5 * THREADPOOL_MAX_THREADS);

//Create worker threads
for (int i = 0; i < WORKER_THREADS; i++)
ThreadPool.RegisterWaitForSingleObject(sem, delegate(object o, Boolean t) { DoWork(o, t); }, null, -1, false);

//wait for all the threads to be created and signal the semaphore
Thread.Sleep(5000);
sem.Release(SEMAPHORE_SLOTS);
Console.ReadLine();
}
static void DoWork(object o, Boolean timedout)
{
// Set our index
int id = Interlocked.Increment(ref threadCount);
//Do Work
Console.WriteLine(“{0} – {1}”, id, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep((int)(new Random().NextDouble() * TOUT));
//Signal semaphore so other threads may start
sem.Release();
}
}
}

it will produce an output like this:

1 – 13
2 – 13
3 – 14
4 – 14
5 – 14
6 – 13
7 – 15
8 – 13
9 – 16
10 – 15
11 – 14
12 – 13
13 – 17
….

So it looks like the ThreadPool while create as many threads as dictated by the semaphore

nov 21 2008

ASP.NET Master Pages links and HtmlControls ID

I’ve been using ASP.NET master pages lately and I’ve found there’s a problem when you include html elements with an href attribute, such as <link>, <a> or <img>. Let’s say you’re including the site navigator and some css links in the master page. If a page in a subdirectory is based in the master page, the links will be relative to thaT subdirectory and not to your site’s root. For instance, if you have all your css files in yoursite/css, the link’s href will be href=”css/stylesheet.css”. However for pages in yoursite/subdirectory the browser will fail to get the css file from yoursite/subdirectory/css/stylesheet.css

One  option is to change the html controls to server controls, adding the runat=”server” attribute and prefix  the href with the ~ symbol . That will make all your hrefs relative to your site’s root.

Unfortunately this won’t work seamlessly in an XP development box, where the site will be published in localhost/yoursitename. In that case the root is localhost and the links won’t work again.

A solution is to use the Page_Init event for rewriting your server side hrefs to an absolute path: here’s how I’ve accomplished it:

Put this class in your App_Code
public class RootRewriter
{
public static string Rewrite(HtmlControl control)
{
StringBuilder sb = new StringBuilder(ConfigurationManager.AppSettings["root"]);
sb.Append(control.Attributes["href"]);
control.Attributes["href"] = sb.ToString();
}
}

In your web.config add an setting to the appSettings:

<appSettings>
<add key=”root” value=”http://yoursite.com/”/>
</appSettings>

Finally, in each of the pages which include a server side ‘hfref’ control:

protected void Page_Init(object sender, EventArgs e)
{
RootRewriter.Rewrite(control);
}

Turning htmlcontrols to server controls has an annoying side effect. The framework will prefix your control’s ID attribute with ‘ctlxx..’. If your css selectors or javascript code use the ID attribute of the element, they’ll stop working.

In order to avoid this ID prefixing I created a couple of custom controls for <link> and <a> elements:

Put this in your App_Code folder:

namespace CustomControls
{

public class CustomAnchor : HtmlAnchor
{
public CustomAnchor()
{
}

protected override void Render(HtmlTextWriter writer)
{
HtmlAnchor anchor = new HtmlAnchor();
anchor.ID = this.ID;
anchor.HRef = RootRewriter.Rewrite(this.Attributes[“href”]);
anchor.InnerHtml = this.InnerHtml;
anchor.RenderControl(writer);
}
}

public class CustomLink : HtmlControl
{
public CustomLink() { }
protected override void Render(HtmlTextWriter writer)
{
HtmlLink link = new HtmlLink();
link.ID = this.ID;
link.Href = RootRewriter.Rewrite(this.Attributes[“href”]);
link.Attributes[“type”]=this.Attributes[“type”];
link.Attributes[“rel”] = this.Attributes[“rel”];
link.RenderControl(writer);
}
}

Notice that the Rewrite method has been changed:

public static string Rewrite(string href)
{
StringBuilder sb = new StringBuilder(ConfigurationManager.AppSettings[“root”]);
return sb.Append(href).ToString();
}

Now in your markup replace your <link> or <a> elements with the custom controls. In this example for the favicon link.

<%@ Register TagPrefix=”custom” namespace=”CustomControls” %>
<custom:CustomLink rel=”icon” id=”favicon” type=”image/png” runat=”server” href=”favicon.png”/>

Hence you can be assured that the id in the server markup will be the same id rendered by the page framework

WordPress Themes