Click here to Skip to main content
6,594,932 members and growing! (15,965 online)
Email Password   helpLost your password?
Desktop Development » List Controls » ListView controls     Intermediate

Modify ListView columns at run-time by using XML

By Niklas Henricson

An article describing how to work with ListView columns in C#.
C#, XML.NET 1.1, WinXPVS.NET2003, Dev
Posted:13 Oct 2004
Views:41,086
Bookmarked:23 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
2 votes for this article.
Popularity: 0.99 Rating: 3.29 out of 5

1

2
1 vote, 50.0%
3
1 vote, 50.0%
4

5

Introduction

One of my favorite things to do in .NET is to work with XML. Many times, users are asking if they can modify ListView columns at run-time. I've seen solutions, saving client-side preferences into databases. It is not wrong but it is not practical, considering that this data is not really related to the business-model design.

Background

Working often with systems providing a lot of information causes a difficulty level for developers to find a way to design flexible and user-friendly applications. ListView controls with a large amount of columns are one of these things, for example.

Then, how to modify a ListView control at run-time?

Using the code

The source code under the download session was made in Microsoft Visual Studio .NET 2003 - Enterprise Architect. I experienced issues compiling it in previous .NET studio versions.

Now, we need to add the following items into our solution:

  1. A form hosting our ListView control.
  2. Another form allowing us to modify the ListView at run time.
  3. A DataSet.

In the following example, we create a DataSet and name it to ListviewColumns.xsd. In the Toolbox option, drag and drop an Element, and finally in this Element, add a row Columns of type string (see figures 1 and 2).

Figure 1

Figure 2

On the main form (ListviewFrm), drag and drop a ListView control and set the following properties to it:

  • View: Details
  • FullRowSelect: True
  • Name: mMainListviewLvw

I also added a button (mColumnsBtn). In the mColumnsBtn_Click event, I added the following code to make an instance of my second form:

private void mColumnsBtn_Click(object sender, System.EventArgs e)
{
    ListviewPropertiesFrm listviewProperties = new ListviewPropertiesFrm();
    listviewProperties.Show();
}

In ListviewFrm, under the ListviewApp_Load event, I call a method ReadXMLColumns:

private void ListviewApp_Load(object sender, System.EventArgs e)
{
    ReadXMLColumns();
}

ReadXMLColumns creates a ListviewColumns typed DataSet, and retrieves the data from ListviewColumns.xml file through the ReadXml method.

private void ReadXMLColumns()
{
    ListviewColumns sr;
    DataTable dt;
    DataColumn dc;

    sr = new ListviewColumns();
    dt = new DataTable("ListviewColumn");
    dc = new DataColumn();

    //Add the table into my typed DataSet

    sr.Tables.Add(dt);
    //Retrieve the type and set the name in the DataColumn

    dc.DataType = System.Type.GetType("System.String");
    dc.ColumnName = "CheckBoxName";
    dt.Columns.Add(dc);

    //Retrieve the path to "Application Data"

    //under my Documents and Settings folder.

    string xmlDocPath = 
      Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

    //Add "ListViewApp" folder into this path

    xmlDocPath = xmlDocPath + "/ListViewApp";

    if (!Directory.Exists(xmlDocPath))
    {
        //Create the directory if it does not exist

        Directory.CreateDirectory(xmlDocPath);
    }
    else
    {
        if (File.Exists(xmlDocPath + "/ListviewColumns.xml"))
        {
            //Read the XML file into my typed DataSet

            sr.ReadXml(xmlDocPath + "/ListviewColumns.xml");
            BuildColumnHeaders(sr);
        }
    }
}

BuildColumnHeaders goes through the DataSet, and finally adds the columns in our ListView by calling the BuildColumn method.

//BuildColumnHeaders

//BuildColumnHeaders goes through the DataSet and calls

//BuildColumn

private void BuildColumnHeaders(DataSet sr)
{
    int i = 0;

    foreach(DataRow dr in sr.Tables[0].Rows)
    {
        string checkBoxName = dr["CheckBoxName"].ToString();

        switch (checkBoxName)
        {
            case "First Column":
                i = BuildColumn("First Column", i);
                break;
            case "Second Column":
                i = BuildColumn("Second Column", i);
                break;
            case "Third Column":
                i = BuildColumn("Third Column", i);
                break;
        }
    }
}
//BuildColumn

//BuildColumn adds a column into mMainListviewLvw.

private int BuildColumn(string columnHeaderName, int i)
{

    ColumnHeader col = new ColumnHeader();
    col.Text = columnHeaderName;
    col.Width = 100;
    mMainListviewLvw.Columns.Add(col);
    i ++;

    return i;
}

ListviewFrm will now be able to read the XML file and display the columns. However, we need to add functionality in order to modify our XML file, therefore it is time to see what is going on in the ListviewPropertiesFrm.

On our second form (ListviewPropertiesFrm), add the following controls (see figure 3):

  • Three CheckBoxes (First Column, Second Column and Third Column)
  • OK and Cancel Buttons

Figure 3

In the mOkBtn_Click event, I call the ColumnsToXML method:

private void mOkBtn_Click(object sender, System.EventArgs e)
{
    Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
    ListviewColumnsToXML();
    Cursor.Current = System.Windows.Forms.Cursors.Default;
    Close();
}

In ListviewColumnsToXML method, we create a typed DataSet, then loop through the form controls, and add the CheckBoxes into our DataSet. Finally, we export them into XML by using the WriteXml method.

private void ListviewColumnsToXML()
{
    ListviewColumns sr;
    DataRow dr;
    DataTable dt;
    DataColumn dc;

    sr = new ListviewColumns();
    dt = new DataTable("ListviewColumn");
    dc = new DataColumn();

    //Add the table into my typed dataset

    sr.Tables.Add(dt);
    dc.DataType = System.Type.GetType("System.String");
    //Retrieve the type and set the name in the DataColumn

    dc.ColumnName = "CheckBoxName";
    dt.Columns.Add(dc);

    //Loop through all controls in this form.

    foreach(Control mControl in this.Controls)
    {
        //If the control would be a CheckBox

        if (mControl.GetType().ToString() == "System.Windows.Forms.CheckBox")
        {
            //type cast of the mControl to a CheckBox

            CheckBox C;
            C = (CheckBox) mControl;
            if (C.Checked)
            {
                dr = dt.NewRow();
                dr["CheckBoxName"].ToString();
                //Add the checkbox name into my datarow

                dr["CheckBoxName"] = mControl.Text;
                dt.Rows.Add(dr);
            }
        }
    }
    //Retrieve the path to "Application Data"

    //under my Documents and Settings folder

    string xmlDocPath = Environment.GetFolderPath(
        Environment.SpecialFolder.ApplicationData);

    //Add "ListViewApp" folder into this path

    xmlDocPath = xmlDocPath + "/ListViewApp";
    if (!Directory.Exists(xmlDocPath))
    {
        //Create the directory if it does not exist

        Directory.CreateDirectory(xmlDocPath);
        //and write the XML file

        sr.WriteXml(xmlDocPath + "/ListviewColumns.xml");
    }
    else
    {
        //Write into the XML file

        sr.WriteXml(xmlDocPath + "/ListviewColumns.xml");
    }
}

We are almost done, but we need to add a few things on our ListviewPropertiesFrm_Load event. In order to have our check boxes be checked, or not checked each time we open this form, we need to retrieve the XML data. I use the two methods for that. The first method would do the same things like the ReadXMLColumns did in ListviewFrm, and the second method would set the CheckBoxes' Checked property to true.

Points of Interest

The best way of designing a special ListView for your needs, is to follow an object oriented design. In other words, inherit .NET ListView into a new class, write additional functionality into it, and then create a DLL where you can add it to your future solutions. This ListView could have additional functionality, such as column sorting, pop-up menu, export to Excel, etc.

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

About the Author

Niklas Henricson


Member
Niklas Henricson began with programming in 1999 by working for the Swedish Working Life Enviroment authority.

Since then, he has been involved in numerous projects involving MTS/COM+, VB 6.0, ISE Eiffel 4.5, ASP.NET/C#/VB.NET as well as common ASP, and finally database enviroments based on Oracle, MySQL and MS SQL.

Between April 2007 and December 2008, Niklas worked as consultant for Mandator AB with some of his assignments spended in Ericsson.

Today he works as a senior consultat at Cybercom Group in Sweden assigned in a project for the Swedish Institute for Infectious Disease Control.

One of his most favorite books regarding programming is "The Pragmatic Programmer". Something he is recommending everyone to read.
Occupation: Web Developer
Company: Cybercom Group South AB
Location: Sweden Sweden

Other popular List Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
  (Refresh) 
-- There are no messages in this forum --

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 13 Oct 2004
Editor: Smitha Vijayan
Copyright 2004 by Niklas Henricson
Everything else Copyright © CodeProject, 1999-2009
Web22 | Advertise on the Code Project