最近有个难题,比较棘手,是关于datagrid的每一行绑定的combobox的下拉列表有可能会不一样,这该如何搞定 vs2003(winform)
DataGridComboBoxColumn类
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又太复杂,唉,有哪位高手能帮我指点一下呢?
谢谢!