解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合”的问题

  很少写WinForm程序第一次使用ListBox控件就遇到了比较恶心的问题。因为我不想手动绑定ListBox中的Item就使用了DataSource,但是当我进行一些添加、删除操作时就报了这个错“设置DataSource属性后无法修改项集合”。实在太恶心了,不知道设计ListBox的人是怎么想的给了DataSource属性却不能随便更改,而我要实现在一个ListBox中选中几项然后放到另一个ListBox中的功能,不能用DataSource的话太麻烦了。上博客园查了下没有找到解决办法,只能自己动手丰衣足食了。

  因为有人说引起这个的原因是“在winForm程序中这样绑定之后是直接和数据源DataTable相关,改动项会对DataTable造成影响”既然这样那解决方法就是如果要对Items做更改就从新弄个DataSource重新绑定,试验后效果不错。我把操作两个ListBox之间互相移动item的操作封装到一个类里,代码如下:

  说明一下,这里必须用泛型来指明所绑定的对象类型,一开始没想用泛型的,可是转移几次以后就不能按照DisplayerMember属性设置的字段来显示了比较奇怪。希望对遇到相同问题的朋友有帮助。

  经热心网友提醒,加入了对DataTable的支持。为了便于编码和统一调用使用DataTable做数据源时泛型参数为DataRow,新代码如下:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
view plaincopy to clipboardprint?
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Windows.Forms; 
 
namespace Lucifer 
{ 
  //用于统一处理两个List类型控件之间互相转移Items 
  public static class LstCtrlMove_Mgr< T ></ T > 
  { 
    //从一个ListBox中删除Items 
    public static void RemoveItems(ListBox lstBox, IEnumerable items) 
    { 
      if (typeof(T) == typeof(DataRow)) 
      { 
        DataTable dt = ((DataTable)lstBox.DataSource); 
        DataTable newDt = dt.Clone();  
        bool flag = false; 
        //因为直接删除DataRow会保存,所以用这样丑陋的方式处理了 
        foreach (DataRow dr in dt.Rows) 
        { 
          foreach (DataRowView item in items) 
          { 
            if (dr == item.Row) 
            { 
              flag = true; 
              break; 
            } 
            else 
              flag = false; 
          } 
          if (!flag) 
            newDt.Rows.Add(dr.ItemArray); 
          else 
            continue; 
        }         
        lstBox.DataSource = newDt; 
      } 
      else 
      { 
        List< T ></ T > lst = new List< T ></ T >(); 
        lst.AddRange((List< T ></ T >)lstBox.DataSource); 
        lst.RemoveAll(delegate(T item1) 
        { 
          foreach (T item2 in items) 
          { 
            if (item1.Equals(item2)) 
              return true; 
          } 
          return false; 
        }); 
        lstBox.DataSource = lst; 
      } 
    } 
    //向一个ListBox中添加Items 
    public static void AddItems(ListBox lstBox, IEnumerable items) 
    { 
      if (typeof(T) == typeof(DataRow)) 
      { 
        DataTable dt = null; 
        foreach (object item in items) 
        { 
          if(item is DataRowView) 
            dt = ((DataRowView)item).Row.Table.Clone(); 
          if (item is DataRow) 
            dt = ((DataRow)item).Table.Clone(); 
          break; 
        }         
        if (lstBox.DataSource != null)         
          dt = ((DataTable)lstBox.DataSource).Copy(); 
        foreach (object item in items) 
        { 
          if(item is DataRowView) 
            dt.Rows.Add(((DataRowView)item).Row.ItemArray); 
          if (item is DataRow) 
            dt.Rows.Add(((DataRow)item).ItemArray); 
        } 
        lstBox.DataSource = dt; 
      } 
      else 
      { 
        List< T ></ T > lst = new List< T ></ T >(); 
        if (lstBox.DataSource != null) 
          lst.AddRange((List< T ></ T >)lstBox.DataSource); 
        foreach (T item in items) 
        { 
          lst.Add(item); 
        } 
        lstBox.DataSource = lst; 
      } 
    } 
    //将ListBox1的选定项转移到ListBox2中,并从ListBox1中去除 
    public static void Move(ListBox lstBox1, ListBox lstBox2) 
    { 
      if (lstBox1.SelectedItems.Count > 0) 
      { 
        AddItems(lstBox2, lstBox1.SelectedItems); 
        RemoveItems(lstBox1, lstBox1.SelectedItems); 
      } 
    } 
    //将整个lstBox1的项转移到ListBox2中,并清空ListBox1 
    public static void MoveAll(ListBox lstBox1, ListBox lstBox2) 
    { 
      if (typeof(T) == typeof(DataRow)) 
      { 
        DataTable dt = (DataTable)lstBox1.DataSource; 
        AddItems(lstBox2, dt.Rows); 
        lstBox1.DataSource = dt.Clone(); 
      } 
      else 
      { 
        AddItems(lstBox2, (List< T ></ T >)lstBox1.DataSource); 
        lstBox1.DataSource = new List< T ></ T >(); 
      } 
    } 
  }   
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值