radpanelbar - WPF Expand RadPanelBarItem only in available space -
i have radpanelbar each radpanelitem having list of entities(different list in each item). each item in list shown groupbox. large number of items radpanelbar has scrolled in order other radpanelbaritems visible. want such scrollbar appears within each radpanelbaritem radpanelbaritems visible on screen @ same time , if contents of item long, user has scroll within each radpanelbaritem.
i'm using itemssource property of each radpanelbaritem , setting itemtemplate display groupboxes.
is there way this, everything(height , such) kept dynamic?
thanks!
there seems no easy way this. got following response telerik when asked similar question:
if got case correctly have several options:
1) set size panelbaritem. way limit how big be. if match items summed size size of panelbar should eliminate clippings.
2) customize panelbar , panelbaritem control templates in order support automatic proportional sizing. in case should remove scrollviewer panelbar control template , add scrollviewer in top level panelbaritem control template (around itemspresenter). should change radpanelbar itemspanel appropriate panel. probably. going custom panel in order measure items equal sizes vertically.
i have made try custom panel , modifying control template. have got working it's quite lot of code, here goes:
distributedheightpanel.cs
this custom panel layout , distributes available height.
/// <summary> /// panel distributes available height amongst it's children (like vertical stackpanel children not allowed placed "outside" parent's visual area). /// </summary> public class distributedheightpanel : panel { /// <summary> /// if set positive number, no child less height specified. /// </summary> public double itemsminheight { { return (double)getvalue(itemsminheightproperty); } set { setvalue(itemsminheightproperty, value); } } public static readonly dependencyproperty itemsminheightproperty = dependencyproperty.register("itemsminheight", typeof(double), typeof(distributedheightpanel), new uipropertymetadata(0.0)); public distributedheightpanel() : base() { } protected override size measureoverride(size availablesize) { list<double> heights = new list<double>(); //find out how height each child desire if child foreach (uielement child in internalchildren) { child.measure(availablesize); heights.add(child.desiredsize.height); } //calculate ratio double ratio = getratio(availablesize.height, heights); //do "real" measure foreach (uielement child in internalchildren) { double actualheight = child.desiredsize.height; if (ratio < 1) { //if ratio < 1 child can't have space wants, calculate new height actualheight = child.desiredsize.height * ratio; } if (itemsminheight > 0 && actualheight < itemsminheight) { //if itemsminheight set , child small, set childs height itemsminheight actualheight = itemsminheight; } child.measure(new size(availablesize.width, actualheight)); } return availablesize; } /// <summary> /// calculates ratio fitting heights in <paramref name="heightstodistribute"/> in total available height (as supplied in <paramref name="availableheight"/>) /// </summary> private double getratio(double availableheight, list<double> heightstodistribute) { //copy heights list list<double> heights = new list<double>(heightstodistribute); double desiredtotalheight = heights.sum(); //if no height desired return 1 if (desiredtotalheight <= 0) return 1; //calculate ratio double ratio = availableheight / desiredtotalheight; //we want compress if ratio higher 1 return 1 if (ratio > 1) { return 1; } //check if heights become small when ratio used int toosmallcount = heights.count(d => d * ratio < itemsminheight); //if no or all heights small: return calculated ratio if (toosmallcount == 0 || toosmallcount == heights.count) { return ratio; } else { //remove items becomes small , ratio without them (they itemsminheight) heights.removeall(d => d * ratio < itemsminheight); return getratio(availableheight - itemsminheight * toosmallcount, heights); } } protected override size arrangeoverride(size finalsize) { //arrange children vertical stackpanel double y = 0; foreach (uielement child in internalchildren) { //child.desiredsize.height contains correct value since calculated in measureoverride child.arrange(new rect(0, y, finalsize.width, child.desiredsize.height)); y += child.desiredsize.height; } return finalsize; } } mainwindow.xaml
contains control template style named distributedheightradpanelbarstyle , radpanelbar testing.
<window x:class="wpfapplication9.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:wpfapplication9" title="mainwindow" height="350" width="525" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"> <window.resources> <style x:key="distributedheightradpanelbarstyle" targettype="{x:type telerik:radpanelbar}"> <setter property="itemspanel"> <setter.value> <itemspaneltemplate> <local:distributedheightpanel itemsminheight="22" /> <!-- 22 fine collapsed headers --> </itemspaneltemplate> </setter.value> </setter> <setter property="template"> <setter.value> <controltemplate targettype="{x:type telerik:radpanelbar}"> <grid> <telerik:layouttransformcontrol x:name="transformationroot" istabstop="false"> <border borderbrush="{templatebinding borderbrush}" borderthickness="{templatebinding borderthickness}" background="{templatebinding background}"> <!-- <scrollviewer x:name="scrollviewer" horizontalcontentalignment="{templatebinding horizontalcontentalignment}" horizontalscrollbarvisibility="auto" istabstop="false" padding="{templatebinding padding}" verticalscrollbarvisibility="auto" verticalcontentalignment="{templatebinding verticalcontentalignment}">--> <telerik:stylemanager.theme> <telerik:office_blacktheme/> </telerik:stylemanager.theme> <itemspresenter/> <!--</scrollviewer>--> </border> </telerik:layouttransformcontrol> </grid> <controltemplate.triggers> <trigger property="orientation" value="horizontal"> <setter property="layouttransform" targetname="transformationroot"> <setter.value> <rotatetransform angle="-90"/> </setter.value> </setter> </trigger> </controltemplate.triggers> </controltemplate> </setter.value> </setter> <setter property="orientation" value="vertical"/> </style> </window.resources> <grid> <telerik:radpanelbar style="{staticresource resourcekey=distributedheightradpanelbarstyle}" verticalalignment="top" expandmode="multiple" horizontalalignment="stretch"> <telerik:radpanelbaritem dropposition="inside" header="a - colors" isexpanded="true"> <scrollviewer verticalscrollbarvisibility="auto"> <stackpanel> <textblock height="100" background="aliceblue" text="i'm aliceblue" /> <textblock height="100" background="antiquewhite" text="i'm antiquewhite" /> </stackpanel> </scrollviewer> </telerik:radpanelbaritem> <telerik:radpanelbaritem dropposition="inside" header="b - colors" isexpanded="true"> <scrollviewer verticalscrollbarvisibility="auto"> <stackpanel> <textblock height="100" background="beige" text="i'm beige" /> <textblock height="100" background="bisque" text="i'm bisque" /> </stackpanel> </scrollviewer> </telerik:radpanelbaritem> <telerik:radpanelbaritem dropposition="inside" header="c - colors"> <scrollviewer verticalscrollbarvisibility="auto"> <stackpanel> <textblock height="100" background="cadetblue" text="i'm cadetblue" /> <textblock height="100" background="chartreuse" text="i'm chartreuse" /> </stackpanel> </scrollviewer> </telerik:radpanelbaritem> </telerik:radpanelbar> </grid> maybe solution late use find useful.
Comments
Post a Comment