如何实现在DataGrid控件上使用下拉列表框。

Bluclyf 2003-10-10 12:12:38
DataSet中包含A、B两个表。

B表内容如下
BID 自动编号
Name内容

A表内容如下
ID自动编号
BID B表中的编号

要实现显示A表,A表中的BID显示为B表中的Name。添加修改时用下拉列表列举出B表中所有的Name。小弟表达能力太差,还望见谅。基本上就像Access中的查阅向导的作用。
...全文
43 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
newchar 2003-10-14
  • 打赏
  • 举报
回复
各个实例
请参考
namespace ClsBase
{

#region the class apply to initialize combo column in datagrid

public delegate void ComboValueChanged( int changingRow, object newValue );

// Step 1. Derive a custom column style from DataGridTextBoxColumn
// a) add a ComboBox member
// b) track when the combobox has focus in Enter and Leave events
// c) override Edit to allow the ComboBox to replace the TextBox
// d) override Commit to save the changed data
public class DataGridComboBoxColumn : DataGridTextBoxColumn
{
public NoKeyUpCombo ColumnComboBox = null;
private System.Windows.Forms.CurrencyManager _source = null;
private int _rowNum;
private bool _isEditing = false;
ComboValueChanged _valueChanging;

public DataGridComboBoxColumn(ComboValueChanged valueChanging) : base()
{
_valueChanging = valueChanging;
ColumnComboBox = new NoKeyUpCombo();

ColumnComboBox.Leave += new EventHandler(LeaveComboBox);
//ColumnComboBox.Enter += new EventHandler(ComboMadeCurrent);
ColumnComboBox.SelectedIndexChanged += new System.EventHandler(ComboIndexChanged);
ColumnComboBox.SelectionChangeCommitted += new System.EventHandler(ComboStartEditing);

}

private void ComboStartEditing(object sender, EventArgs e)
{
_isEditing = true;
base.ColumnStartedEditing((Control) sender);
}

private void ComboIndexChanged(object sender, EventArgs e)
{
_valueChanging(_rowNum , ColumnComboBox.SelectedValue);
}

// private void ComboMadeCurrent(object sender, EventArgs e)
// {
// //_isEditing = true;
// }

private void LeaveComboBox(object sender, EventArgs e)
{
if(_isEditing)
{
SetColumnValueAtRow(_source, _rowNum, ColumnComboBox.SelectedValue);
_isEditing = false;
Invalidate();
}
ColumnComboBox.Hide();
}

protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
base.Edit(source,rowNum, bounds, readOnly, instantText , cellIsVisible);

_rowNum = rowNum;
_source = source;

ColumnComboBox.Parent = this.TextBox.Parent;
ColumnComboBox.Location = this.TextBox.Location;
ColumnComboBox.Size = new Size(this.TextBox.Size.Width, ColumnComboBox.Size.Height);
ColumnComboBox.SelectedIndexChanged -= new System.EventHandler(ComboIndexChanged);
ColumnComboBox.SelectedValue = this.TextBox.Text;
ColumnComboBox.SelectedIndexChanged += new System.EventHandler(ComboIndexChanged);

this.TextBox.Visible = false;
ColumnComboBox.Visible = true;
ColumnComboBox.BringToFront();
ColumnComboBox.Focus();
}

protected override bool Commit(System.Windows.Forms.CurrencyManager dataSource, int rowNum)
{
if(_isEditing)
{
_isEditing = false;
SetColumnValueAtRow(dataSource, rowNum, ColumnComboBox.SelectedValue);
}
return true;
}

}

public class NoKeyUpCombo : ComboBox
{
const int WM_KEYUP = 0x101;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if(m.Msg == WM_KEYUP)
{
//ignore keyup to avoid problem with tabbing & dropdownlist;
return;
}
base.WndProc(ref m);
}
}


#endregion

public class ClsInit
{
public ClsInit()
{
//
// TODO: Add constructor logic here
//
}

}
}

窗体中调用:

...........
private void InitGrid(DataGrid pGrid,DataSet pds)
{
pGrid.TableStyles.Clear();
DataGridTableStyle ts=new DataGridTableStyle();
ts.MappingName="aaa"; // 表名
DataGridComboBoxColumn ComboCol = new DataGridComboBoxColumn(new ComboValueChanged(MyComboValueChanged));
ComboCol.MappingName = "ColumnName"; // 字段名
ComboCol.HeaderText = "aaaaaa";

ComboCol.Items.Add .....

ComboCol.ColumnComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
ts.GridColumnStyles.Add(ComboCol);
pGrid.TableStyles.Add(ts);
}


private void MyComboValueChanged(int rowChanging, object newValue)
{
// Console.WriteLine("index changed {0} {1}", rowChanging, newValue);
}

........
OOSnoopy 2003-10-14
  • 打赏
  • 举报
回复
歡迎來QQ上討論:2636829
OOSnoopy 2003-10-14
  • 打赏
  • 举报
回复
CSDN上關于.NET的高手太少了,而微軟自身的幫助文檔有的講得又粗略了些,苦惱!
OOSnoopy 2003-10-14
  • 打赏
  • 举报
回复
在WinForm中的實現:
這種方法要求在表格中定義兩個列,一個列是代碼字段,一個列是名稱字段,如果不是這種代碼和名稱的,則一個足矣。如果大家有更好的方法,那就最好不過了。
定義一個ComboBox對象,把它加入到DataGrid中,dataGrid1.Controls.Add(comboBox1);
設置comboBox1.visible = false;
設置comboBox1.DataSoruce = 要在下拉框中顯示的數據源。
設置comboBox1.ValueMember = 代碼字段。
設置comboBox1.DisplayMember = 在下拉框中要顯示的字段。
設置comboBox1.DataBinding.Add("SelectedValue", 表格中綁定代碼列字段名)
設置comboBox1.DataBinding.Add("Text", 表格中綁定名稱列的字段名)
然後在表格的CurrentCellChanged事件中,動態顯示下拉框:
dataGrid1_CurrentCellChanged(.....)
{
comboBox1.Visible = false;
if(dataGrid1.CurrentCell.ColumnNumber = 要顯示下拉框的列號)
{
comboBox1.Bounds = dataGrid1.GetCurrentCellBounds();
comboBox1.Visible = true;
}
}

由于下拉框的Text和SelectedValue和表格中值是同步的,但在選擇了一拉框中的一個值後,該值的名稱部分不會自動填到表格中去,只是把代碼部分填過去了,因此,要在表格綁定的數據源中進行處理,我是這樣做的(假設表格的數據源為dataTable1):
dataTable1_ColumnChanged(.....)
{
if(e.Column.ColumnName = "表格中的代碼列的字段名")
e.Row["表格中的名稱列"] = comboBox1.Text;
}

另外,還要在表格的滾動事件中動態刷新下拉框的Bounds屬性,以及其它地方的完善。


這是我目前剛好編寫的一個這樣的程序的一些心得,希望能夠給你幫助。
不過,我在其中也遇到了很多苦惱的問題,比如我如何在程序中去控制表格自動處理的一些异常問題,如違反約束規則時的提示、對表格內正在編輯或新增狀態中的行,如何讓這行結束編輯狀態或新增到數據表中,即對BeginEdit()和EndEdit()如何去靈活運用?
Bluclyf 2003-10-10
  • 打赏
  • 举报
回复
很着急的。大家多帮助。谢谢。winform中怎么做啊。
LoveRose 2003-10-10
  • 打赏
  • 举报
回复
这是在asp.net中的datagrid实现的,它是作为webcontrol的
但是在winform里面的datagrid跟webcontrol不一样
想学习一下在winform里怎么实现datagrid绑定控件的
高手指点一下。
changezhong 2003-10-10
  • 打赏
  • 举报
回复
给你个例子
private void datagridNewComerList_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
datagridNewComerList.EditItemIndex=e.Item.ItemIndex;
bindGrid();//绑定之后再对可编辑状态的控件进行操作,否则会找不到对象的
ListItem objListItem = new ListItem("-- Select Team --","0");
DropDownList ddl_CName=new DropDownList() ;
ddl_CName=(DropDownList)datagridNewComerList.Items[(int)e.Item.ItemIndex].Cells[2].Controls[1];
ddl_CName.Items.Insert(0,objListItem);
TeamMaintenance objTeamMaintenance=new TeamMaintenance();
DataTable dt=objTeamMaintenance.GetTeamData("").Tables[0];
for(int i=0;i<dt.Rows.Count;i++)
{
string strID=dt.Rows[i][0].ToString().Trim();
string strName=dt.Rows[i][1].ToString().Trim();
ListItem obj_ListItem = new ListItem(strName,strID);
ddl_CName.Items.Insert(i+1,obj_ListItem);
}

}
LoveRose 2003-10-10
  • 打赏
  • 举报
回复
想在datagrid添加下拉框控件,asp.net中的datagrid可以实现
但是在winform里的datagrid我还不知道怎么实现
changezhong 2003-10-10
  • 打赏
  • 举报
回复
用模版列实现
wideroad 2003-10-10
  • 打赏
  • 举报
回复
在winform中应该和Webform中的情形没多大区别

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧