using System;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Data;
namespace Microsoft.Msdn.Article.DataGridColumnStyles.DownloadManager {
public class DataGridComboBoxColumn : DataGridColumnStyle {
private ComboBox m_comboBox;
private int m_previouslyEditedCellRow;
private DataGridColumnStylePadding m_padding;
private string displayMember,valueMember;
public DataGridComboBoxColumn(ComboBox m_comboBox,string displayMember,string valueMember) : base() {
this.m_comboBox = m_comboBox;
this.displayMember = displayMember;
this.valueMember = valueMember;
//m_comboBox = new ComboBox();
this.m_comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
this.m_comboBox.Visible = false;
this.m_comboBox.SizeChanged += new EventHandler( ComboBox_SizeChanged );
this.ControlSize = m_comboBox.Size;
this.Padding = new DataGridColumnStylePadding( 0, 0, 0, 0 );
this.Width = this.GetPreferredSize( null, null ).Width;
//this.m_comboBox.SelectedIndex = 0;
}
public ComboBox ComboBox {
get { return m_comboBox; }
}
public DataGridColumnStylePadding Padding {
get { return m_padding; }
set { m_padding = value; }
}
public Size ControlSize {
get { return m_comboBox.Size; }
set { m_comboBox.Size = value; }
}
protected override void Abort(int rowNum) {
// reset combobox
m_comboBox.Visible = false;
}
protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible) {
Debug.WriteLine( "ComboBox Edit" );
// get cursor coordinates
Point p = this.DataGridTableStyle.DataGrid.PointToClient( Cursor.Position );
// get control bounds
Rectangle controlBounds = this.GetControlBounds( bounds );
// get cursor bounds
Rectangle cursorBounds = new Rectangle( p.X, p.Y, 1, 1 );
m_comboBox.SelectedIndex = ( int ) this.GetColumnValueAtRow( source, rowNum );
Debug.WriteLine( "SelectedItem: " + m_comboBox.SelectedIndex );
m_comboBox.Location = new Point( controlBounds.X, controlBounds.Y );
m_comboBox.Visible = true;
if ( cursorBounds.IntersectsWith( controlBounds ) ) {
m_comboBox.DroppedDown = true;
}
m_previouslyEditedCellRow = rowNum;
}
protected override bool Commit( CurrencyManager dataSource, int rowNum ) {
if ( m_previouslyEditedCellRow == rowNum ) {
this.SetColumnValueAtRow( dataSource, rowNum, m_comboBox.SelectedIndex );
}
m_comboBox.Visible = false;
return true;
}
protected override void SetDataGridInColumn( DataGrid value ) {
base.SetDataGridInColumn( value );
if ( !value.Controls.Contains( m_comboBox ) ) {
value.Controls.Add( m_comboBox );
}
}
protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight) {
g.FillRectangle( new SolidBrush( Color.White ), bounds );
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
Rectangle controlBounds = this.GetControlBounds( bounds );
int colValue = ( int ) this.GetColumnValueAtRow( source, rowNum );
string selectedItem = (((DataRowView)m_comboBox.Items[ colValue ])[displayMember]).ToString();
Rectangle textRegion = new Rectangle(
controlBounds.X + 1,
controlBounds.Y + 4,
controlBounds.Width - 3,
( int ) g.MeasureString( selectedItem, m_comboBox.Font ).Height );
g.DrawString( selectedItem, m_comboBox.Font, foreBrush, textRegion, sf );
ControlPaint.DrawBorder3D( g, controlBounds, Border3DStyle.Sunken );
Rectangle buttonBounds = controlBounds;
buttonBounds.Inflate( -2, -2 );
ControlPaint.DrawComboButton(
g,
buttonBounds.X + ( controlBounds.Width - 20 ),
buttonBounds.Y,
16,
17,
ButtonState.Normal );
}
private void ComboBox_SizeChanged(object sender, EventArgs e) {
this.ControlSize = m_comboBox.Size;
this.Width = this.GetPreferredSize( null, null ).Width;
this.Invalidate();
}
private Rectangle GetControlBounds( Rectangle cellBounds ) {
Rectangle controlBounds = new Rectangle(
cellBounds.X + this.Padding.Left,
cellBounds.Y + this.Padding.Top,
this.ControlSize.Width,
this.ControlSize.Height );
return controlBounds;
}
#region The rest of the DataGridColumnStyle methods
protected override int GetMinimumHeight() {
return GetPreferredHeight( null, null );
}
protected override int GetPreferredHeight(System.Drawing.Graphics g, object value) {
return this.ControlSize.Height + this.Padding.Top + this.Padding.Bottom;
}
protected override System.Drawing.Size GetPreferredSize(System.Drawing.Graphics g, object value) {
int width = this.ControlSize.Width + this.Padding.Left + this.Padding.Right;
int height = this.ControlSize.Height + this.Padding.Top + this.Padding.Bottom;
return new Size( width, height );
}
protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, CurrencyManager source, int rowNum) {
this.Paint( g, bounds, source, rowNum, false );
}
protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) {
this.Paint( g, bounds, source, rowNum, Brushes.White, Brushes.Black, false );
}
#endregion The rest of the DataGridColumnStyle methods
}
}
DataGridColumnStylePadding类
using System;
using System.ComponentModel;
namespace Microsoft.Msdn.Article.DataGridColumnStyles {
public class DataGridColumnStylePadding {
int m_left;
int m_right;
int m_top;
int m_bottom;
public int Left {
get { return m_left; }
set { m_left = value; }
}
public int Right {
get { return m_right; }
set { m_right = value; }
}
public int Top {
get { return m_top; }
set { m_top = value; }
}
public int Bottom {
get { return m_bottom; }
set { m_bottom = value; }
}
public void SetPadding( int padValue ) {
m_left = padValue;
m_right = padValue;
m_top = padValue;
m_bottom = padValue;
}
public void SetPadding( int top, int right, int bottom, int left ) {
UpdatePaddingValues( top, right, bottom, left );
}
public DataGridColumnStylePadding( int padValue ) {
this.SetPadding( padValue );
}
public DataGridColumnStylePadding( int top, int right, int bottom, int left ) {
UpdatePaddingValues( top, right, bottom, left );
}
private void UpdatePaddingValues( int top, int right, int bottom, int left ) {
m_top = top;
m_right = right;
m_bottom = bottom;
m_left = left;
}
}
}
以上是我用的微软的一个例子,且修改为可以绑定数据源的combobox
datagrid里建立一个此类型的列,将comboBox加入到此列,并绑定数据源
如果说下拉框都相同,很简单可以实现,但是事实是一个调查表,所以选项肯定可能都相同,我现在都快要放弃DataGrid了,都想用控件自动生成一张由label,和下拉的调查表了,微软的DataGrid好难实现复杂功能,由于掌握得比较肤浅,所以无法驾驭,但是DevExpress的xTraGrid又太复杂,唉,有哪位高手能帮我指点一下呢?
谢谢!
13 个解决方案
#1
可以判断一下是点击的哪一行,然后再根据条件给combbox加不同的items
#2
如果数据不相同,是否合绑定的列有什么关系
#3
三只熊熊 :你的方法我想过,我传给那个列的ComboBox是一个实例,点击一个变化的话,都会变的啊,其它行的选项不就又变化了?
Knight94(愚翁) ( )
比如说第一行我的下拉应该是
|很好|
|不错|
|一般|
|差|
第二行是
|严重|
|还行|
|不行|
Knight94(愚翁) ( )
比如说第一行我的下拉应该是
|很好|
|不错|
|一般|
|差|
第二行是
|严重|
|还行|
|不行|
#4
一年前做过,现在记不得了,呵呵
#5
楼上的哥们难道也是点击一行再对DataView重新绑定?然后把选中的值存在隐藏的Column里?
我一开始就是这么想的,但是觉得微软搞这么个半成品给我们用,是比较郁闷的。。
我一开始就是这么想的,但是觉得微软搞这么个半成品给我们用,是比较郁闷的。。
#6
关注。。。学习。。。帮你顶。。。
#7
其实这不是微软的问题,就你所给出的例子,是把不同组合数据用同一列来表明,这首先在数据库设计上连范式一都满足不了。
如果你的combox列和某些信息与其他表有外键关联信息的话,是可以做的。
如果你的combox列和某些信息与其他表有外键关联信息的话,是可以做的。
#8
Knight94(愚翁)
是这样子的。
答案组表
|QID| |QName|
1 答案组1
2 答案组2
选项组表
|id| |QID| |AName| |Percent|
1 1 很好 80%
2 1 不错 60%
3 1 一般 40%
4 1 差 20%
5 2 严重 100%
6 2 还行 60%
7 2 不行 20%
DataTable中有一列是QID,如果说是直接显示选项组还是很简单的,关键怎么根据行不同,下拉列表的值也不同呢,对DataGrid了解还很肤浅,所以要提这个问题了,微软那个例子的确给我改成一个ComboBox实例来显示不同的数值肯定是不行的,那么要怎么改呢?
是这样子的。
答案组表
|QID| |QName|
1 答案组1
2 答案组2
选项组表
|id| |QID| |AName| |Percent|
1 1 很好 80%
2 1 不错 60%
3 1 一般 40%
4 1 差 20%
5 2 严重 100%
6 2 还行 60%
7 2 不行 20%
DataTable中有一列是QID,如果说是直接显示选项组还是很简单的,关键怎么根据行不同,下拉列表的值也不同呢,对DataGrid了解还很肤浅,所以要提这个问题了,微软那个例子的确给我改成一个ComboBox实例来显示不同的数值肯定是不行的,那么要怎么改呢?
#9
to DataTable中有一列是QID,如果说是直接显示选项组还是很简单的,关键怎么根据行不同,下拉列表的值也不同呢,对DataGrid了解还很肤浅,所以要提这个问题了,微软那个例子的确给我改成一个ComboBox实例来显示不同的数值肯定是不行的,那么要怎么改呢
你不是写了个了DataGridComboBoxColumn,那么在获得焦点的时候,对combobox进行重新绑定不就行了,例如:
DataView dv = new DataView( yourDataTable, rowfilter, null, ... );
//use "dv" to bind your combobox
你不是写了个了DataGridComboBoxColumn,那么在获得焦点的时候,对combobox进行重新绑定不就行了,例如:
DataView dv = new DataView( yourDataTable, rowfilter, null, ... );
//use "dv" to bind your combobox
#10
你不是写了个了DataGridComboBoxColumn,那么在获得焦点的时候,对combobox进行重新绑定不就行了,例如:
DataView dv = new DataView( yourDataTable, rowfilter, null, ... );
//use "dv" to bind your combobox
==============
获得焦点时重新绑定会影响其它的行里的combobox啊。我本来选择好的其它行的ComboBox不是跟着变化了吗?
DataView dv = new DataView( yourDataTable, rowfilter, null, ... );
//use "dv" to bind your combobox
==============
获得焦点时重新绑定会影响其它的行里的combobox啊。我本来选择好的其它行的ComboBox不是跟着变化了吗?
#11
to 获得焦点时重新绑定会影响其它的行里的combobox啊。我本来选择好的其它行的ComboBox不是跟着变化了吗?
谁获的焦点,根据条件设置新的combobox数据,没获得焦点,当然不会进行改变。
谁获的焦点,根据条件设置新的combobox数据,没获得焦点,当然不会进行改变。
#12
我原来只能绑定一个死的DataView,我试试RowFilter。
#13
遇到同样的问题。
关注。
关注。
#1
可以判断一下是点击的哪一行,然后再根据条件给combbox加不同的items
#2
如果数据不相同,是否合绑定的列有什么关系
#3
三只熊熊 :你的方法我想过,我传给那个列的ComboBox是一个实例,点击一个变化的话,都会变的啊,其它行的选项不就又变化了?
Knight94(愚翁) ( )
比如说第一行我的下拉应该是
|很好|
|不错|
|一般|
|差|
第二行是
|严重|
|还行|
|不行|
Knight94(愚翁) ( )
比如说第一行我的下拉应该是
|很好|
|不错|
|一般|
|差|
第二行是
|严重|
|还行|
|不行|
#4
一年前做过,现在记不得了,呵呵
#5
楼上的哥们难道也是点击一行再对DataView重新绑定?然后把选中的值存在隐藏的Column里?
我一开始就是这么想的,但是觉得微软搞这么个半成品给我们用,是比较郁闷的。。
我一开始就是这么想的,但是觉得微软搞这么个半成品给我们用,是比较郁闷的。。
#6
关注。。。学习。。。帮你顶。。。
#7
其实这不是微软的问题,就你所给出的例子,是把不同组合数据用同一列来表明,这首先在数据库设计上连范式一都满足不了。
如果你的combox列和某些信息与其他表有外键关联信息的话,是可以做的。
如果你的combox列和某些信息与其他表有外键关联信息的话,是可以做的。
#8
Knight94(愚翁)
是这样子的。
答案组表
|QID| |QName|
1 答案组1
2 答案组2
选项组表
|id| |QID| |AName| |Percent|
1 1 很好 80%
2 1 不错 60%
3 1 一般 40%
4 1 差 20%
5 2 严重 100%
6 2 还行 60%
7 2 不行 20%
DataTable中有一列是QID,如果说是直接显示选项组还是很简单的,关键怎么根据行不同,下拉列表的值也不同呢,对DataGrid了解还很肤浅,所以要提这个问题了,微软那个例子的确给我改成一个ComboBox实例来显示不同的数值肯定是不行的,那么要怎么改呢?
是这样子的。
答案组表
|QID| |QName|
1 答案组1
2 答案组2
选项组表
|id| |QID| |AName| |Percent|
1 1 很好 80%
2 1 不错 60%
3 1 一般 40%
4 1 差 20%
5 2 严重 100%
6 2 还行 60%
7 2 不行 20%
DataTable中有一列是QID,如果说是直接显示选项组还是很简单的,关键怎么根据行不同,下拉列表的值也不同呢,对DataGrid了解还很肤浅,所以要提这个问题了,微软那个例子的确给我改成一个ComboBox实例来显示不同的数值肯定是不行的,那么要怎么改呢?
#9
to DataTable中有一列是QID,如果说是直接显示选项组还是很简单的,关键怎么根据行不同,下拉列表的值也不同呢,对DataGrid了解还很肤浅,所以要提这个问题了,微软那个例子的确给我改成一个ComboBox实例来显示不同的数值肯定是不行的,那么要怎么改呢
你不是写了个了DataGridComboBoxColumn,那么在获得焦点的时候,对combobox进行重新绑定不就行了,例如:
DataView dv = new DataView( yourDataTable, rowfilter, null, ... );
//use "dv" to bind your combobox
你不是写了个了DataGridComboBoxColumn,那么在获得焦点的时候,对combobox进行重新绑定不就行了,例如:
DataView dv = new DataView( yourDataTable, rowfilter, null, ... );
//use "dv" to bind your combobox
#10
你不是写了个了DataGridComboBoxColumn,那么在获得焦点的时候,对combobox进行重新绑定不就行了,例如:
DataView dv = new DataView( yourDataTable, rowfilter, null, ... );
//use "dv" to bind your combobox
==============
获得焦点时重新绑定会影响其它的行里的combobox啊。我本来选择好的其它行的ComboBox不是跟着变化了吗?
DataView dv = new DataView( yourDataTable, rowfilter, null, ... );
//use "dv" to bind your combobox
==============
获得焦点时重新绑定会影响其它的行里的combobox啊。我本来选择好的其它行的ComboBox不是跟着变化了吗?
#11
to 获得焦点时重新绑定会影响其它的行里的combobox啊。我本来选择好的其它行的ComboBox不是跟着变化了吗?
谁获的焦点,根据条件设置新的combobox数据,没获得焦点,当然不会进行改变。
谁获的焦点,根据条件设置新的combobox数据,没获得焦点,当然不会进行改变。
#12
我原来只能绑定一个死的DataView,我试试RowFilter。
#13
遇到同样的问题。
关注。
关注。