data binding - WPF Dependency Property Question -
i'm new wpf, , i'm trying thought simple task - display value of field in business object changes during program. know how "force" change manually changing textbox.text property in c#, i'm learning wpf want "right" way, , means databinding.
question #1: far understand it, choice either use dependencyproperty or implement inotifypropertychanged in business object, right?
question #2: here generic version of code in attempted go dependencyproperty route.
markup:
button x:name="nextbutton" content="click" grid.row="2" click="nextbutton_click" /> textbox x:name="mytextbox" grid.row="1" text="{binding source=mytest, path=name, updatesourcetrigger=propertychanged, notifyonsourceupdated=true}"/>
code-behind:
namespace dependencytest2 { /// /// interaction logic mainwindow.xaml /// public partial class mainwindow : window { private int i; private testsphere mytest; public mainwindow() { initializecomponent(); = 0; mytest = new testsphere(); } private void nextbutton_click(object sender, routedeventargs e) { switch (i) { case 0: mytest.name = "string1"; break; case 1: mytest.name = "string2"; break; case 2: mytest.name = "string3"; break; } i++; } } class testsphere : dependencyobject { public string name { { return (string)getvalue(nameproperty); } set { setvalue(nameproperty, value); } } public static readonly dependencyproperty nameproperty = dependencyproperty.register("name", typeof(string), typeof(testsphere)); public testsphere() { name = "default"; } } }
when run program, nothing appears in text box, though bound property has value - there else need alert binding source value has changed? thought using dependencyproperty source take care of that, again, i'm wpf rookie. thanks!
- steve
ok, tried implement inotifypropertychanged using wrapper class found on codeproject follows:
class testsphere : notifyproperychangedbase { private string _name; public string name { { return _name; } set { this.checkpropertychanged("name", ref _name, ref value); } } public testsphere() { name = "default"; } } public abstract class notifyproperychangedbase : inotifypropertychanged { #region inotifypropertychanged members public event propertychangedeventhandler propertychanged; #endregion #region methods protected bool checkpropertychanged(string propertyname, ref t oldvalue, ref t newvalue) { if (oldvalue == null && newvalue == null) { return false; } if ((oldvalue == null && newvalue != null) || !oldvalue.equals((t)newvalue)) { oldvalue = newvalue; firepropertychanged(propertyname); return true; } return false; } protected void firepropertychanged(string propertyname) { if (this.propertychanged != null) { this.propertychanged(this, new propertychangedeventargs(propertyname)); } } #endregion
here new markup, too:
grid name="mygrid"> grid.rowdefinitions> rowdefinition height="30"/> rowdefinition height="30"/> rowdefinition height="30"/> rowdefinition height="*"/> /grid.rowdefinitions> label x:name="mylabel" grid.row="0" foreground="black" /> button x:name="nextbutton" content="click" grid.row="2" click="nextbutton_click" /> textbox x:name="mytextbox" grid.row="1" text="{binding path=mytest.name}"/> /grid>
i added line mygrid.datacontext = mytest;
'public mainwindow()' after instantiate mytest. when step through resulting program, value of this.propertychanged
evaluates null
, propertychanged never fires. sorry in advance must noob question.
- steve
you should need implement inotifypropertychanged
on testsphere class, not dependencyobject. update value, call propertychanged(this, new propertychangedeventargs("name"))
.
second, need set datacontext window in code-behind. lets used in xaml root grid element:
<grid name="mainform">
then in code-behind, you'd this:
mainform.datacontext = this;
finally, change mytest property public
, , binding in xaml should need be
text="{binding path=mytest.name}"
Comments
Post a Comment