c# - UserControlViewModel doesn't update binded property in UserControl -


i want able change property in main window user controls view model.

this connection

  • mainwindow
    • i bind property view model usercontrol
  • mainwindowviewmodel
    • my property lies here, updated when user control property changes
  • usercontrol1
    • its dependency property that's binded main window view model returns value usercontrolviewmodel
  • usercontrol1viewmodel
    • the logic changes property (which supposed update mainwindowviewmodel) lies here.

i can binding between of them, problem when update property bottom layer (usercontrolviewmodel), not update property neither in usercontrol or in mainwindowviewmodel.

here code (i have uploaded project on google drive)

mainwindow.xaml

<window x:class="wpfapplicationviewtoviewmodel.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"         xmlns:local="clr-namespace:wpfapplicationviewtoviewmodel"         mc:ignorable="d"         title="mainwindow" height="367" width="624">     <stackpanel>         <local:usercontrol1 textinusercontrol="{binding datacontext.textinmainwindowviewmodel,             mode=twoway, relativesource={relativesource mode=findancestor, ancestortype=window}}">         </local:usercontrol1>           <button content="test mainwindow vm" command="{binding commandtestmwvm}" ></button>         <separator></separator>      </stackpanel> </window> 

mainvindow.xaml.cs

using system.windows;  namespace wpfapplicationviewtoviewmodel {     /// <summary>     /// interaction logic mainwindow.xaml     /// </summary>     public partial class mainwindow : window     {         public mainwindow()         {             initializecomponent();             this.datacontext = new mainwindowviewmodel();         }       } } 

mainwindowviewmodel.cs

using system; using system.windows; using system.windows.input;  namespace wpfapplicationviewtoviewmodel {     class mainwindowviewmodel : viewmodelbase     {         public string textinmainwindowviewmodel         {                         {                 return _textinmainwindowviewmodel;             }             set             {                 _textinmainwindowviewmodel = value;                 raisepropertychanged("textinmainwindowviewmodel");             }         }         private string _textinmainwindowviewmodel { get; set; }          //test button         public mainwindowviewmodel()         {             _commandtestmwvm = new relaycommand(new action<object>(testmwvm));         }          #region [command] commandtestmwvm         public icommand commandtestmwvm         {             { return _commandtestmwvm; }         }         private icommand _commandtestmwvm;         private void testmwvm(object obj)         {             textinmainwindowviewmodel = textinmainwindowviewmodel + "mwvm";             messagebox.show("textinmainwindowmodel " + textinmainwindowviewmodel);         }         #endregion     } } 

usercontrol1.xaml (includes 2 buttons testing purposes)

<usercontrol x:class="wpfapplicationviewtoviewmodel.usercontrol1"              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"               xmlns:d="http://schemas.microsoft.com/expression/blend/2008"               xmlns:local="clr-namespace:wpfapplicationviewtoviewmodel"              mc:ignorable="d"               d:designheight="300" d:designwidth="300">     <stackpanel>         <button content="test uc" click="button_click"></button>         <button content="test ucvm" command="{binding commandtestucvm}" ></button>     </stackpanel> </usercontrol> 

usercontrol1.xaml.cs

using system.windows; using system.windows.controls; using system.windows.data;  namespace wpfapplicationviewtoviewmodel {     /// <summary>     /// interaction logic usercontrol1.xaml     /// </summary>     public partial class usercontrol1 : usercontrol     {         private  usercontrol1viewmodel vm = new usercontrol1viewmodel();          public usercontrol1()         {             initializecomponent();             this.datacontext = vm;              //http://stackoverflow.com/questions/15132538/twoway-bind-views-dependencyproperty-to-viewmodels-property             //does not work because breaks binding somewhere             //string propertyinviewmodel = "textinusercontrolviewmodel";             //var bindingviewmode = new binding(propertyinviewmodel) { mode = bindingmode.twoway };             //this.setbinding(textinusercontrolproperty, bindingviewmode);          }          //dependency property declaration         public static dependencyproperty textinusercontrolproperty =             dependencyproperty.register("textinusercontrol",                 typeof(string),                 typeof(usercontrol1)                  );           public string textinusercontrol         {             {                  return (datacontext usercontrol1viewmodel).textinusercontrolviewmodel;             }             set             {                 (datacontext usercontrol1viewmodel).textinusercontrolviewmodel = value;                 this.setvalue(textinusercontrolproperty, value);             }         }          private void button_click(object sender, routedeventargs e)         {             textinusercontrol = textinusercontrol + "uc";             messagebox.show("textinusercontrol : " + textinusercontrol);         }     } } 

usercontrol1viewmodel.cs

using system; using system.windows; using system.windows.input;  namespace wpfapplicationviewtoviewmodel {     class usercontrol1viewmodel : viewmodelbase     {          private string _textinviewmodel;         public string textinusercontrolviewmodel         {             { return _textinviewmodel; }             set {                 _textinviewmodel = value;                 raisepropertychanged("textinusercontrolviewmodel");             } }          //test button         public usercontrol1viewmodel()         {             _commandtestucvm = new relaycommand(new action<object>(testucvm));         }          #region [command] commandtestucvm         public icommand commandtestucvm         {             { return _commandtestucvm; }         }         private icommand _commandtestucvm;         private void testucvm(object obj)         {             textinusercontrolviewmodel = textinusercontrolviewmodel + "ucvm";             messagebox.show("textinusercontrolviewmodel : " + textinusercontrolviewmodel);         }         #endregion     } } 

any really appreciated because i've been trying figure out system (reading usercontrols viewmodel mainwindow) week.

to make question more clear:

textinusercontrol <=> textinmainwindowviewmodel : works succesfuly

textinusercontrol => textinusercontrolviewmodel : works when change textinusercontrolviewmodel, textinusercontrol doesn't updated automatically.

is there anyway can let textinusercontrol know textinusercontrolviewmodel changed?

you setting usercontrol's datacontext usercontrol1viewmodel instance, binding textinusercontrol property datacontext.textinmainwindowviewmodel, resulting in looking property usercontrol1viewmodel.datacontext.textinmainwindowviewmodel, not exist.

one of first rules of working wpf/mvvm : never set this.datacontext = x; in code behind user-control unless intend never pass control outside value.

instead want add instance of usercontrol1viewmodel onto mainwindowviewmodel, , bind usercontrol.datacontext instance.

for example,

class mainwindowviewmodel : viewmodelbase {     // add property     public usercontrol1viewmodel usercontroldata { ... }      public string textinmainwindowviewmodel { ... }     public icommand commandtestmwvm { ... } } 
<!-- change binding --> <local:usercontrol1 datacontext="{binding usercontroldata}" /> 

and rid of following in usercontrol constructor

this.datacontext = vm; 

Comments

Popular posts from this blog

php - Invalid Cofiguration - yii\base\InvalidConfigException - Yii2 -

How to show in django cms breadcrumbs full path? -

ruby on rails - npm error: tunneling socket could not be established, cause=connect ETIMEDOUT -