导航

可编辑的ListView控件

Posted on 2005-12-14 18:25  hcfalan  阅读(5523)  评论(4编辑  收藏  举报

      ListView控件是一个在Windows应用程序中使用频率比较高的一个,通常使用它来显示数据报表。很多情况下,我们不仅仅使用ListView来显示数据,还要求编辑其中的数据。但是.NET提供的ListView控件的编辑功能十分有限,只能编辑首列,编辑格式只能为文本框,等等,使用起来甚为不便。因此本人新写了一个类,扩充了其功能,客户程序员可以设置任何列的格式(只读,编辑状态下文本框,编辑状态下组合框),界面如图:
源代码在此下载:/Files/hcfalan/EditableListView.rar
摘录部分源代码如下:
  1/// <summary>
  2/// 列描述
  3/// </summary>

  4public class ALAN_ColumnHeader : ColumnHeader
  5{
  6    private ALAN_ListViewColumnStyle cs; //本列的风格
  7
  8    public ALAN_ColumnHeader() : base()
  9    {
 10        cs = ALAN_ListViewColumnStyle.ReadOnly;
 11    }

 12
 13    public ALAN_ColumnHeader(ALAN_ListViewColumnStyle _cs)
 14    {
 15        cs = _cs;
 16    }

 17
 18    public ALAN_ListViewColumnStyle ColumnStyle
 19    {
 20        get return cs; }
 21        set { cs = value;}
 22    }

 23}
;
 24
 25/// <summary>
 26/// 可编辑的ListView控件
 27/// </summary>

 28public class ALAN_EditListView : ListView 
 29{
 30
 31    private ListViewItem m_currentLVItem;     
 32
 33    private int m_nX=0;
 34
 35    private int m_nY=0;
 36
 37    private string m_strSubItemText ;
 38
 39    private int m_nSubItemSelected = 0 ; 
 40
 41    private ComboBox[] m_arrComboBoxes = new ComboBox[20];
 42
 43    private System.Windows.Forms.TextBox  editBox;
 44
 45    private Font m_fontComboBox;
 46
 47    private Font m_fontEdit;
 48
 49    private Color m_bgcolorComboBox;
 50
 51    private Color m_bgcolorEdit;
 52
 53
 54
 55    public ALAN_EditListView()
 56    {
 57
 58        editBox = new System.Windows.Forms.TextBox();
 59
 60        this.ComboBoxFont = this.Font;
 61
 62        this.EditFont = this.Font;
 63
 64    
 65
 66        this.EditBgColor = Color.LightBlue;
 67
 68        this.m_bgcolorComboBox = Color.LightBlue;
 69
 70        this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.SMKMouseDown);
 71
 72        this.DoubleClick += new System.EventHandler(this.SMKDoubleClick);
 73
 74        this.GridLines = true ;
 75
 76    
 77
 78        editBox.Size  = new System.Drawing.Size(0,0);
 79
 80        editBox.Location = new System.Drawing.Point(0,0);
 81
 82        this.Controls.AddRange(new System.Windows.Forms.Control[] {this.editBox});
 83
 84        editBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.EditOver);
 85
 86        editBox.LostFocus += new System.EventHandler(this.FocusOver);
 87
 88        editBox.AutoSize = true;
 89
 90        editBox.Font = this.EditFont;
 91
 92        editBox.BackColor = this.EditBgColor;
 93
 94        editBox.BorderStyle = BorderStyle.FixedSingle;
 95
 96        editBox.Hide();
 97
 98        editBox.Text = "";
 99
100    }

101
102
103
104    public Font ComboBoxFont
105    {
106
107        get return this.m_fontComboBox; }
108
109        set this.m_fontComboBox = value;}
110
111    }

112
113
114
115    public Color ComboBoxBgColor
116    {
117
118        get return this.m_bgcolorComboBox; }
119
120        set 
121
122        {
123
124            this.m_bgcolorComboBox = value;
125
126            for(int i=0; i<this.m_arrComboBoxes.Length; i++)
127
128            {
129
130                if (m_arrComboBoxes[i] != null)
131
132                    m_arrComboBoxes[i].BackColor = this.m_bgcolorComboBox;
133
134            }

135
136        }
      
137
138    }

139
140
141
142    public Font EditFont
143    {
144
145        get return this.m_fontEdit; }
146
147        set
148
149        {
150
151            this.m_fontEdit = value;
152
153            this.editBox.Font = this.m_fontEdit;
154
155        }

156
157    }

158
159
160
161    public Color EditBgColor
162    {
163
164        get return this.m_bgcolorEdit; }
165
166        set
167
168        {
169
170            this.m_bgcolorEdit = value;
171
172            this.editBox.BackColor = this.m_bgcolorEdit;
173
174        }

175
176    }

177
178
179
180    public void SetColumn(int columnIndex, ALAN_ListViewColumnStyle cs)
181    {
182
183        if (columnIndex<0 || columnIndex>this.Columns.Count)
184
185            throw new Exception("Column index is out of range");
186
187        ((ALAN_ColumnHeader)Columns[columnIndex]).ColumnStyle = cs;
188
189    }

190
191
192
193    public void BoundListToColumn(int columnIndex, string[] items)
194    {
195
196        if (columnIndex<0 || columnIndex>this.Columns.Count)
197
198            throw new Exception("Column index is out of range");
199
200        if ( ((ALAN_ColumnHeader)Columns[columnIndex]).ColumnStyle != ALAN_ListViewColumnStyle.ComboBox)
201
202            throw new Exception("Column should be ComboBox style");
203
204
205
206        ComboBox newbox = new ComboBox();
207
208        for(int i=0; i<items.Length; i++)
209
210            newbox.Items.Add(items[i]);
211
212        newbox.Size  = new System.Drawing.Size(0,0);
213
214        newbox.Location = new System.Drawing.Point(0,0);
215
216        this.Controls.AddRange(new System.Windows.Forms.Control[] {newbox});         
217
218        newbox.SelectedIndexChanged += new System.EventHandler(this.CmbSelected);
219
220        newbox.LostFocus += new System.EventHandler(this.CmbFocusOver);
221
222        newbox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.CmbKeyPress);
223
224        newbox.Font = this.ComboBoxFont;
225
226        newbox.BackColor = this.ComboBoxBgColor;
227
228        newbox.DropDownStyle = ComboBoxStyle.DropDownList;
229
230        newbox.Hide();
231
232        this.m_arrComboBoxes[columnIndex] = newbox;
233
234    }

235
236
237
238    private void CmbKeyPress(object sender , System.Windows.Forms.KeyPressEventArgs e)
239    {
240
241        ComboBox cmbBox = (ComboBox)sender;
242
243        if ( e.KeyChar == 13 || e.KeyChar == 27 ) //CR or ESC press
244
245        {
246
247            cmbBox.Hide();
248
249        }

250
251    }

252
253
254
255    private void CmbSelected(object sender , System.EventArgs e)
256    {
257
258        ComboBox cmbBox = (ComboBox)sender;
259
260        int sel = cmbBox.SelectedIndex;
261
262        if ( sel >= 0 )
263
264        {
265
266            string itemSel = cmbBox.Items[sel].ToString();
267
268            m_currentLVItem.SubItems[m_nSubItemSelected].Text = itemSel;
269
270        }

271
272    }

273
274
275
276    private void CmbFocusOver(object sender , System.EventArgs e)
277    {
278
279        ComboBox cmbBox = (ComboBox)sender;
280
281        cmbBox.Hide() ;
282
283    }

284
285
286
287    private void EditOver(object sender, System.Windows.Forms.KeyPressEventArgs e)
288    {
289
290        if ( e.KeyChar == 13 ) 
291
292        {
293
294            m_currentLVItem.SubItems[m_nSubItemSelected].Text = editBox.Text;
295
296            editBox.Hide();
297
298        }

299
300
301
302        if ( e.KeyChar == 27 ) 
303
304            editBox.Hide();
305
306    }

307
308
309
310    private void FocusOver(object sender, System.EventArgs e)
311    {
312
313        m_currentLVItem.SubItems[m_nSubItemSelected].Text = editBox.Text;
314
315        editBox.Hide();
316
317    }

318
319
320
321    public  void SMKDoubleClick(object sender, System.EventArgs e)
322    {
323
324        // Check the subitem clicked .
325
326        int nStart = m_nX ; //current mouse down X position
327
328        int spos = 0 ; 
329
330        int epos = this.Columns[0].Width ;
331
332        for ( int i=0; i < this.Columns.Count ; i++)
333
334        {
335
336            if ( nStart > spos && nStart < epos ) 
337
338            {
339
340                m_nSubItemSelected = i ;
341
342                break
343
344            }

345
346        
347
348            spos = epos ; 
349
350            epos += this.Columns[i].Width;
351
352        }

353
354    
355
356        m_strSubItemText = m_currentLVItem.SubItems[m_nSubItemSelected].Text ;
357
358
359
360        ALAN_ColumnHeader column = (ALAN_ColumnHeader)Columns[m_nSubItemSelected];
361
362        if ( column.ColumnStyle == ALAN_ListViewColumnStyle.ComboBox ) 
363
364        {
365
366            ComboBox cmbBox = this.m_arrComboBoxes[m_nSubItemSelected];
367
368            if (cmbBox == null)
369
370                throw new Exception("The ComboxBox control bind to current column is null");
371
372            Rectangle r = new Rectangle(spos , m_currentLVItem.Bounds.Y , epos , m_currentLVItem.Bounds.Bottom);
373
374            cmbBox.Size  = new System.Drawing.Size(epos - spos , m_currentLVItem.Bounds.Bottom-m_currentLVItem.Bounds.Top);
375
376            cmbBox.Location = new System.Drawing.Point(spos , m_currentLVItem.Bounds.Y);
377
378            cmbBox.Show() ;
379
380            cmbBox.Text = m_strSubItemText;
381
382            cmbBox.SelectAll() ;
383
384            cmbBox.Focus();
385
386        }

387
388        if ( column.ColumnStyle == ALAN_ListViewColumnStyle.EditBox ) 
389
390        {
391
392            Rectangle r = new Rectangle(spos , m_currentLVItem.Bounds.Y , epos , m_currentLVItem.Bounds.Bottom);
393
394            editBox.Size  = new System.Drawing.Size(epos - spos , m_currentLVItem.Bounds.Height);
395
396            editBox.Location = new System.Drawing.Point(spos , m_currentLVItem.Bounds.Y);
397
398            editBox.Show() ;
399
400            editBox.Text = m_strSubItemText;
401
402            editBox.SelectAll() ;
403
404            editBox.Focus();
405
406        }

407
408    }

409
410
411
412    public void SMKMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
413    {
414
415        m_currentLVItem = this.GetItemAt(e.X , e.Y);
416
417        m_nX = e.X ;
418
419        m_nY = e.Y ;
420
421    }

422}
客户代码如下:
 1this.listView1 = new MyControls.ALAN_EditListView();
 2
 3///////////////////////
 4///add the columns

 5MyControls.ALAN_ColumnHeader header1 = new MyControls.ALAN_ColumnHeader(MyControls.ALAN_ListViewColumnStyle.ReadOnly);
 6header1.Width = 120;
 7header1.Text = "姓名";
 8this.listView1.Columns.Add(header1);
 9
10MyControls.ALAN_ColumnHeader header2 = new MyControls.ALAN_ColumnHeader(MyControls.ALAN_ListViewColumnStyle.EditBox);
11header2.Width = 120;
12header2.Text = "性别";
13this.listView1.Columns.Add(header2);
14
15MyControls.ALAN_ColumnHeader header3 = new MyControls.ALAN_ColumnHeader(MyControls.ALAN_ListViewColumnStyle.EditBox);
16header3.Width = 120;
17header3.Text = "年龄";
18this.listView1.Columns.Add(header3);
19
20MyControls.ALAN_ColumnHeader header4 = new MyControls.ALAN_ColumnHeader(MyControls.ALAN_ListViewColumnStyle.ComboBox);
21header4.Width = 120;
22header4.Text = "专业";
23this.listView1.Columns.Add(header4);
24
25MyControls.ALAN_ColumnHeader header5 = new MyControls.ALAN_ColumnHeader(MyControls.ALAN_ListViewColumnStyle.ComboBox);
26header5.Width = 120;
27header5.Text = "轮休";
28this.listView1.Columns.Add(header5);
29
30///////////////////////
31///bound the combox         

32this.listView1.BoundListToColumn(3new string[]{"Lotus""SQL Server"".NET""VB"});
33this.listView1.BoundListToColumn(4new string[]{"Sun""Mon""Tue""Wed""Thu""Fri""Sat"});
34
35/////////////////////////////////////
36///set edit state font and backcolor

37this.listView1.ComboBoxFont = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
38this.listView1.EditFont = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
39
40///////////////////////
41///add rows 

42string[] s = new string[5];
43s[0= "张三" ;
44s[1= "";
45s[2= "24" ;
46s[3= ".NET" ;
47s[4= "Sun";
48this.listView1.Items.Add( new ListViewItem(s));
49
50s[0= "李四" ;
51s[1= "";
52s[2= "25" ;
53s[3= "SQL Server" ;
54s[4= "Mon";
55this.listView1.Items.Add( new ListViewItem(s));
56
57s[0= "王五" ;
58s[1= "";
59s[2= "23" ;
60s[3= "VB" ;
61s[4= "Tue";
62this.listView1.Items.Add( new ListViewItem(s));
63
64s[0= "赵六" ;
65s[1= "";
66s[2= "22" ;
67s[3= "Lotus" ;
68s[4= "Wed";
69this.listView1.Items.Add( new ListViewItem(s));
70
71///////////////////////////
72///other common attributs

73this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
74this.listView1.Font = new System.Drawing.Font("Microsoft Sans Serif"9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
75this.listView1.FullRowSelect = true;
76this.listView1.Name = "listView1";
77this.listView1.Size = new System.Drawing.Size(448273);
78this.listView1.TabIndex = 0;
79this.listView1.View = System.Windows.Forms.View.Details;
That's All. Thanks! ^_^