The first time I used the ListBox control to write a winform program, I encountered a disgusting problem. Because I don't want to manually bind items in ListBox to use datasource, but when I perform some add or delete operations, I reported this error "the item set cannot be modified after the datasource attribute is set ". This is really disgusting. I don't know how The ListBox designer gave the datasource attribute but could not be changed at will. I want to implement the function of selecting a few items in one ListBox and putting them in another ListBox, it is too troublesome to use datasource. I did not find a solution in my blog, but I had to do it myself. Some people say this is because "after binding in the winform program, it is directly related to the data source able, the change will affect the datatable. "In this case, the solution is to re-bind the datasource from the new data source if you want to change the items. After the test, the effect is good. I encapsulate the operation of moving items between two listboxes into a class. The Code is as follows:
Description: here, the generic type must be used to specify the bound object type. At first, the generic type is not used, however, after several transfers, it is strange that the field set according to the displayermember attribute cannot be displayed. I hope to help my friends who have encountered the same problem. Enthusiastic netizens reminded me that the datatable support was added. To facilitate encoding and unified calling of the generic parameter datarow when datatable is used as the data source, the new Code is as follows:
Using system; using system. collections; using system. collections. generic; using system. data; using system. windows. forms; namespace Lucifer {// used to uniformly process the transfer between two list-type controls. Items public static class lstctrlmove_mgr
{// Delete items public static void removeitems (ListBox lstbox, ienumerable items) {If (typeof (t) = typeof (datarow) from a ListBox )) {datatable dt = (datatable) lstbox. datasource); datatable newdt = DT. clone (); bool flag = false; // The 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
LST = new list
(); Lst. addrange (list
) Lstbox. datasource); lst. removeall (delegate (T Item1) {foreach (T item2 in items) {If (item1.equals (item2) return true ;}return false ;}); lstbox. datasource = lst ;}}// add items public static void additems (ListBox lstbox, ienumerable items) {If (typeof (t) = typeof (datarow) to a ListBox )) {datatable dt = NULL; foreach (Object item in items) {If (item is datarowview) dt = (datarowview) item ). row. t Able. 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
LST = new list
(); If (lstbox. datasource! = NULL) lst. addrange (list
) Lstbox. datasource); foreach (T item in items) {lst. add (item);} lstbox. datasource = lst ;}}// transfers selected items of listbox1 to listbox2, and removes public static void move (ListBox lstbox1, ListBox lstbox2) {If (lstbox1.selecteditems. count> 0) {additems (lstbox2, lstbox1.selecteditems); removeitems (lstbox1, lstbox1.selecteditems); }}// transfers the entire lstbox1 item to listbox2, and clear 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
) Lstbox1.datasource); lstbox1.datasource = new list
();}}}}