c# - Binding ViewModel to multiple windows -
i'm re-writing windows forms project scoring sheep shearing events (don't ask, huge sport in new zealand) vbnet wpf c# , have struck problem can't seem overcome.
i have 2 windows. 1 source window type things in (like current event name), , other window display information in flash way projection onto screen (so on second monitor) along other data coming in via xml on network. have set mvvm viewmodel , model separate projects.
on main window, can bind controls fine , if type in 1 text box appears in text box if bound same thing. however, on second window, have bound control same thing , not updating.
i've been going around in circles on week, every example on net shows how on 1 window have got working fine, there lack of 2 window examples.
here have...
this in viewmodel project
namespace sheepviewmodel { public class sheepviewmodel : inotifypropertychanged { private string _currenteventname; static sheepviewmodel _details; public string currenteventname { { return _currenteventname; } set { _currenteventname = value; onpropertychanged("currenteventname"); } } public static sheepviewmodel getdetails() { if (_details == null) _details = new sheepviewmodel(); return _details; } public event propertychangedeventhandler propertychanged; private void onpropertychanged(string prop) { if (propertychanged != null) propertychanged(this, new propertychangedeventargs(prop)); console.writeline("test"); } } } then have main window, there no real code behind other line open second window to...
public mainwindow() { scorescreen sw = new scorescreen(); sw.show(); initializecomponent(); } then xaml
<window x:class="sheep_score_3._1.mainwindow" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" 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:vm="clr-namespace:sheepviewmodel;assembly=sheepviewmodel" mc:ignorable="d" title="mainwindow" height="433.689" width="941.194"> <window.datacontext> <vm:sheepviewmodel/> </window.datacontext> <window.resources> <grid margin="0,0,0,0"> <textbox x:name="currenteventname" height="23" margin="131.01,163.013,0,0" textwrapping="wrap" verticalalignment="top" horizontalalignment="left" width="327.151" text="{binding currenteventname, mode=twoway}"/> <textbox text="{binding currenteventname, mode=twoway}" margin="39.605,0,0,108.567" height="49.111" verticalalignment="bottom" horizontalalignment="left" width="399" /> </grid> the above code works fine, if type text in first textbox appears in second text box. if put console.writeline in notify part can see hitting , updating.
now add second window, setup same way...
<window x:class="sheep_score_3._1.scorescreen" 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:vm="clr-namespace:sheepviewmodel;assembly=sheepviewmodel" mc:ignorable="d" title="scorescreen" height="300" width="300"> <window.datacontext> <vm:sheepviewmodel/> </window.datacontext> <grid> <textbox x:name="textblock" horizontalalignment="left" margin="79.374,116.672,0,0" textwrapping="wrap" text="{binding currenteventname, mode=twoway}" verticalalignment="top"/> </grid> again, no real code behind in this.
the strange thing, if make control 2 way , type in it, can see hitting same notify section, not updating other window.
i'm not sure missing here in pointing me in right direction appreciated.
that's because both windows must share exact same instance of viewmodel.
all properties instance properties, like
public string currenteventname { { // snip and therefore values distinct each instance. you're creating two instances, 1 each window.
<window x:class="sheep_score_3._1.mainwindow" xmlns:blah="http://inurxamlskippinurschemas.org"> <window.datacontext> <vm:sheepviewmodel/> </window.datacontext> that's 1 instance, , here's other
<window x:class="sheep_score_3._1.scorescreen" xmlns:blah="http://yaddayaddawhocares.derp"> <window.datacontext> <vm:sheepviewmodel/> </window.datacontext> remember, xaml markup deserialized object graph. you've got 2 different markup files, contain distinct instances of described within them.
there's nothing wrong this, , nothing wrong having view model instance properties. in fact, that's preferred way on using statics , static bindings.
the answer luckily simple. need hand both windows same instance of view model.
first, remove <window.datacontext> nonsense both of windows. that's not you. now, change constructor to
public mainwindow() { var viewmodel = new sheepviewmodel(); scorescreen sw = new scorescreen(); sw.datacontext = viewmodel; sw.show(); initializecomponent(); //notice! after init called! datacontext = viewmodel; } and you're done.
Comments
Post a Comment