2012-06-04 15 views
1

我有一個RadPanelBar,每個RadPanelItem都有一個實體列表(每個項目中的不同列表)。列表中的每個項目都顯示爲一個GroupBox。對於大量的項目,RadPanelBar必須滾動以便其他RadPanelBarItems可見。我希望滾動條出現在每個RadPanelBarItem中,以便所有的RadPanelBarItems將同時在屏幕上可見,並且如果項目的內容太長,用戶必須僅在每個RadPanelBarItem中滾動。WPF只在可用空間中展開RadPanelBarItem

我正在使用每個RadPanelBarItem的ItemsSource屬性並將其ItemTemplate設置爲顯示GroupBoxes。

是否有一個很好的方法來做到這一點,以便一切(高度等)保持動態?

謝謝!

+0

你有沒有設法解決你的問題?我處於類似的情況尋找解決方案。 –

+0

不幸的不是。 –

回答

1

似乎沒有簡單的方法來做到這一點。我從Telerik的以下響應,當我問一個類似的問題:

如果我有你的情況下正確,您有幾種選擇:

1)設置大小PanelBarItem。這樣你就會限制他們可能會有多大。如果 您將項目的總大小與PanelBar的大小相匹配,您應該刪除剪報。

2)按照 的順序自定義PanelBar和PanelBarItem控件模板以支持自動比例調整。在這種情況下,您應該從PanelBar控件模板中刪除ScrollViewer,並在頂級PanelBarItem控件模板中添加一個 ScrollViewer(大約 ItemsPresenter)。還應該將RadPanelBar ItemsPanel更改爲 適當的面板。大概。它將成爲 中的自定義面板,以便垂直測量具有相同尺寸的項目。

我已經嘗試做一個自定義面板並修改控件模板。我已完成了工作,但它是一個相當大量的代碼,但在這裏有雲:

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> 

也許這個解決方案是爲時已晚供您使用,但希望有人會發現它很有用。

相關問題