c# - Binding properties (width/sorting) of DataGrid on dynamic TabPage -


i've created little wpf test project demonstrate question. project contains single wpf window. window contains tabcontrol. pages of tabcontrol created dynamically bound itemsource.

so here xaml:

<window x:name="window" x:class="testwpf.mainwindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:vm="clr-namespace:testwpf"     title="mainwindow" height="350" width="525">     <tabcontrol x:name="tabcontrol" borderthickness="0" itemssource ="{binding medialists, elementname=window, notifyonsourceupdated=true}">         <tabcontrol.itemtemplate>             <datatemplate datatype="{x:type vm:medialist}">                 <textblock padding="2" text="{binding mediatypename}" horizontalalignment="center" verticalalignment="center"/>             </datatemplate>         </tabcontrol.itemtemplate>         <tabcontrol.contenttemplate>             <datatemplate x:name="contenttemplate" datatype="{x:type vm:medialist}">                 <datagrid x:name="dgmedialist" itemssource="{binding medias, bindsdirectlytosource=true}" dockpanel.dock="top" autogeneratecolumns="false" horizontalgridlinesbrush="{dynamicresource {x:static systemcolors.activeborderbrushkey}}" verticalgridlinesbrush="{dynamicresource {x:static systemcolors.activeborderbrushkey}}">                     <datagrid.columns>                         <datagridtextcolumn x:name="clmauthor" header="author" binding="{binding author}" isreadonly="true" canuserreorder="false" />                     <datagridtextcolumn x:name="clmtitle" header="title" binding="{binding title}" isreadonly="true" canuserreorder="false" />                     </datagrid.columns>                 </datagrid>             </datatemplate>         </tabcontrol.contenttemplate>     </tabcontrol> </window> 

and code behind this:

public partial class mainwindow : window {     private readonly observablecollection<medialist> m_medialists = new observablecollection<medialist>();     public observablecollection<medialist> medialists { { return m_medialists; } }      public mainwindow()     {         initializecomponent();         medialist cdlist = new medialist("cds");         cdlist.medias.add(new media("authorcda", "titlecda1"));         cdlist.medias.add(new media("authorcda", "titlecda2"));         cdlist.medias.add(new media("authorcdb", "titlecdb1"));         cdlist.medias.add(new media("authorcdb", "titlecdb2"));          medialist booklist = new medialist("books");         booklist.medias.add(new media("authorbooka", "titlebooka1"));         booklist.medias.add(new media("authorbooka", "titlebooka2"));         booklist.medias.add(new media("authorbookb", "titlebookb1"));         booklist.medias.add(new media("authorbookb", "titlebookb2"));          m_medialists.add(cdlist);         m_medialists.add(booklist);     } } 

with medialist this:

public class medialist : inotifypropertychanged {     public event propertychangedeventhandler propertychanged;     protected virtual void onpropertychanged(string propertyname)     {         propertychangedeventhandler handler = propertychanged;         if (handler != null) handler(this, new propertychangedeventargs(propertyname));     }      private readonly observablecollection<media> m_medias = new observablecollection<media>();      public string mediatypename { get; private set; }     public observablecollection<media> medias { { return m_medias; }}      public medialist(string typename)     {         mediatypename = typename;     } } 

and media this:

public class media {     public string author { get; private set; }     public string title { get; private set; }     public media(string author, string title)     {         author = author;         title = title;     } } 

so works fine can see here:

enter image description here

now problem: how save datagrid's layout each tabpage? when switch between tabpages, column width kept same pages, sorting lost completely.

i want bind column widths of datagrid multi-column sort settings changed user in members of medialist instance.

so keep question short, let's concentrate on column widths. added members medialist class:

private datagridlength m_widthauthor = datagridlength.sizetocells; private datagridlength m_widthtitle = datagridlength.sizetocells; public datagridlength widthauthor {     { return m_widthauthor; }     set     {         if (value == m_widthauthor) return;         m_widthauthor = value;         onpropertychanged("widthauthor");     } } public datagridlength widthtitle {     { return m_widthtitle; }     set     {         if (value == m_widthtitle) return;         m_widthtitle = value;         onpropertychanged("widthtitle");     } } 

and tried set binding in xaml:

<datagridtextcolumn x:name="clmauthor" ... width="{binding widthauthor, mode=twoway, notifyonsourceupdated=true, updatesourcetrigger=propertychanged}" /> <datagridtextcolumn x:name="clmtitle" ... width="{binding widthtitle, mode=twoway, notifyonsourceupdated=true, updatesourcetrigger=propertychanged}" /> 

but unfortunatly, doesn't work. i've read on several articles two-way binding difficult. one-way binding won't work me. (i'm pretty new wpf/mvvm, maybe use wrong words here...)

in debugger output window can see these error message width-bindings:

system.windows.data error: 2 : cannot find governing frameworkelement or frameworkcontentelement target element. bindingexpression:path=widthauthor; dataitem=null; target element 'datagridtextcolumn' (hashcode=54916642); target property 'width' (type 'datagridlength') system.windows.data error: 2 : cannot find governing frameworkelement or frameworkcontentelement target element. bindingexpression:path=widthtitle; dataitem=null; target element 'datagridtextcolumn' (hashcode=40809782); target property 'width' (type 'datagridlength') 

so if can tell me how save datagrid properties each tabpage happy. focus of question on widths. sorting may subject of new question (note binding sortdirection of columns won't work multi-column sort)

edit: i've added diag:presentationtracesources.tracelevel=high binding expression 1 of columns width , found these messages in debug output:

system.windows.data warning: 62 : bindingexpression (hash=18270086): attach system.windows.controls.datagridtextcolumn.width (hash=37671782) system.windows.data warning: 64 : bindingexpression (hash=18270086): use framework mentor <null> system.windows.data warning: 67 : bindingexpression (hash=18270086): resolving source  system.windows.data warning: 69 : bindingexpression (hash=18270086): framework mentor not found system.windows.data warning: 65 : bindingexpression (hash=18270086): resolve source deferred 

i'm new wpf understand framework mentor , if should null.

i solved of this article. unfortunately wpf knowledge still low cannot explain (as author of mentioned article) happens behind scenes , if solution.

so here did:

implementing `bindingproxy` inherited `freezable`

one of problems datacontext not inherited datagridtextcolumn. aim store in proxy.

public class bindingproxy : freezable {     protected override freezable createinstancecore()     {         return new bindingproxy();     }      public object data     {         { return getvalue(data_property); }         set { setvalue(data_property, value); }     }      // using dependencyproperty backing store data.  enables animation, styling, binding, etc...     public static readonly dependencyproperty data_property =         dependencyproperty.register("data", typeof(object), typeof(bindingproxy), new uipropertymetadata(null)); } 

declaring instance of `bindingproxy` local resource in `datagrid`

i added local resource datagrid in xaml:

<datagrid.resources>     <vm:bindingproxy x:key="proxy" data="{binding}" /> </datagrid.resources> 

adjusting binding

at last modify binding expression datagridtextcolum's width:

width="{binding data.widthauthor, source={staticresource proxy}.... 

et voilá, works!

i continue research on how multi-column sort. if can't find solution open new question. if no 1 adds solution in next days, accept own answer.

update: solved multi-column sort problem here.


Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

css - Can I use the :after pseudo-element on an input field? -