Tag Archives: .NET

Loading forms dynamically in WPF

A friend of mine who is learning WPF recently asked me how to load forms dynamically into the panes of a tab control. Being the helpful sort I am, I wrote up a quick app that demonstrates this.

Essentially, the idea is to create the forms as UserControls, and then load these at runtime into the host control (either a TabItem or some other Content or Item control such as a Grid). Remember that for a Content Control, you would set mycontrol.Content to the new form, while an Items control can contain multiple children, so to replace the content with a form you would call mycontrol.Children.Clear(), followed by mycontrol.Children.Add(newform).

The demo app is available here.

The IEqualityComparer in action

I recently had the situation where I had a class similar to the following:

public class Item
{
    public Guid ItemID { get; set; }
    public string ItemName { get; set; }
    public IList Categories { get; set; }
}

public class Category
{
    public Guid CategoryID { get; set; }
    public string CategoryName { get; set; }
}

Data for the application was pulled out of a Linq to SQL class, working off a SQL database.  (I don’t want to get into a discussion on the semantics of my design choice – perhaps Items should be members of Categories instead of the other way around.  Just enjoy the show for now…)

What I wanted to do was to filter a Linq query from the database (containing IQueryable<Item>) for items that contained Categories with a given CategoryID.  No problems!   Just run up a Linq to SQL query to get the Category instance matching that CategoryID as follows:

var myCategory = (from c in datacontext.dbCategories
                  where c.ID == myCategoryID
                  select new Category
                  {
                      CategoryID = c.ID,
                      CategoryName = c.Name
                  }).Single();

Note that the filter as shown below won’t work on an IQueryable<Item> (due to the Contains() clause), so we’ll evaluate the incoming IQueryable<Item> as it comes in, and (for convenience) convert it back to IQueryable on the way out.  We’ll implement the method as an extension method, because we can.

public IQueryable FilterByCategory(this IQueryable qry, Category cat)
{
    return (from i in qry.ToList()        // Evaluate the qry
            where i.Categories.Contains(cat)
            select i).AsQueryable();
}

Now, this is all fine, as far as it goes.   Except for one small thing.

It didn’t work.

My result set was empty.  Always.

So what’s going on?  Basically, here’s the thing.  Have a look at the following code fragments:

int x = 7;
int y = 7;
Debug.Assert(x == y);    // Assert is true

class MyObject
{
    public int Value;

    public MyObject(int val)
    {
        Value = val;
    }
}
MyObject a = new MyObject(7);
MyObject b = new MyObject(7);
Debug.Assert(a == b);    // Assert fails!

It may seem obvious, but the reason the second Assert fails is that, despite having the same internal value, a and b are not the same! And this is the problem with my filter query above.   Despite the Category instance I received from the SQL query having the same internal values as (perhaps) a Category in the Categories property of an Item, they are not the same object and so the comparison will fail.
What we need is some way of telling .NET that two instances of an object are the same, even if they are different objects, and this is where the IEqualityComparer comes in.  We can create the following class:

class CategoryComparer : IEqualityComparer
{
    #region IEqualityComparer Members

    public bool IsEqual(Category x, Category y)
    {
        return x.CategoryID == y.CategoryID;
    }

    public int GetHashCode(Category obj)
    {
        return obj.CategoryID.GetHashCode();
    }

    #endregion
}

We have created a class that says that two instances of Category are equal when their CategoryID values match, and have based their Hash Code on the CategoryID value rather than the instance itself.  All we need to do now is to plug it in to the query, as follows:

public IQueryable FilterByCategory(this IQueryable qry, Category cat)
{
    return (from i in qry.ToList()        // Evaluate the qry
            where i.Categories.Contains(cat, new CategoryComparer())
            select i).AsQueryable();
}

Voila!  .NET is a wonderful environment, but there are always a few gotchas lying around for the unsuspecting.  Work through probelms methodically, and you’ll find there’s always a way.

.NET 2.0 in the bag…

I’ve just completed the Microsoft 70-536 exam, and… I passed!!  Passing score was 700, I was able to answer and guess my way to 858!!  (I think they’re out of approx. 1000).

I must say that I was dissappointed with the quality of the MS Press Self-Training book – there were many errors in the text and on the CD-ROM (including within the practice exams) that were not covered by the 50 or so pages of errata on the MS website, and the book did not cover all areas (in sufficient detail) to enable a passing mark.

That being said, it was enough to put me on the right track.  A few years of experience with .NET 2.0 didn’t hurt, and the rest is just down to studying the MSDN site and doing as many practice exams from as many sources as possible (they all focus on different areas).

For me, I’m taking a few weeks off from study to finish a few odd jobs around the house, then I’ll probably be on to the .NET 3.5 WPF exam (whatever number that is…)