Thoughts from Dan Miser RSS 2.0
 Wednesday, January 31, 2007
I had a requirement to make a list of objects be displayed in some kind of a grid metaphor. I've used the DataGridView before, and even written some blog entries on extending it (check out the cool Search feature on my blog for more information). However, all of my grid usage had been limited to database-related use.

What I needed was a way to easily get filtering and sorting working for the list of objects. I found 2 links that helped me out a ton. The first one is Building a Drop-Down Filter List for a DataGridView Column Header Cell. This article is incredibly well-written and talks about the different interfaces you need to implement, and provides a sample, too. For the sorting, I used Brian Noyes' BindingListView class from Chapter 9 of his excellent book, Data Binding with Windows Forms 2.0.

When stitching these 2 pieces together, I noticed several things:

  • The DataGridViewAutoFilterColumnHeaderCell.UpdateFilter method was adding square brackets around the property names for some reason. I can't tell why this was being done, but my guess is it had to do with spaces in database column names. Since I'm not using it for that purpose, I removed the brackets. The other approach would have been to adjust the BindingList.UpdateFilter method to deal with the brackets, so I may revisit this in the future.
  • The BindingListView.UpdateFilter needed some minor modifications. I added a precondition guard check to make sure m_FilterString is not null. It looks like the DataGridViewAutoFilterColumnHeaderCell class will call back to the BindingListView class more frequently than Brian had anticipated.
  • I adjusted the setter of the IBindingListView.Filter property to remove the filter if it gets set to String.Empty or null.

    string IBindingListView.Filter

    {

        get

        {

            return m_FilterString;

        }

        set

        {

            if (string.IsNullOrEmpty(value))

                ((IBindingListView)this).RemoveFilter();

            else

            {

                m_FilterString = value;

                m_Filtered = true;

                UpdateFilter();

            }

        }

    }

  • You need to build up your collection of objects using BindingListView
  • You must use a BindingSource to link between your collection and the DataGridView by setting dataGridView1.DataSource = myBindingSource.

By doing all of this, I got things working the way I wanted. Now it's time to tackle the next task of getting child objects bound properly in a DataGridView.

Wednesday, January 31, 2007 2:48:22 PM (Central Standard Time, UTC-06:00)  #    Comments [1] -
.NET
 Wednesday, January 24, 2007
I came across EViL last week when looking into simplifying validation of domain objects. This open-source project is done very well. Dave Donaldson introduced EViL last month.

In a nutshell, it's a library that provides attribute-based enforcement of business rules on your entity objects. It comes with a bunch of pre-defined attributes to handle common scenarios (e.g. a field is required, a field should have a maximum length, a field should match a certain regex, etc.). It also easily allows for adding new, custom rules.

The thing I like best about this project is that it doesn't force you into descending your classes from some super class. You can do that if you want, but it will also work if you want to leave your classes alone. All in all, I would highly recommend looking into using EViL in your .NET applications.

Wednesday, January 24, 2007 2:57:44 PM (Central Standard Time, UTC-06:00)  #    Comments [1] -
.NET
 Monday, January 22, 2007
Well, I suppose this is proof of the power of this meme since it even reached me (from Hallvard). Some of these may be better known than others, but at least they're off the beaten, technical path.

  1. I started my college career as a performance music major playing the trumpet. While I love music to this day, I realized early on that I didn't want to be a teacher, and I always had a knack for computers, so I switched away from music.
  2. I played football for the UW-Madison Badgers in 1988. Well, "played" may be an exaggeration. I walked on under the Don Morton era and made the team as a free safety. By the spring game, I received a subluxation of the shoulder after a nasty collision. While rehabbing, I reinjured the shoulder and finally hung it up.
  3. I started computer programming in ninth grade on a TRS-80, Model I. I tested out of math, so that's what they had me do instead. They eventually allowed me access to the faculty Apple ][, and I ended up teaching a bunch of faculty members how to program it. I even got my picture in the local paper for that.
  4. My obsession for all things Apple lasted through college. I was a student Macintosh expert at the MACC (now known as DoIT). That's how I also got into Pascal, using TurboPascal for Mac, Lightspeed Pascal, and Macintosh Programmer's Workshop. I took my first professional job out of college working in DOS, and sadly, have never returned back to the Mac.
  5. I have always wanted to work for the NSA. However, I can't ever imagine living on the east coast (how's that to slight an entire third of the nation! :-)). Maybe after the kids go to college, I'll see what kind of opportunities exist.

To pass it on, I'll tag Steve Trefethen, Rich Werning, Mark Edington, Geoff Lane, and fellow Badger alum Chris Peterson.

Monday, January 22, 2007 9:24:49 AM (Central Standard Time, UTC-06:00)  #    Comments [1] -

 Friday, January 19, 2007
MSSQLCE has a built-in limitation that it will not work when used inside an ASP.NET application. According to the MSDN documentation for SqlCeConnection, this is due to the fact that the code wasn't written with this scenario in mind. I have seen tools be used outside of the intended use many times over my career, so I understand where the team was coming from. I am even more impressed that they put a simple check in place to allow you to effectively say "I know what I'm doing better than you do, so let me do it anyways".

In order to enable this behavior, simply add one line of code to your application:


AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true);

Steve Lasker has a good write up of this, too. The bottom line is this isn't recommended, so be sure to fully understand the implications before blindly enabling this parameter.

Friday, January 19, 2007 2:52:02 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -
.NET
 Wednesday, January 17, 2007
Another year has come and gone, and with it a few more pounds than I care to admit. Rather than just make yet another hollow New Year's Resolution to "get in shape", I decided to actually take action. I wanted to motivate myself to follow through, so I signed up with Team In Training to ride 100 miles around Lake Tahoe on 6/3/07. Yes, that will be quite a sight to behold, watching me propel all that fat around mountain passes and hairpin switchbacks!

Team In Training (TNT) is a program sponsored by the Leukemia and Lymphoma Society. They have made a lot of strides over the year in researching leukemia and blood cancer diseases. For example, they have increased survival rates of some types of leukemia in children from 4% in 1960 to 80% today.

I need your help to get this done. By donating your money, you get a tax deductible donation, and also help a great cause. I've committed to raise a minimum of $4,200 for the Leukemia Society to help this year's beneficiary, 6 year old Gabrielle Van Dyke. I'm also riding in memory of Lewis Challoner, the father of my friend, Steve Challoner. Lewis took us on the Rock 100 (and then the Rock 64) when we were in high school, and continued to take long-distance bike rides into his late 60s.

The easiest way to donate is to donate online by going to my fund-raising web page at http://www.active.com/donate/tntwi/tntwiDMiser. If you want/need to send a check, or have any other questions, please feel free to email me.

Thanks for your time, and I look forward to your donation to help this important cause. If you know of anyone else that might like to help, please pass this on. Every little bit helps!

Wednesday, January 17, 2007 4:33:25 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -

 Tuesday, January 16, 2007
I just went through the very lengthy process of moving from MSSQLCE beta to MSSQLCE release. The good news is that after I was done, all of my code still worked, so at least I have that going for me. :-)

The biggest time sink for me was uninstalling applications. Uninstalling the patch from VS2005 Pro was not all that straight-forward. First, I had to re-download and burn the ISO image since I couldn't find my original DVD. I then noticed that I had another entry in my Add/Remove Programs called "Microsoft Visual Studio 2005 Permier Partner Edition - ENU" that had the VS.NET SP1 Beta applied to it. I had no idea how this program got installed, and that took quite a bit of spelunking to figure out. I came across a blog entry from Heath Stewart that explained how to look into the patch database to figure out which MS patches were applied to which products. After installing that, it needed a Windows Installer Patch (msp) file, but I couldn't find that. I ended up searching my system, and got the VS.NET msp file and opened it in Heath's utility. From there, I got the GUID of the Premier Partner Edition, and searched my registry. In the end, it turned out to be MSSQL 2005 Developer Edition that installed that program. I finally located that DVD, pointed the uninstaller to the right msi file, and I was able to uninstall the patch. However, after completing all of this, I couldn't install the MSSQL Server 2005 Compact Edition Tools for VS 2005 SP1. I received the same error as I did last time (see the above link for details), but I couldn't solve it by doing a Repair on VS.NET, and I couldn't dig anything up in Filemon or Regmon to find out why it was failing so I ended up completely uninstalling and reinstalling VS.NET. Not exactly very user-friendly.

Installing the release of MSSQLCE is very similar to the post I made earlier on how to install MSSQLCE. The difference is the links to the new files, which can be found here:

Tuesday, January 16, 2007 10:45:46 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
.NET | Compact Framework
 Thursday, January 11, 2007
In Delphi, if you want an array of integers, indexed by an enumeration, you simply do this:

type
  TSuit = (Clubs, Spades, Hearts, Diamonds);
var
  CardCount: array[TSuit] of integer;
...
  CardCount[Clubs] := 13;

In .NET, however, you can not specify an enumerated type as the indexer into an array, so a line by line conversion to C# will not work. Instead, you need to create an entirely new helper class to make the calling code more readable (i.e. without putting casting code in all of the uses of the indexer). Furthermore, you can't use the code below in a Compact Framework (CF) application, because Enum.GetValues() and Enum.GetNames() aren't implemented in the CF libraries.



class Program

{

    static void Main(string[] args)

    {

        CardCounter cc = new CardCounter();

        cc[Suit.Clubs] = 13;

    }

}

 

public enum Suit {Clubs, Spades, Hearts, Diamonds};

 

public class CardCounter

{

    private static int enumCount = Enum.GetValues(typeof(Suit)).Length;

    private int[] counts = new int[enumCount];

 

    public int this[Suit suit]

    {

        get { return counts[(int)suit]; }

        set { counts[(int)suit] = value; }

    }

}

Thursday, January 11, 2007 8:47:32 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
.NET
 Wednesday, January 10, 2007
XML serialization is handy, but it does lack some power. For example, if you have class inheritance, and you want a property of the child class to have a different name than the one given to it by the parent, you will get an error at run-time when trying to serialize the object: "Member 'Derived.Name' hides inherited member 'Base.Name', but has different custom attributes.".

Assume you have a class structure like this:

public abstract class Base

{

    private int id;

    private string name;

 

    [XmlElement("id")]

    public int Id

    {

        get { return id; }

        set { id = value; }

    }

 

    [XmlElement("name")]

    public virtual string Name

    {

        get { return name; }

        set { name = value; }

    }

}

 

public class Derived : Base

{

    [XmlElement("newName")]

    public override string Name

    {

        get { return base.Name; }

        set { base.Name = value; }

    }

}

To see the error, call it like this:

static void Main(string[] args)

{

    Derived d = new Derived();

    d.Id = 23;

    d.Name = "Dan";

    string xml = GetXMLFromObject(d);

    Console.WriteLine(xml);

}

Download the sample application here to play with it.

Wednesday, January 10, 2007 11:57:12 AM (Central Standard Time, UTC-06:00)  #    Comments [1] -
.NET | XML
Navigation
Archive
<January 2007>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Dan Miser
Sign In
Statistics
Total Posts: 339
This Year: 5
This Month: 0
This Week: 0
Comments: 618
All Content © 2010, Dan Miser
DasBlog theme 'Business' created by Christoph De Baene (delarou)