3

如果我把它放在一个 Gridview 中,我设法覆盖了 Boundfield 以显示一个下拉列表。

protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
    {
        Control child = null;
        Control cellControl = null;

        if ((((rowState & DataControlRowState.Edit) != DataControlRowState.Normal) && !this.ReadOnly) 
            || ((rowState & DataControlRowState.Insert) != DataControlRowState.Normal))
        {
            // If data cell is in edit mode, create DropDownList editor for this cell
            // and set data properties.
            
            DropDownList box = new DropDownList();                
            box.Items.Add(DefaultValueText);               

            box.DataSource = this.GetDataSource();
            box.DataMember = this.BusinessObjectName;
            box.DataTextField = this.DataTextField;
            box.DataValueField = this.DataValueField;
            box.AppendDataBoundItems = true;
            box.ToolTip = this.HeaderText;

            cell.Controls.Add(box);
            box.DataBind();
            // if in edit mode, prepare dropdown for binding
            if ((this.DataField.Length != 0) && ((rowState & DataControlRowState.Edit) != DataControlRowState.Normal))
            {
                cellControl = box;
            }
        }
        else if (this.DataField.Length != 0)    // if in read only mode, prepare cell for binding
        {
            cellControl = cell;
        }

        if ((cellControl != null) && base.Visible)
        {
            cellControl.DataBinding += new EventHandler(this.OnDataBindField);
        }
    }
    

    protected override void OnDataBindField(object sender, EventArgs e)
    {
        Control control = (Control)sender;
        Control namingContainer = control.NamingContainer;
        object dataValue = this.GetValue(namingContainer);
        bool encode = (this.SupportsHtmlEncode && this.HtmlEncode) && (control is TableCell);
        string str = this.FormatDataValue(dataValue, encode);
        if (control is TableCell)
        {
            if (str.Length == 0)
            {
                str = " ";
            }
            ((TableCell)control).Text = str;
        }
        else
        {
            //If data cell is in edit mode, set selected value of DropDownList 
            if (dataValue != null)
            {
                DropDownList dropDownList = (DropDownList) control;
                
                ListItem itm = dropDownList.Items.FindByText(dataValue.ToString());
                if (itm != null)
                {
                    dropDownList.Text = itm.Value;
                }
                else
                    ((DropDownList)control).Text = DefaultValueText;
            }
        }
    }

我添加的最后一个功能是在未选择任何内容时显示的默认值/附加项目,例如“请选择”。我可以通过 OnDataBind 事件中的属性 DefaultValueText 进行设置。

现在这是我面临的问题:

在 InitializeDataCell 中,如果我设置

box.AppendDataBoundItems = true;

并打电话

box.DataBind();

下拉列表包含所有项目以及附加的默认项目。它在 OnDataBind 事件中也能很好地工作,如果数据绑定项不包含值,我现在可以在该事件中选择默认值。

但是当下拉列表显示在gridview中时,它包含默认值加上数据源TWICE中的所有内容,因为我设置了AppendDataBoundItems = true,这导致下拉列表在添加项目时不会清除它的项目 gridview必须调用databind两次,但它只在 OnDataBind 事件方法中注册一次。我在那里只看到一个电话,在那一刻,一切都很好,下拉列表包含默认项目加上数据源中的每个项目之一。

有什么建议可以在哪里或如何处理数据绑定,以便完全控制数据绑定?

4

2 回答 2

2

我设法让它工作

我将所有用于设置 selectedValue 的代码移到了 DropDownList 的 DataBound 事件中。在这种情况下,数据绑定已经发生,值列表可供我设置 selectedValue。我不再自己调用 DataBind,因为无论如何它都在控件上被调用。我只在开头添加“进行选择”项并将 AppendDataBoundItems 设置为 true。

现在在某些只读状态下可能存在未处理的情况,因为我不处理任何 Cell.Databinding() 事件。

完整的源代码供有兴趣的人...

它基于CodeProjct上 Javad Zarrinabadi 的示例

用法:

DropDownBoundField dropDownBoundField = new DropDownBoundField();
        dropDownBoundField.HeaderText = "NyColumnName";
        dropDownBoundField.BusinessObjectName = "BusinessLogic.MyDataClass";
        dropDownBoundField.SelectMethod = "GetEnumerable";
        dropDownBoundField.DataTextField = "Name";   // what should be displayed
        dropDownBoundField.DataValueField = "Id";    // value behind the displayed text
        dropDownBoundField.DataField = "IdProperty"; // Property to bind to
        dropDownBoundField.DefaultValueText = "Select";  // text on first item as 
                                                      default if DataField is null            
        dropDownBoundField.FindBy = SetSelectedValueBy.Value  // Choose how the DataField is being evaluated, as source for the value or the text
        GridView.Columns.Add(dropDownBoundField);

班级:

 using System;
 using System.Web.UI.WebControls;
 using System.Web.UI;
 using System.ComponentModel;
 using System.Web;
 using System.Collections.Specialized;

namespace IDVCode.GridViews
{
public class DropDownField : BoundField
{
    #region fields
    private string _listDataSourceID;
    private string _listDataMember;
    private string _listDataTextField;
    private string _listDataValueField;
    #endregion 

    #region eventHandler

    protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
    {
            DropDownList dropDownList = new DropDownList();
            dropDownList.ToolTip = HeaderText;
            dropDownList.DataSourceID = ListDataSourceID;
            dropDownList.DataMember = ListDataMember;
            dropDownList.DataTextField = ListDataTextField;
            dropDownList.DataValueField = ListDataValueField;
            dropDownList.Enabled = !ReadOnly;
            cell.Controls.Add(dropDownList);

            if (rowState == DataControlRowState.Normal || rowState == DataControlRowState.Alternate || ReadOnly)
            {
                dropDownList.Enabled = false;
            }
            if (DataField.Length != 0) // && ((rowState & DataControlRowState.Edit) != DataControlRowState.Normal))
            {
                dropDownList.DataBound += new EventHandler(OnDataBindField);
            }
       }

    protected override void OnDataBindField(object sender, EventArgs e)
    {
        Control control = (Control)sender;
        Control namingContainer = control.NamingContainer;
        object dataValue = GetValue(namingContainer);
        bool encode = (SupportsHtmlEncode && HtmlEncode) && (control is TableCell);
        string str = FormatDataValue(dataValue, encode);
        if (control is TableCell)
        {
            if (str.Length == 0)
            {
                str = " ";
            }
            ((TableCell)control).Text = str;
        }
        else
        {
            if (!(control is DropDownList))
            {
                throw new HttpException("BoundField_WrongControlType");
            }
            if (((DropDownList)control).Items.Count > 0)    // Don't call selectedValue if empty
            {
                if (dataValue != null)
                {
                    DropDownList dropDownList = (DropDownList)control;

                    ListItem item = null;
                    if (FindBy == SetSelectedValueBy.Value)
                    {
                        item = dropDownList.Items.FindByValue(dataValue.ToString());
                    }
                    else
                    {
                        item = dropDownList.Items.FindByText(dataValue.ToString());
                    }

                    if (item != null)
                        dropDownList.Text = item.Value;
                    else
                    {
                        ListItem defaultItem = dropDownList.Items.FindByText(DefaultValueText);
                        if (defaultItem != null)
                            dropDownList.SelectedValue = defaultItem.Value;
                    }
                }
            }
        }
    }

    public override void ExtractValuesFromCell(IOrderedDictionary dictionary, DataControlFieldCell cell,
        DataControlRowState rowState, bool includeReadOnly)
    {
        Control control = null;
        string dataField = DataField;
        object text = null;
        string nullDisplayText = NullDisplayText;
        if (((rowState & DataControlRowState.Insert) == DataControlRowState.Normal) || InsertVisible)
        {
            if (cell.Controls.Count > 0)
            {
                control = cell.Controls[0];
                DropDownList box = control as DropDownList;
                if (box != null)
                {
                    text = box.SelectedValue;
                }
            }
            else if (includeReadOnly)
            {
                string s = cell.Text;
                if (s == " ")
                {
                    text = string.Empty;
                }
                else if (SupportsHtmlEncode && HtmlEncode)
                {
                    text = HttpUtility.HtmlDecode(s);
                }
                else
                {
                    text = s;
                }
            }
            if (text != null)
            {
                if (((text is string) && (((string)text).Length == 0)) && ConvertEmptyStringToNull)
                {
                    text = null;
                }
                if (((text is string) && (((string)text) == nullDisplayText)) && (nullDisplayText.Length > 0))
                {
                    text = null;
                }
                if (dictionary.Contains(dataField))
                {
                    dictionary[dataField] = text;
                }
                else
                {
                    dictionary.Add(dataField, text);
                }
            }
        }
    }

    #endregion

    #region Properties

    public virtual string ListDataSourceID
    {
        get
        {
            if (_listDataSourceID == null)
            {
                object stateBag = ViewState["ListDataSourceID"];
                if (stateBag != null)
                {
                    _listDataSourceID = (string)stateBag;
                }
                else
                {
                    _listDataSourceID = string.Empty;
                }
            }
            return _listDataSourceID;
        }
        set
        {
            if (!object.Equals(value, ViewState["ListDataSourceID"]))
            {
                ViewState["ListDataSourceID"] = value;
                _listDataSourceID = value;
                OnFieldChanged();
            }
        }
    }

    public virtual string ListDataMember
    {
        get
        {
            if (_listDataMember == null)
            {
                object stateBag = ViewState["ListDataMember"];
                if (stateBag != null)
                {
                    _listDataMember = (string)stateBag;
                }
                else
                {
                    _listDataMember = string.Empty;
                }
            }
            return _listDataMember;
        }
        set
        {
            if (!object.Equals(value, ViewState["ListDataMember"]))
            {
                ViewState["ListDataMember"] = value;
                _listDataMember = value;
                OnFieldChanged();
            }
        }
    }

    public virtual string ListDataTextField
    {
        get
        {
            if (_listDataTextField == null)
            {
                object stateBag = ViewState["ListDataTextField"];
                if (stateBag != null)
                {
                    _listDataTextField = (string)stateBag;
                }
                else
                {
                    _listDataTextField = string.Empty;
                }
            }
            return _listDataTextField;
        }
        set
        {
            if (!object.Equals(value, ViewState["ListDataTextField"]))
            {
                ViewState["ListDataTextField"] = value;
                _listDataTextField = value;
                OnFieldChanged();
            }
        }
    }

    public virtual string ListDataValueField
    {
        get
        {
            if (_listDataValueField == null)
            {
                object stateBag = ViewState["ListDataValueField"];
                if (stateBag != null)
                {
                    _listDataValueField = (string)stateBag;
                }
                else
                {
                    _listDataValueField = string.Empty;
                }
            }
            return _listDataValueField;
        }
        set
        {
            if (!object.Equals(value, ViewState["ListDataValueField"]))
            {
                ViewState["ListDataValueField"] = value;
                _listDataValueField = value;
                OnFieldChanged();
            }
        }
    }

    [Description("Sets a default value if applicable")]
    [Category("Appearance")]
    public string DefaultValueText
    {
        get
        {
            object val = ViewState["DefaultValueText"];
            if (val != null)
            {
                return (string)val;
            }
            return (string.Empty);
        }

        set
        {
            ViewState["DefaultValueText"] = value;
        }
    }

    [Description("Defines how the SelectedValue is set")]
    [Category("Data")]
    [DefaultValue(SetSelectedValueBy.Value)]
    public SetSelectedValueBy FindBy
    {
        get
        {
            object val = ViewState["SetSelectedValueBy"];
            return val != null ? (SetSelectedValueBy) val : SetSelectedValueBy.Value;
        }
        set
        {
            ViewState["SetSelectedValueBy"] = value;
        }
    }

    public enum SetSelectedValueBy
    {
        Text,
        Value
    }

    #endregion
}

}

于 2009-12-30T13:53:05.000 回答
0

好吧,我知道在某些情况下它确实绑定了多次(在更改标准等时),所以你必须再次处理这个问题......你可以清除列表并重新绑定吗?

于 2009-12-30T10:48:18.813 回答