Patrick Smacchia [MVP C#]

Sponsors

The Lounge

Wicked Cool Jobs

News

  • NDepend v3 is fully integrated in Visual Studio, and is now available for download! Software dependencies visualization, 82 .NET software metrics, continuous rule validations, assembly version diff, declarative code queries and more ! http://ndepend.com

Advertisement

Agile Behavior: Nurture Knowledge Database

Normal 0 false false false EN-US X-NONE X-NONE

Code Query Language (CQL) can be used to write all sorts of code convention. I’ve described some CQL range of usage, and as an illustration I also exposed some CQL rules dedicated to the .NET Framework usage.

 

We discovered a weird issue in our last NDepend version: to select programmatically a particular row in a Windows Form DataGridView you need to call the setter DataGridView.FirstDisplayedCell. However if the DataGridView height is too small and doesn’t let show any row, then an exception will be raised:

 

Exception.Type {System.InvalidOperationException}

Exception.Message {No room is available to display rows.}

Exception.StackTrace {

   at System.Windows.Forms.DataGridView.set_FirstDisplayedScrollingRowIndex(Int32 value)

   at System.Windows.Forms.DataGridView.set_FirstDisplayedCell(DataGridViewCell value)

 

IMHO this behavior is so counter-intuitive and prone to error that I would qualify it as a .NET Framework bug. But Microsoft is not willing to fix such behavior in the name of ascendant compatibility. The solution is then to capitalize on your own knowledge database. Typically we included the following CQL rule in our set of rules. It warns as soon as there is a method that doesn’t check the rows available height before setting FirstDisplayedCell.


// <Name>Check height space before setting FirstDisplayedCell of  a DataGridView</Name>

SELECT METHODS WHERE

  IsDirectlyUsing "System.Windows.Forms.DataGridView.set_FirstDisplayedCell(DataGridViewCell)" AND

  !(IsDirectlyUsing "System.Windows.Forms.Control.get_Height()" AND

    IsDirectlyUsing "System.Windows.Forms.DataGridView.get_ColumnHeadersHeight()")

 

/* The pattern implementation is:

   if ((rowToSelect.State & DataGridViewElementStates.Displayed) == 0) {

      if (this.Height - this.ColumnHeadersHeight > 0) {

         this.FirstDisplayedCell = rowToSelect.Cells[0];

      }

   }

*/

 

We immediately spotted 3 others risky areas in our code.

 


Posted Sun, Jun 21 2009 11:26 AM by Patrick Smacchia

[Advertisement]

Comments

DotNetShoutout wrote Agile Behavior: Nurture Knowledge Database - Patrick Smacchia - CodeBetter.Com
on Mon, Jun 22 2009 11:13 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

Doug B wrote re: Agile Behavior: Nurture Knowledge Database
on Wed, Aug 5 2009 6:26 PM

Thanks for this great solution! I'm glad to have this check rather than catching and ignoring the exception (slow). However, I believe you want to check for Visible, not Displayed, and the correct comparison would be:

  if ((rowToSelect.State & DataGridViewElementStates.Visible) == DataGridViewElementStates.Visible)

Patrick Smacchia [MVP C#] wrote On being Culture Aware
on Mon, Nov 9 2009 9:29 AM

Normal 0 21 false false false FR X-NONE X-NONE A typical development pitfall comes from forgetting about

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us