Trials and Tribulations of DataGridView, Column Selections, and Sorting

I had to implement some custom sorting in a DataGridView recently.  Essentially, the stakeholders wanted full column selection (like Excel) while still having the ability to sort the data based on a particular column.


This particular DataGridView is data-bound.  DataGridView offers the Sort(DataGridViewColumn, ListSortDirection) method to perform this.  Nice and easy I thought: I’ll set the SelectionMode to DataGridViewSelectionMode.ColumnHeaderSelect and simply call Sort with the selected column.


Well, much to my chagrin this had the side effect of making that column look selected all the time.  No matter where else I clicked, that recently sorted column looked selected (SelectedColumns had a count of zero).  And to add insult to injury, when I control-clicked that column (thinking it was selected) to unselected it, it caused a NullReferenceException deep in the framework.


Suffice it to say, this makes it very difficult to sort by columns in DataGridView without using the built-in sort-column-when-header-is-clicked mode.


What I’m now attempting to do is to unselect the column before sorting it.  This, in itself, is not trivial either; there’s no public method to select or deselect a column in the DataGridView.  I’ve had to create a new DataGridView derivative and call the protected method SetSelectedColumnCore.  A few hoops…


I’ve logged a couple of issues on Microsoft Connect about these problems.  The first is about ctrl-clicking the column and getting an exception:  https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623 The second is about the visual state of the column remaining “selected”: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623 Attached to this post you will find the project referenced by the two Connect issues.


[Update: I've currently only tried this with a .NET 2.0 project in Visual Studio 2008 SP1; if you find this problem occurs in Visual 2008 RTM, please comment.]


[Update: I overlooked the DataGridViewColumn.Select property, so there's no need to derive from DataGridView]


DotNetKicks Image

Drag and drop of control selections onto forms designer toolbox

A while back I blogged about the ability we have in Visual Studio to select text in a text editor and drag it onto the toolbox.  Once on the toolbox you could drag those items back into the text editor to effectively “paste” frequently needed snippets of code into other text files.

Imagine my surprise when we didn’t have this ability in the forms designer.  When writing code, it’s a bit specious to want to have multiple copies of hard-coded snippets of code (DRY should come to mind).  But, for forms, the only alternative is to create user controls to contain commonly-used control groups.  User controls is very heavy weight and basically becomes unusable when talking about simple groups of buttons.  For example, “OK” and “Cancel” buttons.

So, as a result, I’ve logged a suggestion on Microsoft Connect suggesting this ability be added to Visual Studio.

If you want to see the potential of a feature like this, see http://machine.nukeation.com/preview.html

DotNetKicks Image

Location of unit tests.


I had a short  conversation at Alt.Net Canada about the location of unit tests.  I personally tend towards a distinct unit test project.  But, I deal with mostly commercial, off-the-shelf (COTS) projects where I simply can’t ship code like that.  I also don’t want to wire-off the unit test via #if because I would then be shipping something different than that which was tested.


From an enterprise application point of view, this is different.  I would have no problem including the unit tests within their respective project as production code


DotNetKicks Image

The winds of change are blowing

The essence of ALT.NET, or at least the essence that people made use of, was that it was a venue for improving one’s skills.  There has always been an undercurrent of other agendas there; but they never really took root.

The problem with the ALT.NET moniker was it isolates it from most of the industry–it was an island of .NET practitioners.  This basically flicked its thumb at the other communities–other communities that propagated some of the guidance that ALT.NET was trying to proliferate.

In the very spirit of continuous improvement it seems that ALT.NET is attempting to evolve and the ALT.NET conferences may continue (at least for a period of time, until the next kaikaku) as Kaizen conference.

Kaizen is a much more appropriate name for what people use and get out of the ALT.NET conferences.  I just hope this change doesn’t cause division, distrust and dissent (for lack of a better word).

I’ve said from the beginning that "ALT.NET" had some flaws as a name.  I hope Kaizen will continue to give the same people the ability to improve, while embracing more.

DotNetKicks Image

Extra Features: One of the Lean 7 Wastes of Software

Derik Whittaker recently blogged about how writing unused code is one of the Lean 7 Wastes of Software.  Mary Poppendieck calls this “Extra Features” and has a one-to-one association to overproduction in manufacturing. 


In Manufacturing it has different caveats: if you overproduce something you have to have somewhere to store it until its sold.  What do you do when you don’t have the space to store it?  If you have the space, it’s not too much of an issue; you just tuck it away; but you still need people to move it, manage the space, manage the responsibilities around moving/storage, etc. etc.


With Lean Software, there is still technically a storage issue (VCS, disk space, etc.).  The real issue with extra features is that no one is using them. In the best case this means you’re consuming expensive resources that aren’t directly increasing revenue.  Worst case you’re also impacting the usability (and thus the sell-ability) of the software.  If the extra features are something that the vendor hopes to be used in the future; then you’ve increased the time between implementation and fixing bugs.  Unit testing aside, when customers log bugs against the software regarding something implement 6 months ago, you’ve increased the cost of fixing the bug exponentially as time goes on.  This is the philosophy behind TDD, that unit tests find bugs as soon as possible (~build time, depending you your setup).


From an Agile standpoint, extra features mean you’re giving the user something they didn’t want.  This means you’re not listening to your customer and don’t have a relationship built on communication.  In Agile, it’s a tenet to build prototype code based ideas you’ve inferred from communication with the customer.  This isn’t extra features, this is the feedback process.  It’s fine to propose a feature to the user in the form of a prototype; but if they don’t want it, it doesn’t go into the release.


Extra features is technical debt that you’ll have to pay for eventually.


DotNetKicks Image

IS prolific use of inheritance a sign of a poorly design program?

A principle that is used to validate inheritance is Liskov Substitution principle (LSP).  Basically, it implies that a subtype must be interchangeable with its super-type without adverse side effect.

With this principle in mind it’s easy to discount many particular sub/super-type inheritances.  The quintessential Uncle Bob example of a Liskov Substitution violation are Rectangle and Square.  In geometry a Square is a type of Rectangle (and Rectangle is a type of polygon, etc…); but that maxim doesn’t hold true in most OO implementations in light of LSP.

Let’s say we implement a Rectangle class like this:

    public class Rectangle {

        private int width;

        private int height;

 

        public virtual int Width {

            get { return width; }

            set { width = value; }

        }

 

        public virtual int Height {

            get { return height; }

            set { height = value; }

        }

    }


 And we wrote unit tests like this:

    [TestFixture]

    public class RectangleTests {

        [Test]

        public void WhenWidthChanged_EnsureHeightUnchanged() {

            Rectangle rectangle = new Rectangle(10, 20);

            rectangle.Width = 30;

            Assert.AreEqual(rectangle.Height, 20);

        }

    }

Now, we know that a square is a specialized rectangle whose width and height are equal.  So, we’d be tempted to write Square like this:

    public class Square : Rectangle {

        public override int Height {

            get {

                return base.Height;

            }

            set {

                base.Height = value;

                base.Width = value;

            }

        }

        public override int Width {

            get {

                return base.Width;

            }

            set {

                base.Width = value;

                base.Height = value;

            }

        }

    }

 If we no substituted a Square object for the Rectangle object in the WhenWidthChanged_EnsureHeightUnchanged test (e.g. we registered Square for type Rectangle in our IoC) we’d get a failure.


In the same grain as Liskov, I believe that every non-static super-type should be used within the code base–meaning not only should a subtype be substitutable for a super-type but that subtype must be substituted at least somewhere in the code base.


I call this the Tangible Super-type principle.  Like a corollary to LSP, it states that every super type must be substituted by one or more subtypes.


This means I believe inheritance should be used for IS-A relationships.  It also means I don’t believe inheritance is a means of sharing code.  I would suggest using something like the Service Pattern instead of “abstract” super-types.  And yes, this means I think there are better alternatives to the Layer Super-type pattern.


DotNetKicks Image

Law of Reversibility of Attributes

I’ve come up with a simple law called Law of Reversability of Attributes.  It’s based on the physics law of a similar name.  Basically what the law means is that the inverse of a transformation should result in a return to the original state.


The Law of Reversibility of Attributes is defined as:


For a given state of an object; when a attribute’s value is changed, the inverse of that value, when applied to that attribute, will result in the object returning to its original state.


I say “attribute” rather than “property” to encompass methods that imply setting of attributes.  So, for example


            myObject.BooleanValue = !myObject.BooleanValue;
            myObject.BooleanValue = !myObject.BooleanValue;

and


            myObject.SetBooleanValue(!myObject.GetBooleanValue());
            myObject.SetBooleanValue(!myObject.BooleanValue());

means myObject will be in the same state after the second line of code than it was before the first line of code.


[UPDATE: interestingly, after I wrote this post--which was delay-published--Bill Wagner wrote a great article on a very similar topic in Visual Studio Magazine]


DotNetKicks Image

DataGridViewColumn.Frozen

DataGridViewColumn.Frozen is documented as “When a column is frozen, all the columns to its left (or to its right in right-to-left languages) are frozen as well.”

Which is nice until you think of the consequences.  The consequences being that freezing a column and all columns to the left is performed with a single assignment of true to the Frozen property of that column; but to unfreeze is not the opposite (a assignment of false to the Frozen property of that column).  No, you must unfreeze each of those columns to the left.  This can be done by manually unfreezing each column, or by unfreezing column 0.

This means that column.Frozen = false is not the opposite of column.Frozen = true—resulting in unbalanced reversible side-effects.

Neither of the techniques to “unfreeze” the column that was frozen is intuitive; but unfortunately this interface is not “intention revealing”.  You’re not just setting the Frozen property of a column, you’re setting the frozen property of that column and all the columns to the left.

Greg Young recently commented (I don’t remember where) about writing classes without any properties.  This approach would have helped here.  What Greg is alluding to is to recognize behaviour rather than shape.  Freezing the current column and all columns to the left is a behaviour, not an attribute; and it should be modeled as a method rather than a property.

At any rate, if you have a DataGridView on your form, you may be interested in using these methods instead:

        private void FreezeAtColumn(int value)
        {
            dataGridView.Columns[value].Frozen = true;
        }
 
        private void UnfreezeColumns()
        {
            dataGridView.Columns[0].Frozen = false;
        }
DotNetKicks Image

Transparency in Software Products

Lack of transparency leads to an "us and them" attitude.  It breeds contempt for your customer.  Customers are forced to provide feedback at a point when changes are very high friction and hard to manage.  It forces the development team to follow through with undesired functionality simply because "its too late in the development cycle".

No one disputes that iterative development is a bad methodology; but some organizations simply don’t follow it.  They promote iterative development and say they’re iteratively developing; but they aren’t.  They periodically provide their releases and sometimes publicly available betas; but that’s not iterative.  Iterative development is when working parts of the final products are made available to a customer independantly.  Without making working parts available for feedback by the customer independent of final delivery; it’s fundamentally waterfall.

Iterative development is fundamentally a transparent development process.  There’s different levels of transparency that an organization can implement; but without iterative development an organization or team is fundamentally opaque.

There are many leaders in the software development industry who have adopted and endorse Agile.  Agile recognizes that the software end product is a product for customers and the process hinges on customer satisfaction.  At it’s core, Agile is about transparency.  It’s about continual feedback from the customer to ensure work is cost effective.  Without involvement from the customer, work involved on that software end product is a waste.

Agile is so prevalent some software development certifications are based on it.

Signs of an opaque methodology:

  • Issues raised by customers are responded to with:
    • "That’s by design"
    • "this will be considered for the next release"
    • "that’s work”
  • Issues raised by customers to be dealt with in a future release are lost or forgotten when that future release is made public.

If you use software from a company that exhibits these traits, you should everything in your power to tell them that it is unacceptable and that you simply won’t put up with it.

DotNetKicks Image

Getting the most out of Reflector

Reflector has been out for years now.  It’s ubiquitous and a staple for many .NET developers.  But, I think it’s taken for granted because of it’s ubiquity.  I’ll outline how I use Reflector and show how I wouldn’t be able to develop .NET software as well without it.

Understanding Language Constructs

In the days of .NET 1.x, what the .NET languages produced mapped, more-or-less, one-to-one with the language constructs of Intermediate Language (IL or MSIL).  That is, it was easy to reverse from IL back to C#. 

View Code From the Point Of View of a Previous Language Version

Viewing the IL generated by a compiler is often useful in understanding what the compiler is doing, and thus the consequences.  But, you can also disassemble code into a prior version of the language.  For example, if you write the following C# code

        void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
        {
            if(this.InvokeRequired)
            {
                this.BeginInvoke((MethodInvoker)delegate() { fileSystemWatcher_Created(sender, e); });
            }
            UpdateFileList();
        }

Reflector will show the same code (the only difference will be formatting).  But, you can tell Reflector what version of the language you want code to be shown in.  This can be done in View\Options:


image


You can change the Optimization to a prior version of .NET, for example .NET 1.0.  When this code is viewed it .NET 1.0 Optimization you see this:


private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
    MethodInvoker CS$<>9__CachedAnonymousMethodDelegate2 = null;
    <>c__DisplayClass3 CS$<>8__locals4 = new <>c__DisplayClass3();
    CS$<>8__locals4.sender = sender;
    CS$<>8__locals4.e = e;
    CS$<>8__locals4.<>4__this = this;
    if (base.InvokeRequired)
    {
        if (CS$<>9__CachedAnonymousMethodDelegate2 == null)
        {
            CS$<>9__CachedAnonymousMethodDelegate2 = new MethodInvoker(CS$<>8__locals4.<fileSystemWatcher_Created>b__1);
        }
        base.BeginInvoke(CS$<>9__CachedAnonymousMethodDelegate2);
    }
    this.UpdateFileList();
}


This shows clearly what is happening in the behind-the-scenes.


Provide Detail and Clarity to Product Documentation


Let’s face it, API documentation sometimes isn’t as detailed as it needs to be, and lack of Design by Contract (DbC) doesn’t help.


Find Real-World Examples


Akin to the above point, sometimes the documented examples are academic, and sometimes (although showing syntax perfectly) violate fundamental principles of correctly-written software.  And, although it’s no guarantee of finding correctly written code, you’re likely to find real-world examples of API usage.

DotNetKicks Image