binding - WPF Control losing focus when clicking on a tab -
on tabcontrol have several tabpages, on 1 of tabs there textbox in content.
this textbox content bound simple path=propertyname , updatesourcetrigger=lostfocus. reason using lostfocus trap lost focus event of textbox , possibly reformat text. "time" textbox , if enter "0900", want reformat "09:00". part works great when press tab key move next control, if type "0900" press 1 of other tabs, hit lost focus , re-format value in textbox, bind never gets called update object. when come tab, value blanked out (or reset original value on object)
any ideas why textbox not trigger binding update when changing tab page?
note: happens regular textbox wire lost focus event. seems have click on tab.
[[added code ]] more notes: 1. dynamically creating tabs , controls on tab (not sure if has or not) 2. using prism libraries
mainwindow xaml
<window.resources> <datatemplate datatype="{x:type ctrls:mytextboxdef}"> <grid width="300"> <grid.columndefinitions> <columndefinition width="auto" minwidth="100" /> <columndefinition width="*" /> </grid.columndefinitions> <grid.rowdefinitions> <rowdefinition height="28" /> </grid.rowdefinitions> <textblock grid.column="0" horizontalalignment="stretch" verticalalignment="center" text="{binding labeltext}" /> <textbox grid.column="1" horizontalalignment="stretch" verticalalignment="center" text="{binding docvalue, mode=twoway, validatesondataerrors=true, updatesourcetrigger=lostfocus}" /> </grid> </datatemplate> </window.resources> <grid> <tabcontrol horizontalalignment="stretch" verticalalignment="stretch" horizontalcontentalignment="stretch" verticalcontentalignment="stretch" istabstop="false" itemssource="{binding tabs, mode=oneway}" selecteditem="{binding selectedtab, mode=twoway, notifyonsourceupdated=true}" > <tabcontrol.itemtemplate> <datatemplate> <grid> <textblock margin="18,14,22,0" text="{binding headertext}" /> </grid> </datatemplate> </tabcontrol.itemtemplate> <!-- content --> <tabcontrol.contenttemplate> <datatemplate> <grid> <grid.columndefinitions> <columndefinition width="auto" /> <columndefinition width="auto" /> </grid.columndefinitions> <adornerdecorator grid.column="0"> <itemscontrol grid.column="0" horizontalalignment="stretch" verticalalignment="stretch" istabstop="false" itemssource="{binding controls, mode=oneway}"> <itemscontrol.itemspanel> <itemspaneltemplate> <wrappanel grid.column="0" margin="10,5,0,0" horizontalalignment="stretch" verticalalignment="stretch" orientation="vertical" /> </itemspaneltemplate> </itemscontrol.itemspanel> </itemscontrol> </adornerdecorator> </grid> </datatemplate> </tabcontrol.contenttemplate> </tabcontrol> </grid> </window>
main window code behind
public partial class mainwindow : window { private datacontextobject obj = new datacontextobject(); public mainwindow() { initializecomponent(); mytextboxdef txt1 = new mytextboxdef(obj, "textbox 1", "tab1textbox1"); mytextboxdef txt1b = new mytextboxdef(obj, "textbox 1 value", "tab1textbox1"); mytextboxdef txt2 = new mytextboxdef(obj, "textbox 2", "tab1textbox2"); mytextboxdef txt2b = new mytextboxdef(obj, "textbox 2 value", "tab1textbox2"); obj.tabs.add(new mytabdef("tab 1", new observablecollection<mytextboxdef>() { txt1, txt2 })); obj.tabs.add(new mytabdef("tab 2", new observablecollection<mytextboxdef>() { txt1b, txt2b })); obj.selectedtab = obj.tabs[0]; this.datacontext = obj; } }
supporting objects
public class datacontextobject : notificationobject { list<mytabdef> _tabs = new list<mytabdef>(); public list<mytabdef> tabs { { return _tabs; } } private mytabdef _item; public mytabdef selectedtab { { return _item; } set { _item = value; this.raisepropertychanged("selecteditem"); } } private string _txt1 = ""; public string tab1textbox1 { { return _txt1; } set { _txt1 = value; this.raisepropertychanged("tab1textbox1"); } } private string _txt2 = ""; public string tab1textbox2 { { return _txt2; } set { _txt2 = value; this.raisepropertychanged("tab1textbox2"); } } private string _txt3 = ""; public string tab2textbox1 { { return _txt3; } set { _txt3 = value; this.raisepropertychanged("tab2textbox1"); } } } public class mytabdef { public mytabdef(string tabtext, observablecollection<mytextboxdef> controls) { headertext = tabtext; _left = controls; } public string headertext { get; set; } private observablecollection<mytextboxdef> _left = new observablecollection<mytextboxdef>(); public observablecollection<mytextboxdef> controls { { return _left; } } } public class mytextboxdef : notificationobject { public mytextboxdef(notificationobject bound, string label, string bindingpath) { labeltext = label; path = bindingpath; boundobject = bound; boundobject.propertychanged += boundobject_propertychanged; } public string labeltext { get; set; } public notificationobject boundobject { get; set; } public string docvalue { { return propinfo.getvalue(boundobject, null) string; } set { propinfo.setvalue(boundobject, value, null); } } protected virtual void boundobject_propertychanged(object sender, system.componentmodel.propertychangedeventargs e) { if (e.propertyname.equals(path)) { this.raisepropertychanged("docvalue"); } } public string path { get; set; } private propertyinfo pi = null; protected propertyinfo propinfo { { if (pi == null && boundobject != null && !string.isnullorempty(path)) { propertyinfo[] properties = boundobject.gettype().getproperties(bindingflags.public | bindingflags.instance); pi = properties.where((prop) => string.compare(prop.name, path, true) == 0).firstordefault(); } return pi; } } }
we have found solution. came cross set of postings
https://groups.google.com/forum/#!topic/wpf-disciples/hkuu61a5l74
they talk control called tabcontrolex. towards bottom (5th bottom) see posting sacha barber has zip file example.
it solved our problems having.
here link code class posted
Comments
Post a Comment