c# - Relative Column Widths Not Working When DataGrid is Nested Inside A Grouped DataGrid -


suppose have object 6 attributes:

public class myclass {     public string attribute1 { get; set; }     public string attribute2 { get; set; }     public string attribute3 { get; set; }     public string attribute4 { get; set; }     public string attribute5 { get; set; }     public string attribute6 { get; set; } } 

i display collection of these objects in datagrid:

<grid>     <datagrid x:name="mygrid" margin="5, 5, 5, 5" autogeneratecolumns="false" canuseraddrows="false" isreadonly="true">         <datagrid.groupstyle>             <groupstyle containerstyle="{staticresource groupheaderstyle}">                 <groupstyle.panel>                     <itemspaneltemplate>                         <datagridrowspresenter/>                     </itemspaneltemplate>                 </groupstyle.panel>             </groupstyle>         </datagrid.groupstyle>         <datagrid.columns>             <datagridtextcolumn header="attribute1" binding="{binding attribute1}" width="5*"/>             <datagridtextcolumn header="attribute2" binding="{binding attribute2}" width="5*"/>             <datagridtextcolumn header="attribute3" binding="{binding attribute3}" width="10*"/>         </datagrid.columns>     </datagrid> </grid> 

i populate grid this, grouping "attribute1"...

    public mainwindow()     {         initializecomponent();          observablecollection<myclass> data = new observablecollection<myclass>();         data.add(new myclass { attribute1 = "red", attribute4 = "circle", attribute5 = "large", attribute6 = "transparent" });         data.add(new myclass { attribute1 = "red", attribute4 = "square", attribute5 = "medium", attribute6 = "opaque" });         data.add(new myclass { attribute1 = "red", attribute4 = "triangle", attribute5 = "large", attribute6 = "opaque" });         data.add(new myclass { attribute1 = "yellow", attribute4 = "square", attribute5 = "large", attribute6 = "transparent" });         data.add(new myclass { attribute1 = "blue", attribute4 = "triangle", attribute5 = "small", attribute6 = "transparent" });         data.add(new myclass { attribute1 = "blue", attribute4 = "sphere", attribute5 = "small", attribute6 = "opaque" });           listcollectionview lcv = new listcollectionview(data);         lcv.groupdescriptions.add(new propertygroupdescription("attribute1"));         mygrid.itemssource = lcv;      } 

i style groupitems show nested datagrid within expander:

<window.resources>     <style x:key="groupheaderstyle" targettype="{x:type groupitem}">         <setter property="template">             <setter.value>                 <controltemplate targettype="{x:type groupitem}">                     <expander x:name="exp" isexpanded="true" foreground="black">                         <expander.header>                                 <textblock foreground="black" text="{binding name}"/>                         </expander.header>                         <dockpanel>                             <datagrid itemssource="{binding items}" x:name="subgrid" autogeneratecolumns="false" isreadonly="true" canuseraddrows="false">                                 <datagrid.columns>                                     <datagridtextcolumn header="attribute 4" binding="{binding attribute4}" width="auto"/>                                     <datagridtextcolumn header="attribute 5" binding="{binding attribute5}" width="auto"/>                                     <datagridtextcolumn header="attribute 6" binding="{binding attribute6}" width="auto"/>                                 </datagrid.columns>                             </datagrid>                         </dockpanel>                     </expander>                 </controltemplate>             </setter.value>         </setter>     </style> </window.resources> 

with nested datagrid column widths set "auto"... works great:

enter image description here

the problem when try use relative widths...

<datagrid itemssource="{binding items}" x:name="subgrid" autogeneratecolumns="false" isreadonly="true" canuseraddrows="false">     <datagrid.columns>         <datagridtextcolumn header="attribute 4" binding="{binding attribute4}" width="1*"/>         <datagridtextcolumn header="attribute 5" binding="{binding attribute5}" width="1*"/>         <datagridtextcolumn header="attribute 6" binding="{binding attribute6}" width="2*"/>     </datagrid.columns> </datagrid> 

now looks this... enter image description here

not columns super skinny... not re-sizable mouse, usual.

this issue has me puzzled. i've searched , tried several somewhat-related issues without luck.

how can set columns on nested datagrid use relative widths?

i think problem wpf doesn't know how wide dockpanel skinny columns.

one solution set width of dockpanel (or datagrid) fixed width 500 pixels.

another solution bind width of datagrid actualwidth of dockpanel. works datagrid grow in size, not shrink when window gets smaller.

<datagrid itemssource="{binding items}"            x:name="subgrid"            autogeneratecolumns="false"            isreadonly="true"            canuseraddrows="false"            width="{binding                    relativesource={relativesource ancestortype=dockpanel}, path=actualwidth}"> 

yet solution bind width of dockpanel actualwidth of expander. problem doesn't work right... expander gets bigger because dockpanel gets bigger , loop. want actualwidth of expander minus enough not cause expander increase it's width. i've experimented bit , "actualwidth - 3" seems works (but idk why 3...). if add paddings or margins, 3 may need change. binding, need ivalueconverter.

public class actualwidthconverter : ivalueconverter {     public object convert(object value, type targettype, object parameter, system.globalization.cultureinfo culture)     {         if (value double)             return (double)value - 3;         return value;     }     public object convertback(object value, type targettype, object parameter, system.globalization.cultureinfo culture)     {         throw new notimplementedexception();     } } 

you'll need add converter resource (app or window or whatever):

<window ....     xmlns:app="clr-namespace:wpfapplication25"> <window.resources>     <app:actualwidthconverter x:key="actualwidthconverter" /> </window.resources> 

and, of course, you'll need binding applied width of dockpanel:

<dockpanel width="{binding relativesource={relativesource ancestortype=expander}, path=actualwidth, converter={staticresource actualwidthconverter}}"> 

it's not perfect solution maybe it'll helpful? alternative version of method use multibinding; passing in expander's actualwidth , dockpanel's margin: actualwidth - margin.left - margin.right - 3 (i'm still wondering why 3? , 3 on else's computer too?).


Comments

Popular posts from this blog

c++ - No viable overloaded operator for references a map -

java - Custom OutputStreamAppender not run: LOGBACK: No context given for <MYAPPENDER> -

java - Cannot secure connection using TLS -