c# - Multiple Combo Boxes with shared Binding - Display error after first selection from box -
i've been stumped on issue i've run across in last few days , figuring out.
i'm developing wpf application on first run prompt user manually assign detected serial ports arbitrary 'channels', used throughout application , later interface displaying data etc.
one of key features once port has been assigned in combo box, no longer available selection in others (using .isenabled property of comboboxitem class).
the issue i've run while works fine - each combo box set, opening next sees previous selection greyed out - if attempt go combo box i've set displays empty drop down. looks if drop-down still active window contains items hasn't been sized properly.
screen captures:
items disabled in subsequent combo boxes
returning selected box results in blank drop down (blue circle)
here's xaml code combo boxes:
<stackpanel grid.column="1" name="combopanel" margin="5, 20, 5, 5"> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel0" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel1" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel2" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel3" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel4" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel5" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel6" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel7" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel8" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel9" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel10" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> <combobox margin="0, 5, 0, 0" width="100" height="25" name="cboxchannel11" issynchronizedwithcurrentitem="false" itemssource="{binding portcollectionitems, updatesourcetrigger=propertychanged}" selectedindex="0" dropdownopened="cboxchannel0_dropdownopened" dropdownclosed="cboxchannel0_dropdownclosed" /> </stackpanel>
and here's behind code snippets relevant boxes:
public partial class portwindow : window, inotifypropertychanged { public event propertychangedeventhandler propertychanged; public observablecollection<comboboxitem> portcollectionitems { get; set; } public comboboxitem selecteditem; public bool serialportsset { get; set; } public comboboxitem selecteditem { { return selecteditem; } set { if (selecteditem == value) return; selecteditem = value; onpropertychanged("isenabled"); } } public portwindow() { initializecomponent(); datacontext = this; serialportsset = false; portcollectionitems = new observablecollection<comboboxitem>(); (int = 0; < activeserialports.detectedports.count(); i++) { if (i == 0) { portcollectionitems.add(new comboboxitem { content = "<-select->" }); } portcollectionitems.add(new comboboxitem { content = activeserialports.detectedports[i] }); // populates collection list of serial port names class } } void cboxchannel0_dropdownopened(object sender, eventargs e) { combobox combobox = sender combobox; string selectedstring = combobox.selectionboxitem string; selecteditem = combobox.selecteditem comboboxitem; foreach (comboboxitem portitems in portcollectionitems) { if (portitems.content == selecteditem.content) { portitems.isenabled = true; //re-enables disabled selection in case assigned port needs changing } } } void cboxchannel0_dropdownclosed(object sender, eventargs e) { combobox combobox = sender combobox; selecteditem = combobox.selecteditem comboboxitem; string itemstring = selecteditem.content.tostring(); if (!itemstring.contains("<-select->")) { foreach (comboboxitem portitems in portcollectionitems) { if (portitems.content == selecteditem.content) { portitems.isenabled = false; // disables selected item in observable collection return; } } } } protected void onpropertychanged(string propertyname) { if (propertychanged != null) propertychanged(this, new propertychangedeventargs(propertyname)); }
i'm inclined believe there's small vital i'm missing regards binding. thought altering of property within shared collection causing problem, after supressing of code in handlers , running issue persisted.
any appreciated!
you're sharing comboboxitems among different comboboxes. visual elements , you're trying share them among different parents. i'm not surprised breaks.
you need each combobox have distinct collection of comboboxitem instances. can exposing items observablecollection<string>
, letting each combobox create own comboboxitems. bind collection same way you're binding collection you've got; think declaring , populating collection should change need make, unless need disable port items all boxes @ once, rather 1 selected in. selecteditem
on combobox string, though, rather `comboboxitem, guts of loops have change bit.
when disable comboboxitem, disabled combobox belongs to, naturally. if want com4
disabled boxes, you'll have in loop.
or go little more mvvm: if me, create series of comboboxes in templated itemscontrol bound collection of class had selectedport property, , use custom class items well, simple thing string portname
, bool isportenabled
. i'd bind isportenabled
comboboxitem.isenabled
in xaml. there'd lot less code, it's big jump conceptually you're @ now. can go there if you're interested.
Comments
Post a Comment