Search Amazon:

Make a DataGrid row read only based on a cell's value
(this page also shows how to work with delegates, events, and event arguments)

Unfortunately .NET doesn't support this leaving you to write your own code to do it. The C# code below shows how to disable a row based on the value of one of its cells. Actually the row is not disabled per se. The individual cells in the row are.

The code assumes you have a DataGrid formatted with a DataGridTableStyle. The table style contains 2 GridColumnStyles, one for a TextBox in column 1 and one for a data bound ComboBox in column 2. To learn more about using data bound ComboBoxes in a grid click here.

Column 1 contains a "Y" or "N" value. If it is "Y" the row is disabled and cannot be edited. If it contains an "N" it can be. Changing column 1's value from "N" to "Y" instantly disables the row.

The first step is to derive new DataGridEnableTextBoxColumn and DataGridComboBoxColumn GridColumnStyles as shown in the Listings 1 and 2 below. Both classes are derived from the standard DataGridTextBoxColumn class. The Edit method of these derived controls is overridden. Also note the EnableCellEventHandlerxxx Delegates defined at the top these classes. You can think of a delegate as a signature for a method.

When the Edit method is invoked it triggers the CheckxxxEnabled event which is declared at the top of these classes. The CheckxxxEnabled event is associated, via the delegates, with the GridColumnStyles based on the newly derived DataGridEnableTextBoxColumn and DataGridComboBoxColumn. The code to do this is as well as adding the custom ColumnStyles to the grid is shown in Listing 3 below.

Listing 4 shows the SetEnableValues procedure which acts as the handler for the CheckxxxEnabled events. This routine sets the EnableValue flag of its DataGridEnableEventArgs parameter based on the value in column 1 of the grid.

Finally all that's left is to define the Event Arguments used by the EnableCellEventHandlerxxx delegates. This is done in the DataGridEnableEventArgs class which derives from the System.EventArgs class. This can be seen in Listing 5.

Listing 1 - The derived DataGridTextBoxColumn class:

using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace ReadOnly
{
    public delegate void EnableCellEventHandlerTXT( 
         object sender, DataGridEnableEventArgs e);

    public class DataGridEnableTextBoxColumn : DataGridTextBoxColumn
    {
        public event EnableCellEventHandlerTXT CheckTXTEnabled;
	
        private int myColumn;

        public DataGridEnableTextBoxColumn(int theColumn)
        {
            myColumn = theColumn;
        }

        protected override void Edit(
            System.Windows.Forms.CurrencyManager theSource, 
            int    theRowNum, 
            System.Drawing.Rectangle theBounds, 
            bool   theReadOnlyFlag, 
            string theInstantText, 
            bool   theCellIsVisibleFlag)
            {
                bool aEnabled = true;

                if (CheckTXTEnabled != null)
                {
                    DataGridEnableEventArgs e = 
                      new DataGridEnableEventArgs(theRowNum, myColumn, aEnabled);
                    CheckTXTEnabled(this, e);
                    aEnabled = e.EnableValue;
                }

                if(aEnabled)
                    base.Edit(theSource, theRowNum, theBounds, 
                            theReadOnlyFlag, theInstantText, theCellIsVisibleFlag);
            }
    }
}

Listing 2 - The derived DataGridTextBoxColumn class:

using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace ReadOnly
{
    public delegate void EnableCellEventHandlerCBO( 
           object sender, DataGridEnableEventArgs e);

    public class DataGridComboBoxColumn: DataGridTextBoxColumn
    {
        public event EnableCellEventHandlerCBO CheckCBOEnabled;
	
        private int myColumn;

        public DataGridComboBoxColumn()
        {
        }

        protected override void Edit(
            System.Windows.Forms.CurrencyManager theSource, 
            int    theRowNum, 
            System.Drawing.Rectangle theBounds, 
            bool   theReadOnlyFlag, 
            string theInstantText, 
            bool   theCellIsVisibleFlag)
            {
                bool aEnabled = true;

                if (CheckCBOEnabled!= null)
                {
                    DataGridEnableEventArgs e = 
                       new DataGridEnableEventArgs(theRowNum, 0, aEnabled);
                    CheckCBOEnabled(this, e);
                    aEnabled = e.EnableValue;
                }

                if(aEnabled)
                    base.Edit(theSource, theRowNum, theBounds, 
                           theReadOnlyFlag, theInstantText, theCellIsVisibleFlag);
            }
    }
}

Code Listing 3 - format the DataGrid with the derived GridColumnStyles:

    // Create a aGridTableStyle to format the grid.
    DataGridTableStyle aGridTableStyle = new DataGridTableStyle(); 
    aGridTableStyle.MappingName = "myTable";

    // Create GridColumnStyles basd on our derived styles.
    // Here is the TextBox.
    DataGridEnableTextBoxColumn aCol1 = new DataGridEnableTextBoxColumn(0);
    aCol1.MappingName = "Outside_Customer";
    aCol1.HeaderText = "Outside Customer";
    aCol1.Width = 90;
    aCol1.Alignment = HorizontalAlignment.Left;
    aCol1.NullText = "N";
    aCol1.TextBox.MaxLength = 1;
    aCol1.TextBox.Enabled = true;
    aGridTableStyle.GridColumnStyles.Add(aCol1);

    // Here is the ComboBox.
    DataGridComboBoxColumn aCol2 = new DataGridComboBoxColumn();
    aCol2.MappingName = "Customer_ID";
    aCol2.HeaderText = "Customer Name";
    aCol2.Width = 90;
    aCol2.ColumnComboBox.DataSource = myDataSet.Tables["myTable"].DefaultView;
    aCol2.ColumnComboBox.DisplayMember = "Customer_Name";
    aCol2.ColumnComboBox.ValueMember = "Customer_ID";
    aCol2.NullText = "";
    aGridTableStyle.PreferredRowHeight = aCol2.ColumnComboBox.Height;
    aGridTableStyle.GridColumnStyles.Add(aCol2);

    // Add the GridColumnStyles to the GridTableStyle.
    dataGrid.TableStyles.Add(aGridTableStyle);

    // Hook our new event used to disable the TextBox and ComboBox.
    aCol1.CheckTXTEnabled += new EnableCellEventHandlerTXT(SetEnableValues);
    aCol2.CheckCBOEnabled += new EnableCellEventHandlerCBO(SetEnableValues);

Code Listing 4 - Handler for the CheckxxxEnabled events:

    private void SetEnableValues(object sender, DataGridEnableEventArgs e)
    {
        //
        // This handler disables columns based on column 1's value. 
        //
        string aValue = dataGrid[dataGrid.CurrentRowIndex, 0].ToString();
        if (aValue == null)
            aValue = "N";

        if (aValue == "Y")
            e.EnableValue = false;
        else
            e.EnableValue = true;
    }

Code Listing 5 - Event arguments signature:

    using System;

    namespace ReadOnly
    {
        //
        // Event argument signature used by the 
        // EnableCellEventHandlerxxx delegates.
        //
        public class DataGridEnableEventArgs : EventArgs
        {
            private int      myColumnNumber;
            private int      myRowNumber;
            private bool     myEnableValue;

            public DataGridEnableEventArgs(
                int theRowNumber, int theColumnNumber, bool theValue)
            {
                myRowNumber = theRowNumber;
                myColumnNumber = theColumnNumber;
                myEnableValue = theValue;
            } 

            public int ColumnNumber
            {
                get { return myColumnNumber; }
                set { myColumnNumber = value; }
            }

            public int RowNumber
            {
                get{ return myRowNumber; }
                set{ myRowNumber = value; }
            } 

            public bool EnableValue
            {
                get{ return myEnableValue; }
                set{ myEnableValue = value; }
            }
        }
    }

Sign In
  User Id 
  Password 


Submit Your Own Code and Articles




About TheScarms
About TheScarms

Ask me your programming questions

I read every email and answer all I can.

User Feedback: Be the first to add a comment! Items to Show:     

     
You must log in to post feedback.
Comment:    
 

If you use this code, please mention "www.TheScarms.com"

Email this page


TheScarms AppSentinel lets you securely copy protect and create evaluation versions of your software

TheScarms(tm) AppSentinel lets you quickly and easily create evaluation versions of your software and stop unauthorized copying and unregistered use of your programs!

Get your free
trial copy today!


      The World's Number 1 Web Host

© Copyright 2008 TheScarms