解决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,新代码如下:

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>();
      }
    }
  }
}

时间: 2024-10-27 09:55:18

解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合”的相关文章

C# ComboBox控件“设置 DataSource 属性后无法修改项集合”的完美解决方法_C#教程

由于毕业后工作没有对接到专业问题,导致四五年没有碰过Winform程序了.突然由于工作问题,为了方便自己,所以想自己写写小winform小软件,用于自己使用.在使用ComboBox控件时,遇到了重新绑定赋值出问题的情况. 错误代码如下: if (CustomerBLL.select().Rows.Count > 0) { cbTcid.Items.Clear(); cbTcid.DataSource = CustomerBLL.select(); cbTcid.ValueMember = "

winform下拉控件缓存

问题描述 一个winform的下拉控件(例如combox)的绑定数据源可能有十万级别的数据,怎么来做缓存好点?如果在这控件中输入数据然后再去数据库进行模糊匹配的话,可能速度不够快. 解决方案 解决方案二:你想要完成的是什么功能,常规做法是不会绑十万数组在下拉框里的,你让别人怎么选解决方案三:做成autocomplete的功能,到数据库去匹配.缓存就是类似分页读取的效果,解决不了什么问题,不可能让用户去一页一页读取10w条数据解决方案四:用DATAGRID绑定数据吧,然后做个分页,10W的数据要读

数据绑定控件:DataSource属性

数据绑定控件,都有DataSource属性,用于指定数据源.通常情况下,也是比较常用的就是数据源是数据表(DataTable),其实DataSource的范围很广,我们可以在深入研究的同时,改善我们的程序. 有的时候,你在编程进入一定阶段,进一步提升很困难的境况之下,不妨回过头来看看基础的东西,或许你会有新的受益,或许能够真正的体会到孔夫子所谓的"温故而知新"的真正内涵. 常用的数据绑定控件有:Repeater.DataList.GridView.DetailsView等,在这里我拿R

关于winform中listbox控件的问题

问题描述 两个窗体里的listbox传值的问题,我现在是用的委托实现了传值的效果,但是现在只能传过来一个值,如果传第二个,第一个就会被替代,这个该怎么解决呢 解决方案 解决方案二:委托可以是多个参数解决方案三:@xdashewan怎么写呢?解决方案四:引用2楼dong19980903的回复: @xdashewan怎么写呢? 你想实现的效果是什么怎么样的,稍微具体地说明下解决方案五:引用3楼xdashewan的回复: Quote: 引用2楼dong19980903的回复: @xdashewan怎么

如果数据被绑定到控件之后,修改控件上的数据会同时修改数据库里的数据吗?

问题描述 如上,如果不可以的话应改这么做,有什么方法,请大家指点 解决方案 解决方案二:会的设置相关属性~解决方案三:不会要写更新数据库数据的代码解决方案四:不加代码能改变控件的内容吗?解决方案五:一般不会,但是有些控件设置了属性以后会随着更新的.解决方案六:要看你怎么绑定的

winform程序button控件未设置任何热键,为何还可通过热键触发事件

问题描述 winform窗体中的某个按钮,没有定义任何热键但是在程序处理逻辑将该按钮的enabled属性设置为false后,偶然情况下,客户拍了下键盘,居然触发了该按钮事件可以保证1.该按钮的单击事件没有任何其他地方触发,也就是说只有用鼠标单击该按钮才可触发2.整个窗体及其他控件都未设置过热键3.按钮的enabled属性为false,并不存在处理逻辑失误导致enabled属性为true,由客户点击按钮造成触发事件4.客户机上未运行其他任何程序求各位大神解答,谢谢 解决方案 本帖最后由 ilove

向listbox控件里添加字符时,listbox已有的字符会闪烁。

问题描述 用C#的listbox控件,显示串口收到的数据,收到一个包就显示为一行,包的大小不超过10个字节.串口接收放在0.1秒定时器里,读到完整的包后,就送到listbox里去显示.(现在下位机1秒发一次)现在现象是:串口每收到一个包显示时,listbox里已有的数据就会闪一次.如果在界面上用按键测试,每按一次按键就在listbox里添加一行数据,这样操作不会导致listbox闪烁.各位帮忙分析分析,这是什么原因呀? 解决方案 解决方案二:你是每次添加一行呢,还是从头到尾添加一遍呢解决方案三:

学习Winform分组类控件(Panel、groupBox、TabControl)_C#教程

分组类控件主要包括容器控件(Panel),分组框控件(groupBox)和选项卡控件(TabControl)等控件. 一.Panel控件 Panel控件是由System.Windows.Forms.Panel类提供的,主要作用就是将其他控件组合一起放在一个面板上,使这些控件更容易管理.当Panel控件面板上要显示过多的控件时,可设置AutoScroll属性为true.  Panel控件在默认情况下不显示边框,如把BorderStyle属性设置为不是none的其他值,就可以使用面板可视化地组合相关

如何在工具栏上添加平面下拉控件

效果图如下: 使用过WordXP的人都知道,她的界面可谓是耳目一新.尤其是她的菜单和工具条可真是酷.网上也有很多很多的人都在模仿着她,包括很多的软件公司的产品.她的出现,使得软件界刮起了一陈XP界面时尚风.废话就不再多话了,言归正题,下面我就将实现的步骤一步步地告诉给你. 第一步:新建一个单文档项目 第二步:到资源编辑器中,新增一个工具项.里面没内容的,资源就命名为ID_TOOL_ZOOM吧.呵呵,新增一个工具项与我的下拉控件有什么关系呀?当然有关系,因为一会那个下拉控件就是在这个位置上显示出来