C#中WinForm下datagrid中实现Datetimepicker日期控件---类源码
1public class DataGridTimePickerColumn : DataGridColumnStyle
2 {
3 //这里增加需要被DataGridColumnStyle承载的控件,这里用的是一个
4 //DateTimePicker,日期控件,其他的控件类似
5 private DateTimePicker myDateTimePicker = new DateTimePicker();
6 //isEditing属性用于跟踪用户是否在宿主控件中编辑了其中的数据。
7 private bool isEditing;
8
9 //构造函数
10 public DataGridTimePickerColumn() : base()
11 {
12 myDateTimePicker.Visible = false;
13 myDateTimePicker.Format=DateTimePickerFormat.Short ;
14 }
15 ///
16 /// 此方法必须重载,Abort将启动一个请求来中断编辑过程。
17 ///
18 /// 当前中断的行号
19 protected override void Abort(int rowNum)
20 {
21 isEditing = false;
22 myDateTimePicker.ValueChanged -=new EventHandler(TimePickerValueChanged);
23 Invalidate();
24 }
25 ///
26 /// 此方法必须被重载,而且必须返回2个状态,也就是true或者false,返回false的时候
27 /// DataGrid就会用到Abort
28 ///
29 /// 实际上是一个BindManagerBase
30 /// 当前提交的行号
31 ///
32 protected override bool Commit(CurrencyManager dataSource, int rowNum)
33 {
34 myDateTimePicker.Bounds = Rectangle.Empty; //表示其属性未被初始化的 Rectangle 结构。
35
36 myDateTimePicker.ValueChanged -= new EventHandler(TimePickerValueChanged);
37
38 if (!isEditing)
39 return true;
40
41 isEditing = false;
42
43 try
44 {
45 DateTime dtValue = myDateTimePicker.Value;
46 SetColumnValueAtRow(dataSource, rowNum, dtValue);
47 }
48 catch (Exception)
49 {
50 Abort(rowNum);
51 return false;
52 }
53 Invalidate();
54 return true;
55 }
56 ///
57 /// 在派生类中被重写时,将准备一个将要进行编辑的单元格。
58 /// 通常,Edit 方法将控件定位到网格上要编辑的单元格的位置。
59 ///
60 /// DataGridColumnStyle的CurrencyManager,管理 Binding 对象的列表
61 /// 此列中所编辑的行的行号
62 /// 控件将被放置在其中
63 /// 指示该列是否为只读的列的值。如果该值是只读,则为 true;否则为 false
64 /// 控件中将显示的文本
65 /// 指示该单元格是否可见的值。如果该单元格可见,则为 true;否则为 false
66 protected override void Edit(
67 CurrencyManager source,
68 int rowNum,
69 Rectangle bounds,
70 bool readOnly,
71 string instantText,
72 bool cellIsVisible)
73 {
74 DateTime dtValue;
75
76 object obj = GetColumnValueAtRow(source, rowNum);
77 if (obj.GetType().ToString()=="System.DateTime")
78 {
79 dtValue = (DateTime)obj;
80 }
81 else
82 {
83 dtValue=DateTime.Now;
84 }
85
86 if (cellIsVisible)
87 {
88 myDateTimePicker.Bounds=new Rectangle(bounds.X+2,bounds.Y+2,bounds.Width-4,bounds.Height-4);
89 myDateTimePicker.Value = dtValue;
90 myDateTimePicker.Visible = true;
91 //挂接一个事件,就是承载的控件的变量发生变化的时候发生的事件
92 //在此事件的方法中主要是改变编辑的状态以及调用基类的方法ColumnStartedEditing
93 //这个方法用来通知DataGrid开始进入编辑状态
94 myDateTimePicker.ValueChanged +=new EventHandler(TimePickerValueChanged);
95 }
96 else
97 {
98 myDateTimePicker.Value = dtValue;
99 myDateTimePicker.Visible = false;
100 }
101
102 if (myDateTimePicker.Visible)
103 DataGridTableStyle.DataGrid.Invalidate(bounds);
104 }
105 protected override Size GetPreferredSize(Graphics g, object value)
106 {
107 return new Size(100, myDateTimePicker.PreferredHeight + 2);
108 }
109 protected override int GetMinimumHeight()
110 {
111 return myDateTimePicker.PreferredHeight + 2;
112 }
113
114 protected override int GetPreferredHeight(Graphics g,
115 object value)
116 {
117 return myDateTimePicker.PreferredHeight + 2;
118 }
119 //重载之一,一个简单的版本,其他没有涉及到的参数采用了默认值
120 protected override void Paint(Graphics g,
121 Rectangle bounds,
122 CurrencyManager source,
123 int rowNum)
124 {
125 Paint(g, bounds, source, rowNum, false);
126 }
127 //重载之二,一个简单的版本,其他没有涉及到的参数采用了默认值
128 protected override void Paint(
129 Graphics g,
130 Rectangle bounds,
131 CurrencyManager source,
132 int rowNum,
133 bool alignToRight)
134 {
135 Paint(
136 g,bounds,
137 source,
138 rowNum,
139 Brushes.Red,
140 Brushes.Blue,
141 alignToRight);
142 }
143 ///
144 /// 此方法必须重载,而且,这个方法是一个全面的方法,上面2个方法都是重载的这个方法
145 /// 此方法应该是在所承载的控件离开DataGrid之后在DataGrid中写入其中内容的方法
146 ///
147 ///
148 ///
149 ///
150 ///
151 ///
152 ///
153 ///
154 protected override void Paint(
155 Graphics g,
156 Rectangle bounds,
157 CurrencyManager source,
158 int rowNum,
159 Brush backBrush,
160 Brush foreBrush,
161 bool alignToRight)
162 {
163 Rectangle rect = bounds;
164 g.FillRectangle(backBrush,rect);
165 rect.Offset(0, 2);
166 rect.Height -= 2;
167
168 DateTime dtValue;
169 object obj = GetColumnValueAtRow(source, rowNum);
170 if (obj.GetType().ToString()=="System.DateTime")
171 {
172 dtValue = (DateTime)obj;
173 g.DrawString(dtValue.ToString("D"),this.DataGridTableStyle.DataGrid.Font,foreBrush, rect);
174
175 }
176 else
177 {
178 //dtValue=(DateTime)(object)String.Empty;
179 g.DrawString("",this.DataGridTableStyle.DataGrid.Font,foreBrush, rect);
180
181 }
182
183 }
184 ///
185 /// 将要承载的控件关联到DataGrid上
186 ///
187 ///
188 protected override void SetDataGridInColumn(DataGrid dgValue)
189 {
190 base.SetDataGridInColumn(dgValue);
191 if (myDateTimePicker.Parent != null)
192 {
193 myDateTimePicker.Parent.Controls.Remove(myDateTimePicker);
194 }
195 if (dgValue != null)
196 {
197 dgValue.Controls.Add(myDateTimePicker);
198 }
199 }
200 ///
201 /// 被承载的控件的内容发生变化的时候表明用户进行了编辑,此时执行这个事件处理函数
202 ///
203 ///
204 ///
205 private void TimePickerValueChanged(object sender, EventArgs e)
206 {
207 this.isEditing = true;
208 //通知DataGrid已经开始编辑这一列,其中的参数是需要承载的控件
209 base.ColumnStartedEditing(myDateTimePicker);
210 }
211}
2 {
3 //这里增加需要被DataGridColumnStyle承载的控件,这里用的是一个
4 //DateTimePicker,日期控件,其他的控件类似
5 private DateTimePicker myDateTimePicker = new DateTimePicker();
6 //isEditing属性用于跟踪用户是否在宿主控件中编辑了其中的数据。
7 private bool isEditing;
8
9 //构造函数
10 public DataGridTimePickerColumn() : base()
11 {
12 myDateTimePicker.Visible = false;
13 myDateTimePicker.Format=DateTimePickerFormat.Short ;
14 }
15 ///
16 /// 此方法必须重载,Abort将启动一个请求来中断编辑过程。
17 ///
18 /// 当前中断的行号
19 protected override void Abort(int rowNum)
20 {
21 isEditing = false;
22 myDateTimePicker.ValueChanged -=new EventHandler(TimePickerValueChanged);
23 Invalidate();
24 }
25 ///
26 /// 此方法必须被重载,而且必须返回2个状态,也就是true或者false,返回false的时候
27 /// DataGrid就会用到Abort
28 ///
29 /// 实际上是一个BindManagerBase
30 /// 当前提交的行号
31 ///
32 protected override bool Commit(CurrencyManager dataSource, int rowNum)
33 {
34 myDateTimePicker.Bounds = Rectangle.Empty; //表示其属性未被初始化的 Rectangle 结构。
35
36 myDateTimePicker.ValueChanged -= new EventHandler(TimePickerValueChanged);
37
38 if (!isEditing)
39 return true;
40
41 isEditing = false;
42
43 try
44 {
45 DateTime dtValue = myDateTimePicker.Value;
46 SetColumnValueAtRow(dataSource, rowNum, dtValue);
47 }
48 catch (Exception)
49 {
50 Abort(rowNum);
51 return false;
52 }
53 Invalidate();
54 return true;
55 }
56 ///
57 /// 在派生类中被重写时,将准备一个将要进行编辑的单元格。
58 /// 通常,Edit 方法将控件定位到网格上要编辑的单元格的位置。
59 ///
60 /// DataGridColumnStyle的CurrencyManager,管理 Binding 对象的列表
61 /// 此列中所编辑的行的行号
62 /// 控件将被放置在其中
63 /// 指示该列是否为只读的列的值。如果该值是只读,则为 true;否则为 false
64 /// 控件中将显示的文本
65 /// 指示该单元格是否可见的值。如果该单元格可见,则为 true;否则为 false
66 protected override void Edit(
67 CurrencyManager source,
68 int rowNum,
69 Rectangle bounds,
70 bool readOnly,
71 string instantText,
72 bool cellIsVisible)
73 {
74 DateTime dtValue;
75
76 object obj = GetColumnValueAtRow(source, rowNum);
77 if (obj.GetType().ToString()=="System.DateTime")
78 {
79 dtValue = (DateTime)obj;
80 }
81 else
82 {
83 dtValue=DateTime.Now;
84 }
85
86 if (cellIsVisible)
87 {
88 myDateTimePicker.Bounds=new Rectangle(bounds.X+2,bounds.Y+2,bounds.Width-4,bounds.Height-4);
89 myDateTimePicker.Value = dtValue;
90 myDateTimePicker.Visible = true;
91 //挂接一个事件,就是承载的控件的变量发生变化的时候发生的事件
92 //在此事件的方法中主要是改变编辑的状态以及调用基类的方法ColumnStartedEditing
93 //这个方法用来通知DataGrid开始进入编辑状态
94 myDateTimePicker.ValueChanged +=new EventHandler(TimePickerValueChanged);
95 }
96 else
97 {
98 myDateTimePicker.Value = dtValue;
99 myDateTimePicker.Visible = false;
100 }
101
102 if (myDateTimePicker.Visible)
103 DataGridTableStyle.DataGrid.Invalidate(bounds);
104 }
105 protected override Size GetPreferredSize(Graphics g, object value)
106 {
107 return new Size(100, myDateTimePicker.PreferredHeight + 2);
108 }
109 protected override int GetMinimumHeight()
110 {
111 return myDateTimePicker.PreferredHeight + 2;
112 }
113
114 protected override int GetPreferredHeight(Graphics g,
115 object value)
116 {
117 return myDateTimePicker.PreferredHeight + 2;
118 }
119 //重载之一,一个简单的版本,其他没有涉及到的参数采用了默认值
120 protected override void Paint(Graphics g,
121 Rectangle bounds,
122 CurrencyManager source,
123 int rowNum)
124 {
125 Paint(g, bounds, source, rowNum, false);
126 }
127 //重载之二,一个简单的版本,其他没有涉及到的参数采用了默认值
128 protected override void Paint(
129 Graphics g,
130 Rectangle bounds,
131 CurrencyManager source,
132 int rowNum,
133 bool alignToRight)
134 {
135 Paint(
136 g,bounds,
137 source,
138 rowNum,
139 Brushes.Red,
140 Brushes.Blue,
141 alignToRight);
142 }
143 ///
144 /// 此方法必须重载,而且,这个方法是一个全面的方法,上面2个方法都是重载的这个方法
145 /// 此方法应该是在所承载的控件离开DataGrid之后在DataGrid中写入其中内容的方法
146 ///
147 ///
148 ///
149 ///
150 ///
151 ///
152 ///
153 ///
154 protected override void Paint(
155 Graphics g,
156 Rectangle bounds,
157 CurrencyManager source,
158 int rowNum,
159 Brush backBrush,
160 Brush foreBrush,
161 bool alignToRight)
162 {
163 Rectangle rect = bounds;
164 g.FillRectangle(backBrush,rect);
165 rect.Offset(0, 2);
166 rect.Height -= 2;
167
168 DateTime dtValue;
169 object obj = GetColumnValueAtRow(source, rowNum);
170 if (obj.GetType().ToString()=="System.DateTime")
171 {
172 dtValue = (DateTime)obj;
173 g.DrawString(dtValue.ToString("D"),this.DataGridTableStyle.DataGrid.Font,foreBrush, rect);
174
175 }
176 else
177 {
178 //dtValue=(DateTime)(object)String.Empty;
179 g.DrawString("",this.DataGridTableStyle.DataGrid.Font,foreBrush, rect);
180
181 }
182
183 }
184 ///
185 /// 将要承载的控件关联到DataGrid上
186 ///
187 ///
188 protected override void SetDataGridInColumn(DataGrid dgValue)
189 {
190 base.SetDataGridInColumn(dgValue);
191 if (myDateTimePicker.Parent != null)
192 {
193 myDateTimePicker.Parent.Controls.Remove(myDateTimePicker);
194 }
195 if (dgValue != null)
196 {
197 dgValue.Controls.Add(myDateTimePicker);
198 }
199 }
200 ///
201 /// 被承载的控件的内容发生变化的时候表明用户进行了编辑,此时执行这个事件处理函数
202 ///
203 ///
204 ///
205 private void TimePickerValueChanged(object sender, EventArgs e)
206 {
207 this.isEditing = true;
208 //通知DataGrid已经开始编辑这一列,其中的参数是需要承载的控件
209 base.ColumnStartedEditing(myDateTimePicker);
210 }
211}