Wednesday, December 9, 2009

Visual Studio IDE Tab Spacing

Don’t you hate it when you get some source code and the tab spacing is different than yours?  I know I do.  You could go line by line and press backspace, which is not the smartest way to do it (I was guilty of this).

Here’s the much simpler way to get the tabs aligned:

tabspacing

Wednesday, November 18, 2009

TFS folders and the evil “&”

So I tried to make a folder within TFS called “R&D and it let me.  No surprises…yet.  After moving a project into this folder, I ran the project to make sure all paths/references were still intact.  The project ran fine so things seemed okay. 

It wasn’t until I tried opening a form up in Designer view that I got a weird error:

DesignerError

How is it that the project can build and run fine, but I’m seeing this?  XML?  I don’t have anything related to XML in the form code, so what gives?  After doing some searching on the internet, it seems that the “&” character anywhere in the path causes this issue.  Since my project was in the “R&D” folder, I was having this issue.  I renamed the folder and the problem went away…

Thursday, October 29, 2009

WPF Data Binding – ComboBox Items List

As I learn WPF I’m running into quite a few roadblocks, but I’m enjoying the fact that it’s a challenge and something new.  One of the things I’m trying to get used to is Data Binding to the WPF UI.  I’m also trying to learn WPF the MVVM way.  There are a lot of examples on how to do this on the web so I’ll just get to what got me stuck for a bit on ComboBox items binding.  Here’s some of my UI XAML and my code behind:

<DockPanel Margin="0" Height="42" Name="TopDockPanel" Width="auto" DockPanel.Dock="Top" LastChildFill="true">
<Grid Height="auto" Name="Grid1" Width="266" DockPanel.Dock="Left">
<Label Margin="7,7,0,9" HorizontalAlignment="Left" Width="71">Combo1:</Label>
<ComboBox ItemsSource="{Binding ComboList1}" Margin="84,9,22,13" SelectionChanged="Combo1_SelectionChanged" />
</Grid>
<Grid Height="auto" Name="Grid2" Width="281">

<Label HorizontalAlignment="Left" Margin="6,7,0,9" Width="89">Combo2:</Label>
<ComboBox ItemsSource="{Binding ComboList2}" Margin="101,9,20,13" IsEditable="False" />
</Grid>
<Grid Height="auto" Name="Grid3" Width="auto" />
</DockPanel>

Class SomeClass
Private _SomeClassVM As SomeClassViewModel = Nothing

Sub New()

' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
_SomeClassVM = New SomeClassViewModel
Me.DataContext = _SomeClassVM
End Sub

Private Sub Combo1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
_SomeClassVM.Combo1Changed(sender)

End Sub
End Class


Nothing complicated, a simple MVVMish implementation (ish because there’s event handler code in the code behind file, I’ll be refactoring this as I go on).  My View Model implements the INotifyPropertyChanged Interface so that the UI can be notified of any property changes and update any data bindings as needed.  My View Model also exposes a couple of Public Properties: ComboList1 and ComboList2 which are List (Of String) objects:

Public Class SomeClassViewModel
Implements INotifyPropertyChanged

Private _ComboList1 As List(Of String)
Private _ComboList2 As List(Of String)

Public ReadOnly Property ComboList1() As List(Of String)
Get
Return _ComboList1
End Get
End Property

Public ReadOnly Property ComboList2() As List(Of String)
Get
Return _ComboList2
End Get
End Property

Sub New()
_ComboList1 = New List(Of String)

For Each item As String In ItemsList 'this is just a list of strings from anywhere
_ComboList1.Add(item)
Next

OnPropertyChanged("SQLServerList")

_ComboList2 = New List(Of String)

End Sub

Public Sub Combo1Changed(ByVal sender As System.Object)
_ComboList2.Clear()

For Each item As String In SomeOtherList 'this is just list of string from another place
_ComboList2.Add(sqlDatabase)
Next

OnPropertyChanged("ComboList2")
End Sub

Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

Private Sub OnPropertyChanged(ByVal propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class


Now, I thought that clearing and adding items to my ComboList2 object would suffice in propagating change notifications up to the UI…WRONG.  It seems there’s more to it than just clearing/adding to the list and raising the PropertyChanged event.  This implementation only notified the UI that ComboList2 changed once at the first time I changed ComboBox1’s selected item instead of each time.  What gives?

After some fiddling I found that I couldn’t use the current _ComboList2 object reference.  I had to actually set the _ComboList2 object to a new List for the UI to update:

Public Sub Combo1Changed(ByVal sender As System.Object)
Dim NewList As New List(Of String)

For Each item As String In SomeOtherList 'this is just list of string from another place
NewList.Add(item)
Next

_ComboList2 = NewList
OnPropertyChanged("ComboList2")
End Sub

There’s a more elegant way to solve the issue I had, which is to use an ObservableCollection instead of List (Of String) objects:

Public Class SomeClassModel

Private _ComboList1 As ObservableCollection(Of String) = Nothing
Private _ComboList2 As ObservableCollection(Of String) = Nothing

Public ReadOnly Property ComboList1() As ObservableCollection(Of String)
Get
Return _ComboList1
End Get
End Property

Public ReadOnly Property ComboList2() As ObservableCollection(Of String)
Get
Return _ComboList2
End Get
End Property

Sub New()
_ComboList1 = New ObservableCollection(Of String)

For Each item As String In ItemsList 'this is just a list of strings from anywhere
_ComboList1.Add(item)
Next

_ComboList2 = New ObservableCollection(Of String)

End Sub

Public Sub Combo1Changed(ByVal sender As System.Object)
_ComboList2.Clear

For Each item As String In SomeOtherList 'this is just list of string from another place
_ComboList2.Add(item)
Next

End Sub
End Class

You’ll notice a couple of things.  The first being that the View Model no longer needs INotifyPropertyChanged.  This is because ObservableCollection implements INotifyPropertyChanged (and INotifyCollectionChanged).  You’ll also notice that I was able to just clear/add to _ComboList2 without having to raise any events.  The UI updated as expected and I suspect it’s because when clearing or adding items to the ObservableCollection, properties such as count raise the PropertyChanged event properly.

Tuesday, October 13, 2009

Error in last post. Think of it as a what not to do :)

It turns out that pointing to a file with an Interface inside of it doesn’t work as intended (oops! :/).  Although you can implement the Interface, problems arise when you try to cast it since they’re interfaces in different namespaces…  It looks like you will have to point all libraries that need the interface to a single project that has the Interface you need.

Sharing an Interface (What not to do)

Have you ever had a class library that uses an Interface?  How about two or more libraries that need to use the same Interface?  For instance, ClassLibrary1 and ClassLibrary2 need to implement ISomeInterface below:

Interface1

Instead of copying ISomeInterface.vb to both ClassLibrary projects or adding a project reference, you can add a link to ISomeInterface.vb and have access to ISomeInterface:

Interface2

Interface3

Now you’ll notice that ISomeInterface.vb is part of ClassLibrary1 as a linked file:

Interface3

Now we can implement ISomeInterface in ClassLibrary1:

Interface4

The benefit of adding the Interface file as a link is that you can maintain the Interface in one location.  You don’t have to worry about having to copy new versions if you decide to change your contract.

Monday, August 10, 2009

The Best Things In Life Are Free

This post by Greg inspired me to post to my blog about some of the free software utilities and applications that I use at home.  Although some of the things I list may not be the absolute best, it really is hard to beat free.  Plus a lot of times the term “best” is used subjectively and this includes software.

7-Zip is a compression utility used for packing and unpacking various file formats.  Think of it as an open source WinZip.  Below is the main feature list from the 7-Zip website:

  • High compression ratio in new 7z format with LZMA compression
  • Supported formats:
    • Packing / unpacking: 7z, ZIP, GZIP, BZIP2 and TAR
    • Unpacking only: ARJ, CAB, CHM, CPIO, DEB, DMG, HFS, ISO, LZH, LZMA, MSI, NSIS, RAR, RPM, UDF, WIM, XAR and Z.
  • For ZIP and GZIP formats, 7-Zip provides a compression ratio that is 2-10 % better than the ratio provided by PKZip and WinZip
  • Strong AES-256 encryption in 7z and ZIP formats
  • Self-extracting capability for 7z format
  • Integration with Windows Shell
  • Powerful File Manager
  • Powerful command line version
  • Plugin for FAR Manager
  • Localizations for 74 languages

---------

Every Windows user needs and anti-virus application.  The one I use is Avast because it seems to be the least intrusive.  I haven’t had a single problem since I began using Avast over a year ago.  Here are some of the features:

  • Anti-spyware built-in
  • Web Shield
  • Anti-rootkit built-in
  • Automatic updates
  • Strong self-protection
  • Virus Chest
  • Antivirus kernel
  • System integration
  • Simple User Interface
  • Integrated Virus Cleaner
  • Resident protection
  • Support for 64-bit Windows
  • P2P and IM Shields
  • Internationalization
  • Network Shield

---------

Ever have issues with your OS or feel that your registry has become a bit dirty?  CCleaner may help you find the issues.  I use it regularly to clean out unnecessary temporary and log files.  I also use it to check for any registry issues:

“CCleaner is a freeware PC optimization tool.  It combines a system cleaner that removes unused and temporary files from your system and also a fully featured registry cleaner!  CCleaner allows Windows to run faster, more efficiently and gives you more hard disk space.  The best part is that it's Small, Fast and Free!”

---------

CDBurnerXP is one of the best disc burning applications I’ve ever used, free or otherwise.  It handles everything I throw at it without any issues:

  • burn all kinds of discs
  • audio-CDs with or without gaps between tracks
  • burn and create ISO files
  • data verification after burning process
  • create bootable discs
  • multi-language interface
  • bin/nrg → ISO converter, simple cover printing and much more!
  • Operating Systems: Windows 2000/XP/2003 Server/Vista/Windows 7

---------

Hate scratched audio CDs?  I know I do.  I use CDex to rip from the original disc so that I don’t have to worry about scratching up the original:

  • Direct recording of multiple tracks
  • Read / store album information from/to the cdplayer.ini file
  • Read / store album information from/to a local and/or remote CD Database (CDDB)
  • Support CD-Text (if your CD-drive supports it)
  • Advanced jitter correction (based on the cd-paranoia ripping library)
  • Indicates track progress and jitter control
  • Normalization of audio signal
  • Supports many CD-Drive from many manufacters
  • Conversion of external WAV files
  • Support for M3U and PLS play list files
  • Best of all, it's free (GPL license, source code available)
  • Serveral languages are supported

---------

Into news feeds?  Then you should be using FeedDemon.  It will sync to your Google Reader account:

  • Newspaper Format: When you select a channel, FeedDemon's tabbed browser displays the channel's news items in a newspaper for easy reading. You can display a newspaper of news items for an entire folder or view one feed at a time.
  • News Bins: Store news items in a central location and provide a handy way to collect items from different channels. If you find an interesting item that you might want to read again, just store it in a news bin for future reference.
  • Shared Experience: See what news is popular with other NewsGator users and find out who is linking to the news you’re reading.
  • Video: Watch embedded video right within the newspaper view.
  • Panic Button: Ever gone on vacation and gotten a little behind on your reading? The Panic Button solves this and many other problems by quickly marking all older items read.
  • Watches: Look for keywords in news items as they're downloaded. After you create a watch, it examines every incoming news item whenever any channel is updated.
  • News Comes To You: Subscribe to feeds from all over the web or choose some of the dozens of default feeds.
  • Search: Search outside of FeedDemon's subscriptions by selecting a feed search engine, then enter your keyword, and FeedDemon will subscribe to a dynamic channel containing the search results for that keyword.
  • Podcasts: Powerful podcasting tools enable you to download audio files and automatically copy them to your iPod or other media player. The bundled FeedStation utility enables you to schedule your downloads so they happen overnight while you're asleep. When you wake up, you'll find new audio waiting on your media player of choice.

---------

Is Photoshop a bit too expensive for you?  Try Paint.NET.  I use it for editing images, creating icons, and a myriad of other minor image tasks.  A true power user can do much more than I can with it:

  • Simple, intuitive, and innovative user interface
    Every feature and user interface element was designed to be immediately intuitive and quickly learnable without assistance. In order to handle multiple images easily, Paint.NET uses a tabbed document interface. The tabs display a live thumbnail of the image instead of a text description. This makes navigation very simple and fast.
  • Layers
    Usually only found on expensive or complicated professional software, layers form the basis for a rich image composition experience. You may think of them as a stack of transparency slides that, when viewed together at the same time, form one image.
  • Active Online Community
    Paint.NET has an online forum with a friendly, passionate, and ever-expanding community. Be sure to check out the constantly growing list of tutorials and plugins!
    Frequently Updated
    Updates usually come about every 4 to 8 weeks, and contain new features, performance improvements, and bug fixes. Upgrading to the latest version is very simple, requiring only two clicks of the mouse.
  • Special Effects
    Many special effects are included for enhancing and perfecting your images. Everything from blurring, sharpening, red-eye removal, distortion, noise, and embossing are included. Also included is our unique 3D Rotate/Zoom effect that makes it very easy to add perspective and tilting.
  • Adjustments are also included which help you tweak an image's brightness, contrast, hue, saturation, curves, and levels. You can also convert an image to black and white, or sepia-toned.
  • Powerful Tools
    Paint.NET includes simple tools for drawing shapes, including an easy-to-use curve tool for drawing splines or Bezier curves. The Gradient tool, new for 3.0, has been cited as an innovative improvement over similar tools provided by other software. The facilities for creating and working with selections is powerful, yet still simple enough to be picked up quickly. Other powerful tools include the Magic Wand for selecting regions of similar color, and the Clone Stamp for copying or erasing portions of an image. There is also a simple text editor, a tool for zooming, and a Recolor tool.
  • Unlimited History
    Everybody makes mistakes, and everybody changes their mind. To accommodate this, every action you perform on an image is recorded in the History window and may be undone. Once you've undone an action, you can also redo it. The length of the history is only limited by available disk space.
  • Free!
    Paint.NET doesn't cost a dime.

---------

Do you chat with friends that use different IM networks?  Trillian is a great application that supports various IM networks.  MSN, AIM, Yahoo, ICQ, and IRC are supported.

---------

How am I writing this blog post?  Windows Live Writer of course. Greg turned me on to this application and it makes blog posting must simpler:

“Writer makes it easy to share your photos and videos on almost any blog service—Windows Live, Wordpress, Blogger, LiveJournal, TypePad, and many more.”

Friday, May 8, 2009

WPF Canvas Coordinate System

I noticed that the Canvas class doesn’t use the Cartesian coordinate system for mapping points. For instance, here’s a list of points: 0, 0; 15, 5; 25, 18.  Here’s how these points look when drawn to a Canvas:

wpfCanvasPoints

The above image is fine if that’s what you want to do with the points, but that isn’t the result I wanted.  I had to add a ScaleTransform to the Canvas for it to look the way I wanted.  This can be done in XAML:

<Canvas Name="MainCanvas" Background="AliceBlue" Width="400" Height="200" >
    <Canvas.RenderTransform>
        <ScaleTransform CenterX="200" CenterY="100" ScaleX="1" ScaleY="-1" />
    </Canvas.RenderTransform>
</Canvas>

or programmatically (VB.NET here):

Dim YScale As New ScaleTransform

YScale.ScaleX = 1
YScale.ScaleY = -1
YScale.CenterX = MainCanvas.Width / 2
YScale.CenterY = MainCanvas.Height / 2

MainCanvas.RenderTransform = YScale

You’ll notice the CenterX and CenterY properties are set to the middle of the Canvas.  You can think of this as your pivot point when flipping the Canvas (The CenterX isn’t really needed here since we’re just flipping on the Y axis).The end result is what I was expecting:

wpfCanvasPointsYTransform

Monday, April 27, 2009

Visual Studio Unit Testing – System.TypeLoadException

So I was trying to write unit tests today and I ran into quite a weird issue.  My test failed on a simple constructor test.  When I looked at the error message I noticed something odd: 

VersionErrorMessage

The referenced assembly version in the picture is x.x.x.91, but the current version it should be is a later version.  What gives?  I tried creating a new unit test project because I thought maybe our unit test project got messed up somehow, but the same error message kept on happening.  Another frustrating issue was that when I ran the unit test in debug mode, it passed correctly. 

After some searching on the web I ran into this page, which led me to check the project’s code coverage instrumentation section.  Sure enough, the project was pointing to an assembly that no longer existed.  The red one was the non-existent assembly, the green one is the correct one.

WrongArtifact

My guess as to why this happened was because initially, the solution was setup to build against Any CPU and this was changed to x86 somewhere along the way.  The LocalTestRun.testrunconfig probably never got updated.  After pointing to the correct assembly, the test passes and no odd version issues exist. 

Incidentally, I asked Greg if his laptop ran into some slowness lately because my hard drive would thrash and adding unit tests literally took me longer than 5 minutes via right-click.  Correcting the instrumented assembly corrected this issue as well.  One would think that Visual Studio would let the user know that something was up :)

Tuesday, April 21, 2009

MS Tech Ed 2009

I’ll be attending Tech Ed this year, which is the first conference of this kind for me. So here’s my badge:

TENA_blgr1_imattending

You can get your badges for Tech Ed hereGreg will also be there, so stop by his booth to say hi and take a picture with him or something.

Tuesday, March 24, 2009

Excel and CSV files

Have you ever tried to open a comma delimited .csv file in MS Excel and gotten these dialogs?

ExcelCSV

ExcelCSV2

There might actually be nothing wrong with your file.  If the first item happens to be ID (case sensitive), you will get this dialog in Excel (I’ve had this happen to me in 2003 and 2007).  If you don’t want this dialog to keep coming up, you’ll have to rename the first item or just change the casing of ID to id, Id, or iD.