Click here to Skip to main content
15,886,864 members
Articles / Programming Languages / C#
Article

Model driven Gridview

Rate me:
Please Sign up or sign in to vote.
3.10/5 (12 votes)
16 Nov 20042 min read 83.7K   313   31   6
A Model driven GridView.

Image 1

Introduction

In .NET framework, there is no model driven grid (table) component. And I missed it a lot. Therefore, I made this simple component. It is a GridView descendant with an additional property: Model, which is responsible for delivering of: Columns, Rows and Cell values. It is very nice to separate the View of Data from the Data itself. In this article, you will find the first step to how to implement it.

Background

This article assumes that you are familiar with WinForms programming in the .NET Framework using C#, and that you have the beta of version 2.0 installed.

Using the code

Using the MVCGridView component is very simple. Put it on your Form. Implement a MVCGridViewModel. Assign the MVCGridView.Model property to your MVCGridViewModel descendant. That's all. You can hence add and edit your business entities.

Here is the MVCGridViewModel:

C#
public abstract class MVCGridViewModel
{
    public abstract void AddNewElement(Object Element);

    public abstract System.Int32 ElementCount { get; }

    public virtual Boolean IsValid(String formattedValue, String colName)
    {
        return true;
    }

    public abstract Object GetElement(System.Int32 index);

    public abstract Object GetElementValue(Object element, String ColName);

    public abstract Object NewElement();

    public abstract void SetElement(System.Int32 index, Object Element);

    public abstract void SetElementValue(Object element, 
                         String ColName, Object Value);

    public abstract void RemoveAt(System.Int32 index);

    public abstract IEnumerable<DataGridViewColumn> VisibleColumns { get; }
}

The descendant is the only thing you have to implement. Very easy. You can almost copy and paste this code.

C#
public class Person
{
    private String _FirstName = "";
    public String FirstName
    {
        get { return _FirstName; }
        set { _FirstName = value; }
    }

    private String _LastName = "";
    public String LastName
    {
        get { return _LastName; }
        set { _LastName = value; }
    }

    private System.Double _Salary;
    public System.Double Salary
    {
        get { return _Salary; }
        set { _Salary = value; }
    }

    public String FullName
    {
        get { return _FirstName + " " +_LastName; }
    }
}

public class SimpleModel : MVCGridViewModel
{
    private List<Person> Persons = new List<Person>();

    public override void AddNewElement(Object Element)
    {
        Persons.Add((Person)Element);
    }

    public override System.Int32 ElementCount
    {
        get
        {
            return Persons.Count;
        }
    }

    public override Boolean IsValid(String formattedValue, String colName)
    {
        try
        {
            if (colName == "Salary")
                Convert.ToDouble(formattedValue);
            return true;
        }
        catch
        {
            Console.Beep();
            return false;
        }
    }

    public override Object GetElement(System.Int32 index)
    {
        return Persons[index];
    }

    public override Object GetElementValue(Object element, String ColName)
    {
        switch (ColName)
        {
            case "First Name": return ((Person)element).FirstName;
            case "Last Name": return ((Person)element).LastName;
            case "Full Name": return ((Person)element).FullName;
            case "Salary": return ((Person)element).Salary;
            default: return "";
        }
    }

    private IEnumerable<DataGridViewColumn> GetVisibleColumns()
    {
        DataGridViewColumn col = new DataGridViewTextBoxColumn();
        col.Name = "First Name";
        col.HeaderText = "First Name";
        col.Resizable = DataGridViewTriState.True;
        yield return col;

        col = new DataGridViewTextBoxColumn();
        col.Name = "Last Name";
        col.HeaderText = "Last Name";
        col.Resizable = DataGridViewTriState.True;
        yield return col;

        col = new DataGridViewTextBoxColumn();
        col.Name = "Full Name";
        col.HeaderText = "Full Name";
        col.Resizable = DataGridViewTriState.True;
        col.ReadOnly = true;
        yield return col;

        col = new DataGridViewTextBoxColumn();
        col.Name = "Salary";
        col.HeaderText = "Salary";
        col.Resizable = DataGridViewTriState.True;
        col.ReadOnly = false;

        yield return col;
    }

    public override void SetElementValue(Object element,
     String ColName, Object Value)
    {
        switch (ColName)
        {
            case "First Name": ((Person)element).FirstName =
            (String)Value; FireDataChanged(); break;
            case "Last Name": ((Person)element).LastName =
            (String)Value; FireDataChanged(); break;
            case "Salary": ((Person)element).Salary =
            Double.Parse(Value.ToString(),
            (NumberStyles.AllowDecimalPoint)); break;
        }
    }

    public override void SetElement(System.Int32 index, Object Element)
    {
        Persons[index] = (Person)Element;
    }

    public override Object NewElement()
    {
        return new Person();
    }

    public override void RemoveAt(System.Int32 index)
    {
        Persons.RemoveAt(index);
    }

    public override IEnumerable<DataGridViewColumn> VisibleColumns
    {
        get { return GetVisibleColumns(); }
    }
}

A little explanation: Person is your the business entity. It has 4 properties. First name, last name and salary is editable. Full name is computed not editable property. Of course, you can put the properties and logic in it. The Person represents a row in the GridView. You can and must provide the collection of visible columns in the GridView. Every other method is right trivial. The only interesting is the IsValid method. In this method, you can test the user input.

What next?

  1. You can add for every row, a different kind of object. You must only change your AddNewElement(Object Element) method.
  2. You can persist the changes immediately. You must update your data in the persistence storage in SetElement(System.Int32 index, Object Element), SetElementValue(Object element, String ColName, Object Value) and RemoveAt(System.Int32 index).

History

  • Initial release 10/29/2004.
  • Computed column added 11/15/2004.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralThe MVCGridViewModel should be an interface Pin
ugog9116-Nov-04 3:41
ugog9116-Nov-04 3:41 
GeneralRe: The MVCGridViewModel should be an interface Pin
Burkovsky16-Nov-04 4:31
Burkovsky16-Nov-04 4:31 
GeneralRe: The MVCGridViewModel should be an interface Pin
ugog9116-Nov-04 5:23
ugog9116-Nov-04 5:23 
GeneralCollections integration Pin
Nick Hounsome12-Nov-04 19:26
Nick Hounsome12-Nov-04 19:26 
GeneralRe: Collections integration Pin
Anonymous13-Nov-04 1:49
Anonymous13-Nov-04 1:49 
General.NET 1.1 Pin
aprogram9-Nov-04 1:18
aprogram9-Nov-04 1:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.