将文本列转换为对象绑定DataGridView控件中的组合框列

时间:2012-11-26 05:35:49

标签: c# winforms datagridview combobox

我有一个名为Contacts的类,它包含一组名为PhoneNumbers的对象。每个PhoneNumbers对象都有多个属性,包括PhoneNumberPhoneType以及外键PhoneTypeFK。我将此集合分配给DataGridView控件的DataSource并隐藏我不希望在DGV中看到的列(属性)。这会在DGV中创建一组文本单元格(行/列),用于电话号码和类型。除了之外,我还希望在电话类型列中显示一个组合框,其中填充了PhoneTypes表的所有各种电话类型,并在该电话号码的单元格中显示相应的电话类型。
我在某个地方读到我需要在设计时添加一个组合框列,其DataPropertyName对象的属性与PhoneNumbers相同PhoneType,这样当DGV填充列时将使用此列而不是创建一个新列(对于PhoneType)。但是,我无法让它发挥作用。 我使用下面的代码填充DGV并隐藏不相关的列:

//Fill Grid
uxContactPhoneNumbersGrd.DataSource = contacts.PhoneNumbers;

//Hide non-required columns/rows
uxContactPhoneNumbersGrd.RowHeadersVisible = false;
string[] columnNamesToHide = { "ErrMsg", "ContactsFk", "PhoneNumbersPk", "PhoneTypesFk" };
SAPSCommon.Instance.HideGridColumns(ref uxContactPhoneNumbersGrd, columnNamesToHide);

当我这样做时,PhoneType得到2列,一个是填充DGV时创建的文本单元格,另一个是我在设计时添加的组合框列(即使它具有相同的DataPropertyName)如建议)。

如何只为PhoneType获取1列,如何将其绑定到PhoneTypes表,以便来自PhoneNumbers对象的数据为相应的{设置正确的PhoneType {1}}? (在使用PhoneNumber对象填充网格之前,是否需要首先绑定PhoneType组合框列?)

1 个答案:

答案 0 :(得分:1)

好的,经过数小时的反复试验后,我似乎找到了解决办法。

基本过程是:

  1. 在表单
  2. 上放置一个DataGridView控件
  3. 将网格的第1列创建为文本框列对象,并将其DataPropertyName设置为与PhoneNumbers对象的PhoneNumber属性名称相同
  4. 将网格的第二列创建为comboxbox列对象,并将其DataPropertyName设置为与PhoneNumbers对象的PhoneType KEY属性名称相同
  5. 将组合框柱绑定到支撑台
  6. 将列添加到网格
  7. 将网格的AutoGenerateColumns属性设置为False
  8. 将网格数据源设置为PhoneNumbers对象
  9. 我将网格列的DataPropertyName命名为与PhoneNumber对象属性名称相同的原因是网格自动使用PhoneNumber对象列表中的数据填充正确的列。禁用AutoGenerateColumns可确保仅填充指定的列,即网格不会自动为此应用程序不需要的PhoneNumber对象的其他属性生成列。

    这是PhoneNumber类,用于在Contacts对象中创建PhoneNumber对象列表:

    using System;
    using System.Data;
    using System.Text;
    
    namespace SAPS
    {
    public class clsPhoneNumber
    {
        #region Fields (4) 
    
        private int _contacts_FK;
        private string _errMsg;
        private string _phoneNumber;
        private int _phoneNumbers_PK;
        private int _phoneTypes_FK;
        private string _phoneType;
    
        #endregion Fields 
    
        #region Constructors (1) 
    
        public  clsPhoneNumber()
        {
            _errMsg = "";
            _phoneNumbers_PK = 0;
            _phoneTypes_FK = 0;
            _phoneType = "";
            _phoneNumber = "";
            _contacts_FK = 0;
        }
    
        #endregion Constructors 
    
        #region Properties (4) 
    
        public int ContactsFk
        {
            get { return _contacts_FK; }
            set { _contacts_FK = value; }
        }
    
        public string ErrMsg
        {
            get { return _errMsg; }
            set { _errMsg = value; }
        }
    
        public string PhoneNumber
        {
            get { return _phoneNumber; }
            set { _phoneNumber = SAPSCommon.Instance.StripNonNumerics(value); }
        }
    
        public int PhoneNumbersPK
        {
            get { return _phoneNumbers_PK; }
            set { _phoneNumbers_PK = value; }
        }
    
        public int PhoneTypesFK
        {
            get { return _phoneTypes_FK; }
            set { _phoneTypes_FK = value; }
        }
    
        public string PhoneType
        {
            get { return _phoneType; }
        }
    
        #endregion Properties 
    
        #region Methods (2) 
    
        // Public Methods (1) 
    
        /// <summary>
        /// Get the Notes for the specified key
        /// </summary>
        /// <param name="TableID">The Table Primary Key</param>
        /// <returns>An Object containing data for the specified Primary Key</returns>
        public clsPhoneNumber GetData(int TableID)
        {
            AssignProperties(SAPSCommon.Instance.ReadTable("PhoneNumbers", "PN_PhoneNumbers_PK", TableID));
            return this;
        }
        // Private Methods (1) 
    
        /// <summary>
        /// Assigns the table's data to the properties of the Data Object.
        /// This method must be hand coded for each table.
        /// </summary>
        /// <param name="ds">A Dataset containing the data record read from the Table</param>
        private void AssignProperties(DataSet ds)
        {
            //Assign properties with database data
            try
            {
                //Primary Key for Table
                _phoneNumbers_PK = ds.Tables[0].Rows[0].Field<int>("PN_PhoneNumbers_PK");
    
                //The rest of the data fields
                _contacts_FK = ds.Tables[0].Rows[0].Field<int>("PN_Contacts_FK");
                _phoneNumber = FormatPhoneNumber(ds.Tables[0].Rows[0].Field<string>("PN_PhoneNum"));
                _phoneTypes_FK = ds.Tables[0].Rows[0].Field<int>("PN_PhoneTypes_FK");
    
                //Follow links of Foreign Keys
                DataTable dt = new DataTable();
                string sqlSelect =
                    string.Format(
                        "SELECT PT_Description FROM Pensions.dbo.PhoneTypes WHERE PT_PhoneTypes_PK = '{0}'",
                        _phoneTypes_FK);             
                dt = SQLCommon.Instance.SQLSelect(sqlSelect);
                _phoneType = dt.Rows[0].Field<string>("PT_Description");
            }
            catch (Exception e)
            {
                _errMsg = e.Message;
                SAPSCommon.Instance.ShowErrorMsg(e.Message);
            }
        }
    
        /// <summary>
        /// Format an Australian Phone number
        /// </summary>
        /// <param name="Num">Phone Number to format in string format</param>
        /// <returns>Formatted Phone Number</returns>
        private string FormatPhoneNumber(string Num)
        {
            if (Num.Substring(0, 2) == "04") //Mobile Number
            {
                return string.Format("{0:0### ### ###}", Convert.ToInt64(Num));
            }
            return string.Format("{0:(0#) #### ####}", Convert.ToInt64(Num));
        }
    
        #endregion Methods 
    
        public string  Update()
        {
            StringBuilder sb = new StringBuilder("UPDATE [");
            sb.Append(Properties.Settings.Default.SQLDatabaseName);
            sb.Append("].[dbo].[PhoneNumbers] SET PN_Contacts_FK='");
            sb.Append(_contacts_FK);
            sb.Append("', PN_PhoneTypes_FK='");
            sb.Append(_phoneTypes_FK);
            sb.Append("', PN_PhoneNum='");
            sb.Append(_phoneNumber);
            sb.Append("' WHERE PN_PhoneNumbers_PK='");
            sb.Append(_phoneNumbers_PK);
            sb.Append("'");
    
            _errMsg = SQLCommon.Instance.SQLUpdate(sb.ToString());
            return _errMsg;
        }
    }
    

    }

    这是填充DataGridView控件的代码:

            private void PopulatePhoneNumbers(clsContacts contacts)
        {
            //Create the 1st column as a textbox for the Phone Number
            DataGridViewTextBoxColumn tb = new DataGridViewTextBoxColumn();
            tb.Name = "PhoneNumber";
            tb.DataPropertyName = "PhoneNumber"; //This is the name of the PhoneNumber object Property for Phone Number
    
            //Create  2nd column as combobox for PhoneType
            DataGridViewComboBoxColumn cb = new DataGridViewComboBoxColumn();
            cb.Name = "PhoneTypes";
            cb.DataPropertyName = "PhoneTypesFK"; //This is the name of the PhoneNumber object Property for Phone Type
    
            //Bind the cb to the table
            string sqlQuery = "SELECT PT_PhoneTypes_PK, PT_Description " +
                              "FROM [Pensions].[dbo].[PhoneTypes] ";
            DataTable dtPhoneTypes = SQLCommon.Instance.SQLSelect(sqlQuery);
            cb.DataSource = dtPhoneTypes;
            cb.ValueMember = dtPhoneTypes.Columns["PT_PhoneTypes_PK"].ColumnName;
            cb.DisplayMember = dtPhoneTypes.Columns["PT_Description"].ColumnName;
    
            uxContactPhoneNumbersGrd.Columns.Add(tb);
            uxContactPhoneNumbersGrd.Columns.Add(cb);
    
            uxContactPhoneNumbersGrd.AutoGenerateColumns = false;
    
            if (contacts.PhoneNumbers != null)
            {
                //Show how many phone numbers
                uxContactPhoneNumbersLbl.Text = string.Format("Phone Numbers ({0})", contacts.PhoneNumbers.Count);
                uxContactPhoneNumbersLbl.Visible = true;
                //Fill Grid
                uxContactPhoneNumbersGrd.DataSource = contacts.PhoneNumbers;
                //Hide non-required columns/rows
                uxContactPhoneNumbersGrd.RowHeadersVisible = false;
            }
    
            //Adjust text column size and auto wrap
            uxContactPhoneNumbersGrd.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            uxContactPhoneNumbersGrd.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
       }
    

    我希望这可以帮助其他一些可怜的灵魂尝试使用支持表使DataGridView控件显示来自对象的数据......