c# - Two Reordering ListBoxes on Same page, prevent user from dragging and dropping between -
i have wpf c# application has window 2 reordering listboxes right next each other. used examples in this link make listbox user control. unfortunately allows user drag 1 box , drop in other. how can make sure doesn't happen?
here code:
public void setitems(list<string> values){ _items = new observablecollection<item>(); foreach (string s in values) { _items.add(new item(s)); } listbox.displaymemberpath = "name"; listbox.itemssource = _items; listbox.previewmousemove += listbox_previewmousemove; var style = new style(typeof(listboxitem)); style.setters.add(new setter(listboxitem.allowdropproperty, true)); style.setters.add( new eventsetter( listboxitem.previewmouseleftbuttondownevent, new mousebuttoneventhandler(listboxitem_previewmouseleftbuttondown))); style.setters.add( new eventsetter( listboxitem.dropevent, new drageventhandler(listboxitem_drop))); listbox.itemcontainerstyle = style; } private void listbox_previewmousemove(object sender, mouseeventargs e) { point point = e.getposition(null); vector diff = _dragstartpoint - point; if (e.leftbutton == mousebuttonstate.pressed && (math.abs(diff.x) > systemparameters.minimumhorizontaldragdistance || math.abs(diff.y) > systemparameters.minimumverticaldragdistance)) { var lb = sender listbox; var lbi = findvisualparent<listboxitem>(((dependencyobject)e.originalsource)); if (lbi != null) { dragdrop.dodragdrop(lbi, lbi.datacontext, dragdropeffects.move); } } } private void listboxitem_previewmouseleftbuttondown(object sender, mousebuttoneventargs e) { _dragstartpoint = e.getposition(null); } private void listboxitem_drop(object sender, drageventargs e) { if (sender listboxitem) { var source = e.data.getdata(typeof(item)) item; var target = ((listboxitem)(sender)).datacontext item; int sourceindex = listbox.items.indexof(source); int targetindex = listbox.items.indexof(target); debug.writeline("target: " + targetindex.tostring()); move(source, sourceindex, targetindex); } } private void move(item source, int sourceindex, int targetindex) { if (sourceindex < targetindex) { _items.insert(targetindex + 1, source); _items.removeat(sourceindex); } else { int removeindex = sourceindex + 1; if (_items.count + 1 > removeindex) { _items.insert(targetindex, source); _items.removeat(removeindex); } } } }
i figured out in case else has similar issue...
i changed move function following:
private void move(item source, int sourceindex, int targetindex) { ilist<item> previtems = _items; try { _items.removeat(sourceindex); _items.insert(targetindex, source); } catch(argumentoutofrangeexception) { //user doesn't need notified this. means dragged out of box ordering. //the application not need stopped when happens. _items = previtems; debug.writeline("user tried drag between boxes.. order of boxes not changed. "); } }
i realized if remove item first won't have worry changing target or remove index based on position of sourceindex in relation targetindex. instead can wrap in try catch , argumentoutofrangeexception, happen if user tries drag , drop between. if happens reset box previous items.
as far can tell solution works fine... there may have been simpler way go this.
Comments
Post a Comment