我有一个RadPanelBar,每个RadPanelItem都有一个实体列表(每个Item中的不同列表)。 List中的每个项目都显示为GroupBox。对于大量项目,必须滚动RadPanelBar,以便其他RadPanelBarItem可见。我希望滚动条出现在每个RadPanelBarItem中,以便所有RadPanelBarItems同时在屏幕上可见,如果项目的内容太长,用户只需在每个RadPanelBarItem内滚动。
我正在使用每个RadPanelBarItem的ItemsSource属性并设置其ItemTemplate以显示GroupBox。
有没有一种好方法可以做到这一点,所以一切(高度等)都保持动态?
谢谢!
答案 0 :(得分:1)
似乎没有简单的方法可以做到这一点。当我问一个类似的问题时,我得到了Telerik的以下回复:
如果我的案例正确,你有几个选择:
1)设置PanelBarItem的大小。这样你就可以限制它们的大小。如果 你将项目总和大小与PanelBar的大小相匹配 消除剪报。
2)按顺序自定义PanelBar和PanelBarItem控件模板 支持自动比例尺寸调整。在这种情况下你应该 从PanelBar控件模板中删除ScrollViewer并添加一个 ScrollViewer在顶级PanelBarItem控件模板中(周围 ItemsPresenter)。您还应将RadPanelBar ItemsPanel更改为 适当的小组。大概。它将是一个自定义面板 为了垂直测量相同尺寸的物品。
我尝试过自定义Panel并修改控件模板。我有它工作,但它是相当多的代码,但在这里:
<强> DistributedHeightPanel.cs 强>
这是自定义面板,用于布局并分配可用高度。
/// <summary>
/// Panel that distributes the available height amongst it's children (like a vertical StackPanel but the children are not allowed to be placed "outside" the parent's visual area).
/// </summary>
public class DistributedHeightPanel : Panel
{
/// <summary>
/// If set to a positive number, no child will get less height than specified.
/// </summary>
public double ItemsMinHeight
{
get { 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 much height each child desire if it was the only child
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
heights.Add(child.DesiredSize.Height);
}
//Calculate ratio
double ratio = GetRatio(availableSize.Height, heights);
//Do the "real" Measure
foreach (UIElement child in InternalChildren)
{
double actualHeight = child.DesiredSize.Height;
if (ratio < 1)
{
//If ratio < 1 then the child can't have all the space it wants, calculate the new height
actualHeight = child.DesiredSize.Height * ratio;
}
if (ItemsMinHeight > 0 && actualHeight < ItemsMinHeight)
{
//If ItemsMinHeight is set and the child is to small, then set the childs height to ItemsMinHeight
actualHeight = ItemsMinHeight;
}
child.Measure(new Size(availableSize.Width, actualHeight));
}
return availableSize;
}
/// <summary>
/// Calculates the ratio for fitting all heights in <paramref name="heightsToDistribute"/> in the total available height (as supplied in <paramref name="availableHeight"/>)
/// </summary>
private double GetRatio(double availableHeight, List<double> heightsToDistribute)
{
//Copy the heights list
List<double> heights = new List<double>(heightsToDistribute);
double desiredTotalHeight = heights.Sum();
//If no height is desired then return 1
if (desiredTotalHeight <= 0)
return 1;
//Calculate ratio
double ratio = availableHeight / desiredTotalHeight;
//We only want to compress so if ratio is higher than 1 return 1
if (ratio > 1)
{
return 1;
}
//Check if heights become too small when the ratio is used
int tooSmallCount = heights.Count(d => d * ratio < ItemsMinHeight);
//If no or all all heights are too small: return the calculated ratio
if (tooSmallCount == 0 || tooSmallCount == heights.Count)
{
return ratio;
}
else
{
//Remove the items which becomes too small and get a ratio without them (they will get ItemsMinHeight)
heights.RemoveAll(d => d * ratio < ItemsMinHeight);
return GetRatio(availableHeight - ItemsMinHeight * tooSmallCount, heights);
}
}
protected override Size ArrangeOverride(Size finalSize)
{
//Arrange all children like a vertical StackPanel
double y = 0;
foreach (UIElement child in InternalChildren)
{
//child.DesiredSize.Height contains the correct value since it was calculated in MeasureOverride
child.Arrange(new Rect(0, y, finalSize.Width, child.DesiredSize.Height));
y += child.DesiredSize.Height;
}
return finalSize;
}
}
<强> MainWindow.xaml 强>
将控件模板包含为名为DistributedHeightRadPanelBarStyle的样式和用于测试的RadPanelBar。
<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 is fine for 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>
也许这个解决方案对你来说太晚了,但希望有人会发现它很有用。