.net - WPF ItemsControl horizontal orientation and fill parent? -
i trying horizontally place items in itemcontrol whilst making them fill parent control.
here xaml:
<itemscontrol itemssource="{binding annualweatherviewmodels}" visibility="{binding isannualweatherviewmodels, converter={staticresource visibilityconverter}}"> <itemscontrol.itemspanel> <itemspaneltemplate> <stackpanel orientation="horizontal"></stackpanel> </itemspaneltemplate> </itemscontrol.itemspanel> <itemscontrol.itemtemplate> <datatemplate> <v:aerosolsimpleweathercharacteristicsview datacontext="{binding}"></v:aerosolsimpleweathercharacteristicsview> </datatemplate> </itemscontrol.itemtemplate> </itemscontrol>
the 2 variations have tried itemscontrol.itemspanel
are:
<stackpanel orientation="horizontal"></stackpanel>
and:
<dockpanel lastchildfill="false"></dockpanel>
however neither achieve desired result, stackpanel
compresses items , dockpanel
either fill space of parent control large portion of space dedicated last item or not fill parent space depending on value of lastchildfill
.
so how can layout items of itemscontrol
horizontally , have them fill space of parent control?
i ended creating custom control sugested in answer:
public partial class stretchingpanel : grid { public static readonly dependencyproperty orientationproperty = dependencyproperty.register("orientation", typeof(orientation), typeof(stretchingpanel), new uipropertymetadata(system.windows.controls.orientation.horizontal)); public static readonly dependencyproperty fillfirstitemproperty = dependencyproperty.register("fillfirstitem", typeof(bool), typeof(stretchingpanel), new uipropertymetadata(true)); public static readonly dependencyproperty fillfirstitemfactorproperty = dependencyproperty.register("fillfirstitemfactor", typeof(double), typeof(stretchingpanel), new uipropertymetadata(1.8)); public orientation orientation { { return (orientation)getvalue(orientationproperty); } set { setvalue(orientationproperty, value); } } public bool fillfirstitem { { return (bool)getvalue(fillfirstitemproperty); } set { setvalue(fillfirstitemproperty, value); } } public double fillfirstitemfactor { { return (double)getvalue(fillfirstitemfactorproperty); } set { setvalue(fillfirstitemfactorproperty, value); } } protected override void onvisualchildrenchanged(dependencyobject visualadded, dependencyobject visualremoved) { if (orientation == system.windows.controls.orientation.horizontal) { columndefinitions.clear(); (int = 0; < children.count; ++i) { var column = new columndefinition(); if (i == 0 && fillfirstitem) column.width = new gridlength(fillfirstitemfactor, gridunittype.star); columndefinitions.add(column); grid.setcolumn(children[i], i); } } else { rowdefinitions.clear(); (int = 0; < children.count; ++i) { var row = new rowdefinition(); if (i == 0 && fillfirstitem) row.height = new gridlength(fillfirstitemfactor, gridunittype.star); rowdefinitions.add(row); grid.setrow(children[i], i); } } base.onvisualchildrenchanged(visualadded, visualremoved); } public stretchingpanel() { initializecomponent(); } }
so want proportionally stretch items. if achievable @ standard panels, it's grid (which can have proportional columns), require setting columndefinitions after itemsource changes.
it's simple custom panel:
class proportionallystretchingpanel : panel { protected override size measureoverride(size availablesize) { foreach (uielement child in internalchildren) child.measure(availablesize); return availablesize; } protected override size arrangeoverride(size availablesize) { double widthsum = 0.0; foreach (uielement child in internalchildren) { widthsum += child.desiredsize.width; } double x = 0.0; foreach (uielement child in internalchildren) { double proportionalwidth = child.desiredsize.width / widthsum * availablesize.width; child.arrange( new rect( new point(x, 0.0), new point(x + proportionalwidth, availablesize.height))); x += proportionalwidth; } return availablesize; } } <itemspaneltemplate> <local:proportionallystretchingpanel"/> </itemspaneltemplate>
Comments
Post a Comment