我有一个名为Contacts的类,它包含一组名为PhoneNumbers
的对象。每个PhoneNumbers
对象都有多个属性,包括PhoneNumber
和PhoneType
以及外键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
组合框列?)
答案 0 :(得分:1)
好的,经过数小时的反复试验后,我似乎找到了解决办法。
基本过程是:
我将网格列的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控件显示来自对象的数据......