c# - Why does binding the MainWindow datacontext in XAML fail to act the same as binding in the codebehind with this.datacontext=this? -
i trying use data binding bind observablecollection itemssource of datagrid, learn wpf , stuff.
in code-behind can set datacontext this.datacontext = this;
or bloopdatagrid.datacontext = this;
. that's fine , dandy.
i thought try like
<window.datacontext> <local:mainwindow/> </window.datacontext>
in main window, causes stack overflow exception explained in this question. fine, makes sense.
after reading this , other questions/answers try datacontext="{binding relativesource={relativesource self}}"
in window's xaml code, thought actually this. apparently cannot. or @ least, ide lets me , it's syntactically correct, not want (ie, this.datacontext = this;
does).
then read this using "{binding elementname=, path=}"
, tried use so:
<datagrid name="bloopdatagrid" grid.row="1" itemssource="{binding elementname=testwin, path=outputcollection}"> </datagrid>
which doesn't work. maybe not same reason, can't figure out problem it.
oddly, can't replicate rebinding example shown in rachel lim's blog post.
xaml:
<window x:class="databinding.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" title="mainwindow" height="350" width="525" x:name="testwin"> <grid> <grid.rowdefinitions> <rowdefinition /> <rowdefinition /> </grid.rowdefinitions> <label grid.row="0" content="{binding text}"> </label> <datagrid name="bloopdatagrid" grid.row="1" itemssource="{binding path=outputcollection}"> </datagrid> </grid> </window>
c#:
using system; using system.collections.objectmodel; //for observablecollection<t> using system.windows; namespace databinding { public partial class mainwindow : window { public string text { get; set; } public observablecollection<teststruct> outputcollection { get; set; } public struct teststruct { public teststruct(string x, string y) : this() { col1 = x; col2 = y; } public string col1 { get; set; } public string col2 { get; set; } } public mainwindow() { initializecomponent(); testa t1 = new testa(); this.datacontext = this; //this.datacontext = t1; //bloopdatagrid.datacontext = this; text = "bound \"this\""; t1.text = "bound class"; outputcollection = new observablecollection<teststruct>(); outputcollection.add(new teststruct("1", "2")); outputcollection.add(new teststruct("3", "4")); } public class testa { public string text { get; set; } } } }
the above code i'm using test this, , using code-behind version correctly gives me
what doing wrong, preventing me getting same results above picture using xaml datacontext handling? not connecting dots properly? ...am missing dots?
<window.datacontext> <local:mainwindow/> </window.datacontext>
is not same
this.datacontext = this;
the first 1 creating new instance of mainwindow
class , assigning datacontext
property of window
, while second assigning same instance of window
datacontext
property.
in order achieve in xaml, need use relativesource
binding:
<window datacontext="{binding relativesource={relativesource self}}"> </window>
edit:
the difference in behavior between defining datacontext
in xaml , in code behind caused fact xaml parsed when constructor finishes executing, because dispatcher
waits user code (in constructor of window) finish before executing pending operations.
this causes actual property values different in these different moments, , since there no inotifypropertychanged
, wpf has no way of updating ui reflect new values.
you could
implement inotifypropertychanged
in window
itself, suggest creating viewmodel this, don't fact of mixing inotifypropertychanged
(which more of viewmodel concept) dependencyobject
-derived classes (ui elements).
Comments
Post a Comment