Articles on Custom GridView Fields

Rate It (1)

Last post 09-30-2005 2:37 PM by Eilon. 1 replies.

Sort Posts:

  • Articles on Custom GridView Fields

    08-19-2005, 3:42 PM
    • All-Star
      27,996 point All-Star
    • bmains
    • Member since 10-22-2004, 12:20 PM
    • Posts 5,646
    Hello,

    I was curious if anyone came across an article on creating a custom GridView field...  maybe one inherited from BoundField, but that doesn't matter.  Just couldn't find any custom field articles...

    Thanks.
    Brian

    "Trust in the Lord and do what is good; dwell in the land and live securely. Take delight in the Lord, and He will give you your heart's desires" (Psalm 37: 3-4).
  • Re: Articles on Custom GridView Fields

    09-30-2005, 2:37 PM
    • Contributor
      5,641 point Contributor
    • Eilon
    • Member since 06-26-2002, 6:14 PM
    • Redmond, WA
    • Posts 964
    • AspNetTeam

    Hi Brian,
    Unfortunately I don't know of any articles about the topic, however I am planning on writing one at some point. For now to get you started, here's a sample of a "NullableCheckBoxField". It allows editing of fields that are of type Nullable<bool> and actually supports all three states: true, false, null (not set). This is unlike the built-in GridView CheckBoxField that only supports true and false.

    Here's the snippet of code:
    namespace NullableTest {
        using System;
        using System.ComponentModel;
        using System.Reflection;
        using System.Web.UI;
        using System.Web.UI.WebControls;

        public class NullableCheckBoxField : BoundField {

            private PropertyDescriptor _boundFieldDesc;

            // Called when a data bound control needs to get the value back out of the control(s) created by this cell
            public override void ExtractValuesFromCell(System.Collections.Specialized.IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly) {
                Control childControl = null;
                string dataField = DataField;
                object value = null;

                if (cell.Controls.Count > 0) {
                    childControl = cell.Controls[0];

                    NullableCheckBox dropDownList = childControl as NullableCheckBox;
                    if (dropDownList != null) {
                        if (includeReadOnly || dropDownList.Enabled) {
                            switch (dropDownList.SelectedIndex) {
                                case 0:
                                    value = new bool?(true);
                                    break;
                                case 1:
                                    value = new bool?(false);
                                    break;
                                case 2:
                                    value = null;
                                    break;
                            }
                        }
                    }
                }

                if (dictionary.Contains(dataField)) {
                    dictionary[dataField] = value;
                }
                else {
                    dictionary.Add(dataField, value);
                }
            }

            // Called when a data bound control need to get the value for this cell when is is being data bound
            protected virtual object GetValue(Control controlContainer) {
                object data = null;
                object dataItem = null;
                string boundField = DataField;

                if (controlContainer == null) {
                    throw new ArgumentNullException("controlContainer");
                }

                // Get the DataItem from the container
                dataItem = DataBinder.GetDataItem(controlContainer);

                if (dataItem == null && !DesignMode) {
                    throw new InvalidOperationException("No data item");
                }
                // Get value of field in data item
                if (_boundFieldDesc == null) {
                    if (!boundField.Equals(ThisBLOCKED EXPRESSION {
                        _boundFieldDesc = TypeDescriptor.GetProperties(dataItem).Find(boundField, true);
                        if ((_boundFieldDesc == null) && !DesignMode) {
                            throw new InvalidOperationException("The field '" + boundField + "' was not found on the data item");
                        }
                    }
                }

                if (_boundFieldDesc != null && dataItem != null) {
                    data = _boundFieldDesc.GetValue(dataItem);
                }
                else {
                    if (DesignMode) {
                        data = GetDesignTimeValue();
                    }
                    else {
                        data = dataItem;
                    }
                }

                return data;
            }

            // Called when the child controls for this cell need to be created
            protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState) {
                NullableCheckBox childControl = null;
                NullableCheckBox boundControl = null;

                if (((rowState & DataControlRowState.Edit) != 0 && ReadOnly == false) || (rowState & DataControlRowState.Insert) != 0) {
                    NullableCheckBox editor = new NullableCheckBox();
                    editor.ToolTip = HeaderText;
                    childControl = editor;

                    if (DataField.Length != 0 && (rowState & DataControlRowState.Edit) != 0) {
                        boundControl = editor;
                    }
                }
                else if (DataField.Length != 0) {
                    NullableCheckBox editor = new NullableCheckBox();
                    editor.Enabled = false;
                    childControl = editor;
                    boundControl = editor;
                }

                if (childControl != null) {
                    MethodInfo mi = typeof(Control).GetMethod("ClearChildState", (BindingFlags)(-1));
                    mi.Invoke(childControl, new object[0]);
                    cell.Controls.Add(childControl);
                }

                if (boundControl != null) {
                    boundControl.DataBinding += new EventHandler(OnDataBindField);
                }
            }

            // Called when the cell is being data bound
            protected override void OnDataBindField(object sender, EventArgs e) {
                Control boundControl = (Control)sender;
                Control controlContainer = boundControl.NamingContainer;

                object data = GetValue(controlContainer);

                bool? dataBool = (bool?)data;
                if (!dataBool.HasValue) {
                    ((NullableCheckBox)boundControl).SelectedIndex = 2;
                }
                else {
                    ((NullableCheckBox)boundControl).SelectedIndex = dataBool.Value ? 0 : 1;
                }
            }

            // Simple 3-state checkbox. Since no such thing exists in HTML, we use a DropDownList with three options instead.
            private sealed class NullableCheckBox : DropDownList {
                public NullableCheckBox() {
                    Items.Add("true");
                    Items.Add("false");
                    Items.Add("not set");
                }
            }
        }
    }


    And you'd use it just like any other field in a GridView, except that it only works against Nullable<bool> types.

    I hope this gets you pointed in the right direction!

    Thanks,
    Eilon

    Blog: http://weblogs.asp.net/LeftSlipper/
Page 1 of 1 (2 items)