0

我有一个名为 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);

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

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

4

1 回答 1

1

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

基本流程是:

  1. 在窗体上放置一个 DataGridView 控件
  2. 将网格的第一列创建为文本框列对象,并将其 DataPropertyName 设置为与 PhoneNumbers 对象的 PhoneNumber 属性名称相同
  3. 将网格的第 2 列创建为组合框列对象,并将其 DataPropertyName 设置为与 PhoneNumbers 对象的 PhoneType KEY 属性名称相同
  4. 将组合框列绑定到支持表
  5. 将列添加到网格
  6. 将网格的 AutoGenerateColumns 属性设置为 False
  7. 将网格数据源设置为 PhoneNumbers 对象

我将网格列的 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 控件显示来自对象的数据...

于 2012-12-04T04:16:25.077 回答