将文本列转换为对象绑定DataGridView控件中的组合框列 [英] Convert text column to combobox column in an object bound DataGridView control

查看:70
本文介绍了将文本列转换为对象绑定DataGridView控件中的组合框列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为Contacts的类,它包含一组名为PhoneNumbers的对象。每个PhoneNumbers对象都有几个属性,包括PhoneNumber和PhoneType以及外键PhoneTypeFK。我将此集合分配给DataGridView控件的DataSource,并隐藏我不希望在DGV中看到的所有其他列(属性)。这会在DGV中创建一组文本单元格(行/列),用于电话号码和类型。一切都很好,除了,我想在电话类型列中显示一个组合框,其中填充了PhoneTypes表的所有各种电话类型,并在该电话号码的单元格中显示相应的电话类型。

我在某处读到需要在设计时添加一个组合框列,其中DataPropertyName与PhoneNumbers对象的属性相同,即PhoneType,这样当DGV填充列时,它将使用此列而不是创建新列(对于PhoneType)。但是,我无法让它发挥作用。我使用下面的代码填充DGV并隐藏不相关的列:



  / /  填充网格 
uxContactPhoneNumbersGrd.DataSource = contacts.PhoneNumbers;

// 隐藏不需要的列/行
uxContactPhoneNumbersGrd .RowHeadersVisible = false ;
string [] columnNamesToHide = { ErrMsg ContactsFk PhoneNumbersPk PhoneTypesFk};
SAPSCommon.Instance.HideGridColumns( ref uxContactPhoneNumbersGrd,columnNamesToHide);



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



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

解决方案

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



基本流程是:



1)放置一个DataGridView控件在表格上

2)创建网格的第一列作为文本框列对象,并将其DataPropertyName设置为与PhoneNumbers对象的PhoneNumber属性名称相同

3)创建网格的第二列作为comboxbox列对象,并将其DataPropertyName设置为与PhoneNumbers对象的PhoneType KEY属性名称相同

4)将组合框列绑定到支持表

5)将列添加到网格中

6)将网格的AutoGenerateColumns属性设置为False

7)将网格DataSource设置为PhoneNumbers对象



我为DataProp命名的原因网格列的ertyName与PhoneNumber对象相同属性名称使网格自动使用PhoneNumber对象列表中的数据填充正确的列。禁用AutoGenerateColumns可确保仅填充指定的列,即网格不会自动为此应用程序不需要的PhoneNumber对象的其他属性生成列。



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



 使用系统; 
使用 System.Data;
使用 System.Text;

命名空间 SAPS
{
public class clsPhoneNumber
{
#region字段(4​​)

private int _contacts_FK;
private string _errMsg;
private string _phoneNumber;
private int _phoneNumbers_PK;
private int _phoneTypes_FK;
private string _phoneType;

#endregion字段

#region构造函数(1)

public clsPhoneNumber()
{
_errMsg = ;
_phoneNumbers_PK = 0 ;
_phoneTypes_FK = 0 ;
_phoneType = ;
_phoneNumber = ;
_contacts_FK = 0 ;
}

#endregion构造函数

#region属性(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属性

#region方法(2)

// 公共方法(1)

/// < 摘要 >
/// 获取指定键的注释
/// < / summary >
/// < param name = TableID > 表主键< / param >
/// < span class =code-comment> < 返回 > 包含指定主键的数据的对象< / returns >
public clsPhoneNumber GetData( int TableID)
{
AssignProperties(SAPSCommon.Instance.ReadTable( PhoneNumbers PN_PhoneNumbers_PK,TableID));
返回 ;
}
// 私有方法(1)

/// < 摘要 >
/// 将表的数据分配给数据对象的属性。
/// 此方法必须为每个表手动编码。
/// < / summary >
/// < param < span class =code-summarycomment> name =ds > 数据集包含从表中读取的数据记录< / param >
private void AssignProperties(DataSet ds)
{
// 使用数据库分配属性se数据
尝试
{
// 表的主键
_phoneNumbers_PK = ds.Tables [ 0 ]。行[ 0 ]。字段< int>( PN_PhoneNumbers_PK );

// 其余数据字段
_contacts_FK = ds.Tables [ 0 ]。行[ 0 ]。字段< int>( PN_Contacts_FK);
_phoneNumber = FormatPhoneNumber(ds.Tables [ 0 ]。行[ 0 ]。字段< string>( PN_PhoneNum));
_phoneTypes_FK = ds.Tables [ 0 ]。行[ 0 ]。字段< int> ( PN_PhoneTypes_FK);

// 关注外键链接
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 ]。字段< string>( PT_Description);
}
catch (例外e)
{
_errMsg = e.Message;
SAPSCommon.Instance.ShowErrorMsg(e.Message);
}
}

/// < 摘要 >
/// 格式化澳大利亚电话号码
/// < / summary < span class =code-summarycomment>>
/// < param name =Num > 以字符串格式格式化的电话号码< / param >
< span class =code-summarycomment> /// < 返回 > 格式化电话号码< / return >
private string FormatPhoneNumber( string Num)
{
if (Num.Substring( 0 2 )== 04 // 手机号码
{
return string .Format( {0:0 ### ### ###},Convert.ToInt64(Num));
}
return string .Format( {0:(0#)#### ####},Convert.ToInt64(Num));
}

#endregion方法

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;
}
}
}
< / string > < / int < span class =code-keyword>> < / string > < / int > < / int >



这是填充DataGridView控件的代码:

  private   void  PopulatePhoneNumbers(clsContacts contacts)
{
// 创建第1列作为Phon的文本框e Number
DataGridViewTextBoxColumn tb = new DataGridViewTextBoxColumn();
tb.Name = PhoneNumber;
tb.DataPropertyName = PhoneNumber; // 这是PhoneNumber对象的名称电话号码的属性

// 为PhoneType创建第二列为combobox
DataGridViewComboBoxColumn cb = new DataGridViewComboBoxColumn();
cb.Name = PhoneTypes;
cb.DataPropertyName = PhoneTypesFK; // 这是PhoneNumber对象的名称Phone Type的属性

// 将cb绑定到支持表
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
{
// 显示多少个电话号码
uxContactPhoneNumbersLbl.Text = string .Format( 电话号码({0}),contacts.PhoneNumbers.Count);
uxContactPhoneNumbersLbl.Visible = true ;

// 填充网格
uxContactPhoneNumbersGrd.DataSource = contacts。电话号码;

// 隐藏不需要的列/行
uxContactPhoneNumbersGrd .RowHeadersVisible = false ;
}

// 调整文本列大小并自动换行
uxContactPhoneNumbersGrd.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
uxContactPhoneNumbersGrd.AutoSizeRowsMo​​de = DataGridViewAutoSizeRowsMo​​de.AllCells;
}



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


I have a class called Contacts which contains a collection of objects called PhoneNumbers. Each PhoneNumbers object has several properties including PhoneNumber and PhoneType as well as the foreign key PhoneTypeFK. I assign this collection to a DataGridView control’s DataSource and hide all the other columns (properties) I don’t want to see in the DGV. This creates a bunch of text cells (rows/cols) in the DGV being for the Phone Number and the Type. All well and good except, I want a combobox to be shown in the Phone Type column populated with all the various Phone Types of the PhoneTypes Table with the appropriate Phone Type shown in the cell for that Phone Number.
I read somewhere that I need to add a combobox column at design time with the same DataPropertyName as the Property of the PhoneNumbers Object, i.e. PhoneType, so that when the DGV is populated with columns it will use this column instead of creating a new one (for the PhoneType). I cannot, however, get this to work. I used the code below to populate the DGV and hide the irrelevant columns:

//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);


When I do this, I get 2 columns for the PhoneType, one is the text cell created when populating the DGV, the other is the combobox column I added at design time (even though it has the same DataPropertyName as suggested).

How do I get only 1 column for PhoneType and how do I bind it to the PhoneTypes Table so that the data from the PhoneNumbers Objects sets the correct PhoneType for the respective PhoneNumber? (Do I need to bind the PhoneType combobox column 1st before populating the grid with the PhoneNumbers Objects?)

解决方案

OK, so after MANY hours of trial and error I seem to have found a solution.

The basic process is to:

1) Place a DataGridView control on the form
2) Create the 1st column of the grid as a textbox column object and set its DataPropertyName the same as the PhoneNumber Property name of the PhoneNumbers Object
3) Create the 2nd column of the grid as a comboxbox column object and set its DataPropertyName the same as the PhoneType KEY Property name of the PhoneNumbers object
4) Bind the combobox column to the supporting table
5) Add the columns to the grid
6) Set the grid''s AutoGenerateColumns property to False
7) Set the grids DataSource to the PhoneNumbers Object

The reason I name the DataPropertyName of the grid columns to be the same as the PhoneNumber object Property names is so that the grid automatically populates the correct columns with the data from the list of PhoneNumber objects. Disabling AutoGenerateColumns ensures only the named columns are populated, i.e. the grid does not automatically generate columns for the other properties of the PhoneNumber objects which are not required for this application.

This is the PhoneNumber class which is used to create a list of PhoneNumber objects in the Contacts object:

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;
        }
    }
}
</string></int></string></int></int>


This is the code that populates the DataGridView control:

 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 support 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;

     //Add the columns to the grid
     uxContactPhoneNumbersGrd.Columns.Add(tb);
     uxContactPhoneNumbersGrd.Columns.Add(cb);

     //Prevent automatically generating columns for other properties
     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;
}


I hope this helps some other poor soul out there trying to make the DataGridView control display data from an object using a support table...


这篇关于将文本列转换为对象绑定DataGridView控件中的组合框列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆