Category Archives: Coding

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.

31 Days of Refactoring on LosTechies

August is Refactoring Month for Sean Chambers over on LosTechies.  Some of the methods he looks at are well known, some not so much, but all are worth knowing.  Check it out at http://www.lostechies.com/blogs/sean_chambers/archive/2009/07/31/31-days-of-refactoring.aspx.

Windows 7 API Code Pack v1.0 released

My new best friend, the Windows 7 Code Pack, has been released.  From Charlie Calvert’s Community Blog:

The Windows® API Code Pack for Microsoft® .NET Framework provides support for various features of Windows 7 and previous releases of that operating system. The Code Pack has  reached version 1.0 and has been published on Code Gallery:

Here are some of the features you can from managed code using the Code Pack:

  • Windows 7 Taskbar Jump Lists, Icon Overlay, Progress Bar, Tabbed Thumbnails, and Thumbnail Toolbars.
  • Windows 7 Libraries, Known Folders, non-file system containers.
  • Windows Shell Search API support, a hierarchy of Shell Namespace entities, and Drag and Drop functionality for Shell Objects.
  • Explorer Browser Control.
  • Shell property system.
  • Windows Vista and Windows 7 Common File Dialogs, including custom controls.
  • Windows Vista and Windows 7 Task Dialogs.
  • Direct3D 11.0, Direct3D 10.1/10.0, DXGI 1.0/1.1, Direct2D 1.0, DirectWrite, Windows Imaging Component (WIC) APIs. (DirectWrite and WIC have partial support)
  • Sensor Platform APIs
  • Extended Linguistic Services APIs
  • Power Management APIs
  • Application Restart and Recovery APIs
  • Network List Manager APIs
  • Command Link control and System defined Shell icons.

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.

Extending the Microsoft ASP.NET Membership Provider

Microsoft did a wonderful thing when they gave us the ASP.NET Membership Provider.  With a single command line call to aspnet_regsql.exe, we can have a fully implemented membership system providing persistence of usernames, one-way encrypted passwords, question / answer combinations, account lockout, roles, personalization, and all sorts of other useful (and not-quite-so-useful) features.

However, there is also a bit missing.  Most websites will also want to store a bit more information about their users, such as first / last names, maybe their address, birthdate, favorite color, etc, etc.  For Microsoft to have supplied fields for all of this would have made things quite unwieldy, to say the least, but fortunately there is an easy way to extend the provider.

DISCLAIMER: Before I begin, let me say that this is not the only way to extend the provider, nor is it necessarily the best.  It is quite simple, however, and therein lies it’s appeal…

Database Tables

Once you have decided which fields you wish to add to the membership provider, create a table that includes these fields along with an ID field (you can call it what you want, but ID or UserID are obvious choices) of type uniqueidentifier.

The value in the ID field will be used to link to the ASP.NET Membership Provider tables (the UserId field in aspnet_Users).  You can create a relationship between these fields if you want, but I don’t worry about it as it saves messing with the auto-generated tables.  The table structure I am using for this example is as shown below:

databasetables

MyUser class

Create a class for your membership provider, called something like MyUser.  It’s structure should be something like the following:

public class MyUser
{
    public Guid ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }

    public MembershipUser User
    {
        get { return Membership.GetUser(ID); }
    }

    public static bool IsLoggedIn
    {
        get
        {
            MembershipUser u = null;
            try
            {
                u = Membership.GetUser();
            }
            catch
            {
            }

            return (u != null);
        }
    }

    public static bool IsAdmin
    {
        // Assumes a role called "Admin"
        get { return (IsLoggedIn && Roles.IsUserInRole("Admin")); }
    }

    public bool IsUserAdmin
    {
        get { return (Roles.IsUserInRole(User.UserName, "Admin")); }
    }

    private static UsersService _service;

    private static UsersService Service
    {
        get
        {
            if (_service == null)
                _service = new UsersService();

            return _service;
        }
    }

    public static MyUser GetUser(Guid userId)
    {
        return Service.GetUser(userId);
    }

    public static MyUser GetCurrentUser()
    {
        try
        {
            return Service.GetUser((Guid)Membership.GetUser().ProviderUserKey);
        }
        catch
        {
            return null;
        }
    }

    public static MyUser AddNewUser(string username, string password, string email, string firstName, string lastName, out MembershipCreateStatus createStatus)
    {
        MembershipUser u = Membership.CreateUser(username, password, email, null, null, false, out createStatus);
        if (u != null)
        {
            MyUser user = Service.AddUser((Guid)u.ProviderUserKey, firstName, lastName);
            return user;
        }
        else
            return null;
    }

    public static MyUser ConfirmUser(Guid id)
    {
        var user = Service.GetUser(id);

        if (user != null)
        {
            if (user.User.IsApproved)
                user = null;
            else
            {
                var mu = user.User;
                mu.IsApproved = true;
                Membership.UpdateUser(mu);
            }
        }
        return user;
    }
}

Okay, there’s quite a bit there, so let’s have a look at the various parts.

Lines 3-5 provide the extended field set we want, including the Guid field (which maps to the SQL uniqueidentifier) to link to the ASP.NET Membership Provider.  Lines 7-10 just provide a quick way to get a user’s full name, while lines 12-15 provides a simple way to get to the ASP.NET Membership User.

Following this are a few static and instance methods for getting the status of a user:  Lines 17-32 is a static call to see if anyone is currently logged in;  Lines 34-38 can be used to see if the currently logged in user is a member of the Admin role (you can use several of these methods for different roles), while lines 40-43 is an instance method to see if a particular user is a member of the Admin role.

Line 45 introduces a reference to a UsersService class.  We’ll be using this service class to provide access to our database repository, and I’ll provide full details below.  This is a static field, and lines 47-56 essentially provide a single property accessor to this field (sort of a Singleton, even though it’s all static).  Following this are several methods for CRUD (Create Read Update Delete – okay, there’s no Delete here, but you get the idea..).  The only surprise here is the ConfirmUser method.  I like users to confirm their email address by clicking a link in an email sent to them, so create their user as Unapproved.  When they click on a link in an email (which contains their UserID as a parameter), the ConfirmUser method is called with that ID, which updates their status.

Now, about that UsersService…

The UsersService class

The UsersService relies on a repository class, so let’s get that first.  I’m using Linq to SQL, so create a new LINQ to SQL class, and let’s call it LinqUsers.dbml.  Drag the User table (from the top of this post) onto the designer and check your namespaces if required.  I have named my data context ‘DB’ to make things easy.  Now, here’s the UsersRepository code…

public class UsersRepository
{
    public IQueryable<MyUser> GetUsers()
    {
        DB db = new DB();
        return from u in db.Users
               orderby u.LastName
               select new MyUser
               {
                   ID = u.ID,
                   FirstName = u.FirstName,
                   LastName = u.LastName
               };
    }

    public MyUser AddUser(Guid id, string firstName, string lastName)
    {
        MyUser result = null;

        using (DB db = new DB())
        {
            User user = new User();
            user.ID = id;
            user.FirstName = firstName;
            user.LastName = lastName;

            db.Users.InsertOnSubmit(user);
            db.SubmitChanges();

            result = GetUsers().ByID(id);
        }

        return result;
    }

    public bool RemoveUser(Guid id)
    {
        bool result = false;

        using (DB db = new DB())
        {
            var del = from u in db.Users
                      where u.ID == id
                      select u;

            db.Users.DeleteAllOnSubmit(del);
            db.SubmitChanges();

            result = true;
        }

        return result;
    }
}

The only thing this needs is the ByID() filter, as follows:

public static class UserFilters
{
    public static MyUser ByID(this IEnumerable<MyUser> qry, Guid id)
    {
        return (from u in qry
                where p.ID == id
                select p).SingleOrDefault();
    }
}

Now, the UsersService class can be defined as follows:

public class UsersService
{
    UsersRepository _repository = new UsersRepository();

    public IList<MyUser> GetUsers()
    {
        return _repository.GetUsers().ToList();
    }

    public MyUser GetUser(Guid id)
    {
        return _repository.GetUsers().ByID(id);
    }

    public MyUser AddUser(Guid id, string firstName, string lastName)
    {
        return _repository.AddUser(id, firstName, lastName);
    }

    public bool RemoveUser(Guid id)
    {
        MyUser user = _repository.GetUsers().ByID(id);
        if (user == null)
            return false;

        MembershipUser mu = user.User;
        _repository.RemoveUser(id);
        return Membership.DeleteUser(mu.UserName, true);
    }
}

This should all be fairly self explanatory.  The reference to the UsersRepository could be taken through a constructor, and the UsersRepository should really implement an IUsersRepository interface, so that IOC and Dependency Injection can be used to enable unit testing, but if you need it, you’ll know how to do it (yes, I do it on my own code, so don’t beat me…).

So that’s it, really.  While there is a fair whack of code in there, it’s all fairly simple stuff.  Linq to SQL makes the database work easy, and the database and MyUser class are easily extendable to provide for the management of more fields and roles.  Feel free to leave comments if this has helped, or to offer suggestions for how this could be improved.

SimpleSlideShow update…

Ran into a problem with SimpleSlideShow recently where a flash drive contained files with a .jpg extension, but that were not JPEG files. While I don’t know exactly where they came from, the best solution was to add some code to SimpleSlideShow that would check the validity of alleged JPEG images before importing them. The result is at https://simpleslideshow.svn.codeplex.com/svn, version 1.1.

InsertScript for ASP.NET MVC

I recently had a situation where a custom control I was using in a page required jQuery.  Since I like the idea of keeping such controls self-contained, I added the usual <script type="text/javascript" src="jquery-1.2.6.min.js"></script> tag.

No problem – until I then loaded a page that included this control AND also had its own requirement for jQuery.  It seems that jQuery doesn’t like begin included twice, so I had a choice.  I could:

  • Include jQuery once in the header (or wherever) of each page (i.e. in the Master Page), hence breaking the self-containment of my control, or;
  • Write a helper method to keep track of which script files had been included in each page and hence allow a script file to only be included once per request.

It should come as no surprise (as otherwise there would be no point in this post) that I went for the second option.

The HttpContext object has an Items collection, and since the HttpContext has a lifetime of one request, we can use this Items collection to keep track of our included files.  Just add the following static method to a static class (Don’t you just love Extension Methods!):

public static string InsertScript(this HtmlHelper helper, string jsFile)
{
    const string RESID = "__resources";

    List<string> _resources = (List<string>)helper.ViewContext.HttpContext.Items[RESID];
    if (_resources == null)
    {
        _resources = new List<string>();
        helper.ViewContext.HttpContext.Items[RESID] = _resources;
    }

    string url = ScriptUrl(jsFile);
    if (!_resources.Contains(url.ToLower()))
    {
        _resources.Add(url.ToLower());
        return "<script type=\"text/javascript\" src=\"" + url + "\"></script>";
    }
    else
        return "";
}

Notice the call to ScriptUrl(jsFile) – this is just a static helper method to map javascript file names to the Scripts folder in my web app. It’s up to you whether you use such a method.

It’s now just a matter of calling this from your .aspx pages, replacing the usual
<script type="text/javascript" src="myjavascriptfile.js"></script>
with
<%= Html.InsertScript("myjavascriptfile.js") %>