好的,经过数小时的反复试验,我似乎找到了解决方案。
基本流程是:
- 在窗体上放置一个 DataGridView 控件
- 将网格的第一列创建为文本框列对象,并将其 DataPropertyName 设置为与 PhoneNumbers 对象的 PhoneNumber 属性名称相同
- 将网格的第 2 列创建为组合框列对象,并将其 DataPropertyName 设置为与 PhoneNumbers 对象的 PhoneType KEY 属性名称相同
- 将组合框列绑定到支持表
- 将列添加到网格
- 将网格的 AutoGenerateColumns 属性设置为 False
- 将网格数据源设置为 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 控件显示来自对象的数据...