3

グリッドビューにドロップダウンリストを配置すると、バウンドフィールドをオーバーライドしてドロップダウンリストを表示することができました。

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イベントでもうまく機能します。このイベントでは、データバインドされたアイテムに値が含まれていない場合にデフォルトを選択できるようになりました。

ただし、ドロップダウンリストがグリッドビューに表示される場合、AppendDataBoundItems = trueを設定したため、デフォルト値に加えてデータソースからのすべてがTWICEに含まれます。これにより、アイテムが追加されたときにドロップダウンがアイテムをクリアし ないようになります。グリッドビューはdatabindを2回呼び出す必要があります。ただし、OnDataBindイベントメソッドに登録されるのは1回だけです。そこには1つの呼び出ししか表示されません。その瞬間、すべてが正常です。ドロップダウンには、デフォルトのアイテムとデータソースの各アイテムの1つが含まれます。

データバインディングを完全に制御できるように、データバインディングをどこで、またはどのように処理できるかについての提案はありますか?

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 に答える