mvvm - Binding WPF UserControl to View Model and Code Behind -


i'm attempting understand best way of wiring custom control use dependency properties , view model. dependency properties implemented expose properties can used in xaml initialise properties in view model. example, in code behind of custom control can define following dependency property:

public static readonly dependencyproperty mypropertyproperty = dependencyproperty.register(          "myproperty", typeof(string), typeof(mycontrol), new propertymetadata(null));  public string myproperty {   { return (string)getvalue(mypropertyproperty); }   set { setvalue(mypropertyproperty, value); } } 

where view model defined as

public class mycontrolviewmodel : inotifypropertychanged    {       public mycontrolviewmodel()       {          _myproperty = "default view model string";       }        private string _myproperty;        public string myproperty       {                   {             return _myproperty;          }          set          {             _myproperty = value;             onpropertychanged("myproperty");          }       }        public event propertychangedeventhandler propertychanged;        protected virtual void onpropertychanged(string propertyname = null)       {          var handler = propertychanged;          if (handler != null) handler(this, new propertychangedeventargs(propertyname));        }    } 

and custom control binds view model myproperty follows

<usercontrol x:class="myproject.mycontrolview"              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"              xmlns:local="clr-namespace:myproject">      <usercontrol.datacontext>         <local:mycontrolviewmodel/>     </usercontrol.datacontext>      <grid>         <textblock text="{binding myproperty}"/>                     </grid>  </usercontrol> 

now since have defined dependency property myproperty in custom control's code behind, want able use initialise myproperty in viewmodel. this

 <window x:class="myproject.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:local="clr-namespace:myproject"         title="mainwindow" height="350" width="525">     <grid>         <local:mycontrolview myproperty="this set in xaml"/>     </grid> </window> 

running above display string "default view model string" set in view model's constructor. how hook dependency property value correctly initialises string in view model? i.e. should display "this set in xaml".

update

i can set property changed callback in code behind , set value in view model, i.e.

public static readonly dependencyproperty mypropertyproperty =           dependencyproperty.register("myproperty", typeof(string), typeof(mycontrolview), new propertymetadata("default", onmypropertychanged));        private static void onmypropertychanged(dependencyobject d, dependencypropertychangedeventargs e)       {          var view = d mycontrolview;          if (view != null)          {             var viewmodel = view.datacontext mycontrolviewmodel;             if (viewmodel != null)             {                viewmodel.myproperty = e.newvalue string;             }          }       } 

is correct, or smell?

you have created dependency property nice. but, have made tightly coupled instiantiating view model , using property code behind. wrong way.

you should inherit class "control" , binding value , create 1 dp below in custom control class:

public static readonly dependencyproperty myvalueproperty = dependencyproperty.register(             "myproperty", typeof(object), typeof(fieldcontrol), new frameworkpropertymetadata(null, myvaluechanged)); 

then,

private static void myvaluechanged(dependencyobject dependencyobject, dependencypropertychangedeventargs dependencypropertychangedeventargs)         {             var fc = dependencyobject fieldcontrol;             if (fc != null)             {                 fc.setvalue(bindingexpression1key, fc.getbindingexpression(valueproperty));                 fc.raisevaluechangedevent(dependencypropertychangedeventargs);             }         } 

now, use , bind property below:

 <local:mycontrolview myproperty="{binding myproperty, mode=twoway}"/> 

Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -