首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
iiprogram (68)
qdzx2008 (50)
goodboy1881 (14)
wangchinaking (58)
fancyhf (1)
harrymeng (41)
yjz0065 (113)
coofucoo (105)
Drate (69)
lphpc (30)
CSDN - 文档中心 - .NET 阅读:15213   评论: 10    参与评论
标题   DataGrid使用技巧(三)     选择自 dy_2000_abc 的 Blog
关键字   DataGrid,使用技巧
出处  

DataGrid使用技巧(三)

--------如何实现下拉列表

       有时候听有些朋友抱怨.NET的DataGrid不是很好用。就我个人的体会,DataGrid的功能非常强大,可以使我们随心所欲的完成各种各样的工作,可惜就是实现起来不够简单明了。我对平时经常碰到的一些问题积累了一些解决的方法,现在把它们总结一下供大家参考。
       比较经常碰到的一个问题是:在编辑单元格内容时我们希望出现这样的下拉列表,如图1所示:


图1

思路:
            1 写一个类comboForm表示下拉列表,类包含两个成员:Form窗体和DataGrid组件。
            2 写一个类NoKeyUpComboBox(继承ComboBox),目的是屏蔽WM_KEYUP消息,避免在按Tab键时出现问题。
            3 写一个继承于DataGridTextBoxColumn的类,命名为DataGridComboFormColumn。在类中加入一个ComboBox和一个comboForm,类实现下面几个功能:
            a 编辑单元格内容时显示组件NoKeyUpComboBox;
            b ComboBox下拉时显示下拉列表comboForm;
            c 鼠标点击下拉列表时,隐藏comboForm并将用户选定的内容写入单元格(当然,你也可以设置其他隐藏下拉列表的操作,比如按回车键);
            d 下拉列表comboForm不具有焦点时隐藏。

代码:           
//comboForm类:
 public class comboForm:Form
 {
  private DataGrid dataGrid;
  public DataGrid DataGrid
  {
   get {return dataGrid;}
   set {dataGrid=value;}
  }
  public comboForm()
  {
   this.FormBorderStyle=FormBorderStyle.None;
   this.StartPosition=FormStartPosition.Manual;
   dataGrid=new DataGrid();
   this.Controls.Add(dataGrid);
   dataGrid.Dock=DockStyle.Fill;
   dataGrid.CaptionVisible=false;
  }
 }

//NoKeyUpComboBox类:
public class NoKeyUpComboBox:ComboBox
 {
 const int WM_KEYUP=0x101;
  protected override void WndProc(ref Message msg)
  {
  if (msg.Msg==WM_KEYUP)
   return;
   base.WndProc(ref msg);
  }
 }

//DataGridComboFormColumn类:
 public class DataGridComboFormColumn:DataGridTextBoxColumn
 {
  private NoKeyUpComboBox comboBox;
  private CurrencyManager _source;
  private int rowNum;
  private comboForm frm;
  public comboForm Frm
  {
   get {return frm;}
  }
  //我们将使用Index属性表示单元格内容与下拉列表的第Index列的内容相联系
  private int index;
  public int Index
  {
   get {return index;}
   set {index=value;}
  }
  
  public DataGridComboFormColumn()
  {
  frm=new comboForm();
  comboBox=new NoKeyUpComboBox();
  frm.Deactivate+=new EventHandler(frm_deactive);
  frm.DataGrid.Click+=new EventHandler(grid_click);
  this.comboBox.DropDown+=new EventHandler(comboBox_dropDown);
  this.comboBox.Leave+=new EventHandler(comboBox_leave);
  }
  //comboBox不具有焦点时隐藏
  private void comboBox_leave(object sender,EventArgs e)
  {
  comboBox.Visible=false;
  }
  //下拉列表--Frm不具有焦点时隐藏
  private void frm_deactive(object sender,EventArgs e)
  {
  frm.Hide();
  comboBox.Visible=false;
  }
   //comboBox下拉时显示下拉列表--Frm
  private void comboBox_dropDown(object sender,EventArgs e)
  {
   //在这里您还可以根据下拉列表的长与宽是否超出屏幕设置下拉列表的位置
  frm.Left=comboBox.PointToScreen(new Point(0,comboBox.Height)).X;
  frm.Top=comboBox.PointToScreen(new Point(0,comboBox.Height)).Y;
  frm.Show();
  frm.BringToFront();
  }
  //点击下拉列表的DataGrid时,将选中的内容写入单元格并隐藏下拉列表--Frm
  private void grid_click(object sender,EventArgs e)
  {
  BindingManagerBase cm=frm.BindingContext[Frm.DataGrid.DataSource, frm.DataGrid.DataMember];
  comboBox.Text=((DataRowView)cm.Current)[index].ToString();
  this.TextBox.Text=((DataRowView)cm.Current)[index].ToString();
  frm.Hide();
  comboBox.Visible=false;
  this.SetColumnValueAtRow(_source,rowNum,this.TextBox.Text);
  }
  //重载Edit方法,使用comboBox代替TextBox
  protected override void Edit(CurrencyManager dataSource,int rowNum,Rectangle bounds,bool readOnly,string instanttext,bool cellVisible)
  {
   base.Edit(dataSource,rowNum,bounds,readOnly,instanttext,cellVisible);
   comboBox.Parent=this.TextBox.Parent;
   comboBox.Left=this.TextBox.Left-2;
   comboBox.Top=this.TextBox.Top-2;
   comboBox.Size=new Size(this.TextBox.Width,this.comboBox.Height);
   comboBox.Text=this.TextBox.Text;

   this.TextBox.Visible=false;
   comboBox.Visible=true;
   comboBox.BringToFront();
   comboBox.Focus();
   _source=dataSource;
   this.rowNum=rowNum;
  }
 }

      下面的例子说明了如何使用DataGridComboFrom类:
新建一个Windows 应用程序,加入SqlConnection,连接SQL数据库Northwind,加入下面代码。

private void Form1_Load(object sender, System.EventArgs e)
  {
  SqlDataAdapter da=new SqlDataAdapter("select ProductName from Products",this.sqlConnection1);
  DataSet ds=new DataSet();
   da.Fill(ds,"products");
   DataSet ds_Combo=new DataSet();
   da.SelectCommand=new SqlCommand("select ProductName,QuantityPerUnit,UnitPrice from Products",this.sqlConnection1);
   da.Fill(ds_Combo,"products");

   DataGridTableStyle dts=new DataGridTableStyle();
   dts.MappingName="products";
   myDataGridColumn col=new myDataGridColumn();
   col.MappingName="ProductName";
   col.Width=100;
   col.Index=0;
   col.HeaderText="ProductName";

   col.Frm.DataGrid.DataSource=ds_Combo;//设置下拉列表的数据源
   col.Frm.DataGrid.DataMember="products";
   dts.GridColumnStyles.Add(col);
   
   this.dataGrid1.TableStyles.Add(dts);
   this.dataGrid1.SetDataBinding(ds,"products");
  }


相关文章
对该文的评论
CSDN 网友 ( 2006-02-03)
用这个东东可以做年历吗?
CSDN 网友 ( 2005-11-10)
还行,我也做过类市的
CSDN 网友 ( 2005-10-16)
myDataGridColumn col=new myDataGridColumn();
应该换成:
DataGridComboFormColumn col=new DataGridComboFormColumn();
CSDN 网友 ( 2005-03-21)
好文章,先顶一下.虽然还每看,但看过(一)
CSDN 网友 ( 2005-01-24)
楼下的刚开始学编程吧?您不会连定义一个类都不会吧?
楼主这篇文章好!顶!