1

各RadPanelItemにエンティティのリスト(各アイテムの異なるリスト)を持つRadPanelBarがあります。List 内の各項目は GroupBox として表示されます。多数の項目がある場合、他の RadPanelBarItems を表示するには、RadPanelBar をスクロールする必要があります。スクロールバーが各 RadPanelBarItem 内に表示されるようにして、すべての RadPanelBarItems が同時に画面に表示され、アイテムのコンテンツが長すぎる場合、ユーザーは各 RadPanelBarItem 内でのみスクロールする必要があります。

各 RadPanelBarItem の ItemsSource プロパティを使用し、その ItemTemplate を設定して GroupBoxes を表示しています。

すべて(高さなど)が動的に保たれるように、これを行う良い方法はありますか?

ありがとう!

4

1 に答える 1

2

これを行う簡単な方法はないようです。同様の質問をしたときに、Telerikから次の応答がありました。

私があなたのケースを正しく受け取った場合、あなたにはいくつかの選択肢があります:

1)PanelBarItemのサイズを設定します。このようにして、それらの大きさを制限します。アイテムの合計サイズをPanelBarのサイズに一致させる場合は、クリッピングを削除する必要があります。

2)自動比例サイジングをサポートするために、PanelBarおよびPanelBarItemコントロールテンプレートをカスタマイズします。この場合、PanelBarコントロールテンプレートからScrollViewerを削除し、最上位のPanelBarItemコントロールテンプレート(ItemsPresenterの周囲)にScrollViewerを追加する必要があります。また、RadPanelBarItemsPanelを適切なパネルに変更する必要があります。おそらく。縦に同じサイズのアイテムを測定するためのカスタムパネルになります。

カスタムパネルを実行して、コントロールテンプレートを変更しようとしました。私はそれを動作させましたが、それはかなり多くのコードですが、ここに行きます:

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>

たぶん、この解決策はあなたが使うには遅すぎますが、うまくいけば誰かがそれが役に立つと思うでしょう。

于 2012-07-11T16:18:16.440 に答える