c# - Simple DataBinding in wpf application -
hi trying study simple data binding in wpf. tried , not succeeding.. please suggest ways..
<window x:class="wpftestapp.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" title="mainwindow" height="250" width="350"> <grid> <grid.columndefinitions> <columndefinition width="70"/> <columndefinition width="*"/> </grid.columndefinitions> <grid.rowdefinitions> <rowdefinition height="50"/> <rowdefinition height="50"/> <rowdefinition height="50"/> <rowdefinition height="50"/> </grid.rowdefinitions> <label content="first name" grid.row="0" grid.column="0" height="25" horizontalalignment="stretch"/> <label content="last name" grid.row="1" grid.column="0" height="25" horizontalalignment="stretch"/> <label content="full name" grid.row="2" grid.column="0" height="25" horizontalalignment="stretch"/> <textbox x:name="fname" text="{binding firstname, updatesourcetrigger=propertychanged}" grid.row="0" grid.column="1" height="25" horizontalalignment="stretch"/> <textbox x:name="lname" text="{binding lastname, updatesourcetrigger=propertychanged}" grid.row="1" grid.column="1" height="25" horizontalalignment="stretch"/> <label x:name="lblfullname" content="{binding firstname}" grid.row="2" grid.column="1" height="25" horizontalalignment="stretch"/> <button x:name="cmdcommand" content="command" grid.row="3" grid.column="1" margin="2" verticalalignment="center" horizontalalignment="center" click="cmdcommand_click"/> </grid> </window>
now see, want label lblfullname automatically updated type name in textboxes.
now codebehind file looks this:
public partial class mainwindow : window, inotifypropertychanged { private string _firstname; public string firstname { { return _firstname; } set { if (value != _firstname) { _firstname = value; onpropertychanged("firstname"); } } } private string _lastname; public string lastname { { return _lastname; } set { if (value != _lastname) { _lastname = value; onpropertychanged("lastname"); } } } public event propertychangedeventhandler propertychanged; /// <summary> /// notifies objects registered receive event property value has changed. /// </summary> /// <param name="propertyname">the name of property changed.</param> protected virtual void onpropertychanged(string propertyname) { if (this.propertychanged != null) { this.propertychanged(this, new propertychangedeventargs(propertyname)); } } public mainwindow() { initializecomponent(); } private void cmdcommand_click(object sender, routedeventargs e) { lblfullname.content = firstname + " " + lastname; } }
needless say, clicking command button not working...
any suggestions?
setting datacontext point window solve immediate problem:
public mainwindow() { initializecomponent(); this.datacontext = this; }
the paths in binding expressions in xaml relative datacontext of controls datacontext has set.
however, suggest put first name , last name in separate class (e.g. personviewmodel) make code easier read , maintain.
public class personviewmodel : inotifypropertychanged { private string _firstname; public string firstname { { return _firstname; } set { if (value != _firstname) { _firstname = value; onpropertychanged("firstname"); } } } private string _lastname; public string lastname { { return _lastname; } set { if (value != _lastname) { _lastname = value; onpropertychanged("lastname"); } } } public event propertychangedeventhandler propertychanged; protected virtual void onpropertychanged(string propertyname) { var handler = this.propertychanged; if (handler != null) { handler(this, new propertychangedeventargs(propertyname)); } } } public partial class mainwindow : window { public mainwindow() { initializecomponent(); this.datacontext = new personviewmodel(); } private void cmdcommand_click(object sender, routedeventargs e) { lblfullname.content = firstname + " " + lastname; } }
now last part of code not work anymore. there 2 solutions.
the quick , dirty solution:
private void cmdcommand_click(object sender, routedeventargs e) { var person = this.datacontext personviewmodel; if(person == null) return; lblfullname.content = string.format("{0} {1}", person.firstname, person.lastname); }
a better way, when trying proper mvvm put property in viewmodel (note change in first , last name properties!):
public class personviewmodel : inotifypropertychanged { public string fullname { { return string.format("{0} {1}", firstname, lastname); } } private string _firstname; public string firstname { { return _firstname; } set { if (value != _firstname) { _firstname = value; onpropertychanged("firstname"); onpropertychanged("fullname"); } } } private string _lastname; public string lastname { { return _lastname; } set { if (value != _lastname) { _lastname = value; onpropertychanged("lastname"); onpropertychanged("fullname"); } } } // remainder of class remains same }
remove button , click handler. bind label new property:
<label content="{binding fullname}" grid.row="2" grid.column="1" height="25" horizontalalignment="stretch"/>
Comments
Post a Comment