Professional Programmer Notes

or just call this my soapbox

Archive for May 2008

Fix Visual Style of Tab Control in .NET

with one comment

I was having an issue with my tab contols looking very ugly:

Ugly Tab

These controls did not look anything like other fancy tab controls that I have seen recently in XP and Vista.    My tab control sucked.  Looking at it took away my desire to use my application.

I made several attempts at remedying the issue.  I tried one combination of property changes after another to no avail.  I was on the verge of creating a new owner-drawn tab control ( I had created a new project in Visual C# Express and everything) when I stumbled upon a CodeProject article.

I didn’t follow the article all the way through because it seemed to be written for an older version of the Framework and IDE.  But, it reminded me that there is an Application.EnableVisualStyles() method*.

I swiftly made sure I called that method before any controls were drawn, saved my hard work, and clicked the VS “Play” button with the excitement and anticipation of a child in line at Chuck E. Cheese.  That all died quickly when I received a screen containing the same ugly tabs staring back at me.

I checked the return value of the Application.RenderWithVisualStyles property and discovered my application was not using visual styles.  Thanks to the MSDN documentation, I quickly found the problem.  I had XP’s Appearance set to Windows Classic style.  Doh!!!

After changing XP’s Appearance back to Windows XP style, I had beautiful tabs:

Beautiful Tabs

To recap the solution:

  1. Call Application.EnableVisualStyles() before any controls get rendered.  In Program.cs just before Application.Run is a good place.
  2. Make sure you are allowing your OS to use visual styles.
  3. Don’t judge me for being absent-minded most of the time.  I’m trying to get it out of the way so that I won’t be absent-minded when I’m older.

* I probably saved over that memory with a Mitch Hedberg joke or my wedding anniversary date.

Advertisement

Written by curtismitchell

May 17, 2008 at 9:38 am

Posted in .net, CSharp, vb.net

Tagged with , , , ,

BDD in .NET the way the big kids are doing it

leave a comment »

This is an introductory article about using test/unit and test/spec for behavior driven development (BDD) in .NET.

Target audience:

This article is for you if:
1. You are a programmer/developer that uses Microsoft’s .NET Framework
2. You are interested in doing behavior driven development
3. You realize that while .NET has some nice up and coming BDD Frameworks, they still lag behind test/spec and rspec in features and usability.

Assumptions:

This article assumes that the target platform is Windows XP or greater (or lesser, depending on your experiences with Vista). These steps were not tested on Mono (by me), nor did I test on any OS not previously mentioned. I also assume that you are familiar with Ruby and gems. Also, I assume that you are comfortable with changing environment variables within Windows, which may require elevated privileges.

Required software/tools:

1. Ruby programming language
2. DiffUtils
3. RubyCLR (gem)
4. test/spec (gem)
5. zentest (gem)

Installation:

Download the One-Click Installer for Ruby from here. Double-click the executable and follow the wizard. Installation is a breeze with the One-Click Installer.

Second, download the DiffUtils from here. I suggest you download the installer instead of the zipped binaries. I tried the binaries initially, but found a missing dependency (try figuring that out). After downloading the installer, run it and remember the installation path for later use.

To complete the installation, we need to add the installation path to the PATH environment variable. We can do this by hitting the Left Windows key + Page Break. Select the “Advance” tab and click on the “Environment Variables” button. Select the variable named Path in the System Variables list. Click the “Edit” button under the list to bring up the edit dialog. Append a semi-colon and the installation path to the end of the “Variable Value” text box. BEFORE you exit out of the dialogs, click the “New…” button under the User Variables list. Create a variable named “HOME” and set its value to your user directory that has your “My Documents” folder e.g. “C:\Documents And Settings\Curtis”. Press the “Ok” buttons to exit all of the dialogs, and reboot your computer. The last step is very important, so try not to skip it.

Now that we have Ruby and DiffUtils installed, we can install the requisite ruby gems. Installation of the gems is straight-forward. At the command prompt, use a variation of the following command to install each gem:

gem install [gem name] --include-dependencies

I suggest you add the –include-dependencies flag to the gem commands in order to save a few prompts. Once the gems are installed, you’re all set. You don’t need me.

Usage:

I’ll add a few notes about how to use your new setup. This is where all your hard work pays off.

First, create a new C# Class Library solution in Visual Studio. I suggest you change the output directory to “../bin” in order to have MSBuild output your assembly to a “bin” directory in the root path of the solution.

Open your text editor and create a new file called “.autotest” in the root path of your solution. Note: This may be difficult to accomplish in Notepad since the filename is essentially an extension in Windows. I suggest using Notepad++ or Scite (installed with the one-click Ruby installer) instead.

This file is really just a Ruby source file used by the ZenTest gem. Copy the following code into the file and save it:

class Autotest
  #This method tells autotest to run all of the Ruby source files in the 'test'
  #directory whenever a file changes; namely a test file.
  def tests_for_file(filename)
    return Dir["/test/**/*.rb"]
  end
end

#This block tells autotest to run any file in the 'test' folder that starts with
#'test_' and ends with 'rb' whenever a 'dll' file changes in the 'bin' directory
Autotest.add_hook :initialize do |at|
  at.add_mapping(/^bin.*\/.*dll$/) do |filename, _|
    puts "This file changed: " + filename
    at.files_matching(/^test.*\/test_.*rb$/)
  end
end

This assumes the only .rb files in the solution’s path will be files intended to test the .NET assembly that is being created.

Next, create a new file in your text editor. Call it “test_mydotnetlib.rb” or something cheesier. But, be sure to prefix it with “test_” and save it into a folder called “test” under your solution’s path. The following steps will detail how to actually create a file to test your code.

All test files will require a few standard declarations in order to work properly:

require 'rubyclr'
require 'test/unit'
require 'test/spec'

include Test::Unit

#includes the .NET assembly intended for testing
reference_file 'C:\Dotnet\src\MySolution\bin\MyCustomLibrary.dll'

There are two points to note about the above line: First, the whole path to the output of your class library project should be specified. Secondly, this line points to a ‘bin’ directory located under the Solution’s path. This isn’t the default path of output for Visual Studio, so if you skipped the step above where I suggested you change the output path of your class library project, now is the time to correct that.

Now, we can begin writing our actual tests. Add the following to your test file and save it:

describe "MyCustomLibrary" do
  before(:each) do
    @speaker = MyCustomLibrary::Speaker.new
  end

  it "should say hello" do
    @speaker.sayHello.should.equal 'hello'
  end
end

At this point, we can start up Autotest. Open a command window and change directories to the root of your Visual Studio solution. Type “.autotest” and hit enter. Autotest will run the test that you just saved. It should show that you have 1 failed test. That’s great!

Create a Speaker class in your .NET project. Implement the sayHello method so that it returns the string “hello”. Build your project, and watch Autotest re-test your code again. This time the test should pass.

Sweet! This is just the tip of the iceberg of what can be done with RubyCLR.

This solution works because of the creativity and hard work of some great developers. I’m going to run the credits before the end, just to make sure you stick around to acknowledge their efforts:

Credits:
John Lam (RubyCLR) and the person or people continuing to develop it
Christian Neukirchen (test/spec)
Nathaniel Talbott (test/unit) and the person or people that continue to develop it
ZenSpider (ZenTest)
Paul Eggert (DiffUtils)
Venkat Subramaniam (for his inspiring presentation on DNRTV.com)
And, of course, Matz and the rest of the Ruby team

I also appreciate the efforts of all others involved whether directly or indirectly.

Now, back to the code…

Written by curtismitchell

May 5, 2008 at 7:37 pm

Posted in CSharp, Ruby, Testing

Tagged with , , , , , ,