动态高度和滚动基于堆栈面板中的可用空间

时间:2014-05-07 10:09:18

标签: wpf

这很难解释:

我有两个列表,每个列表可以包含大量项目,并且它们一个放在另一个上面,如下所示:

<StackPanel>
   <List Name="ListOne"/>
   <List Name="ListTwo"/>
</StackPanel>

ListOne在底部有一点点边缘,使它看起来很整洁。

堆栈面板包含在另一个具有固定高度的控件中。假设在两个列表溢出之前有足够的空间容纳8个项目。

我想要的是,当两个列表之间有8个项目时,没有滚动条,即使有不均匀的传播,如7-1,4-4,3-5等,一旦有超过8个元素然后出现一个滚动条,但只在需要的地方出现。

例如,如果ListOne有5个元素而ListTwo有4个元素,那么ListOne有一个滚动条,它们都是相同的高度,就好像它是6-3然后ListOne有一个滚动条并占用尽可能多的空间可以同时仍然给ListTwo足够的空间来显示而不需要滚动条。

知道怎么可能吗?不确定这是否有意义,但我很难解释它。如果您发表评论,我们会尽快回复。提前谢谢。

2 个答案:

答案 0 :(得分:0)

好的,所以我有一些东西似乎使用附加属性工作到一个不错的水平。

using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace Sus.Common.UI
{
    public class PanelHeightManagerExtension
    {
        public static readonly DependencyProperty ManageHeightsProperty =
           DependencyProperty.RegisterAttached("ManageHeights",
                                               typeof(bool),
                                               typeof(PanelHeightManagerExtension),
                                               new UIPropertyMetadata(false, OnManageHeightsChanged));


        public static bool GetManageHeights(DependencyObject obj)
        {
            return (bool)obj.GetValue(ManageHeightsProperty);
        }
        public static void SetManageHeights(DependencyObject obj, bool value)
        {
            obj.SetValue(ManageHeightsProperty, value);
        }
        private static void OnManageHeightsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = ((Panel)d);
            element.Loaded += (sender, args) => Update((Panel)sender);
        }


        private static void Update(Panel panel)
        {
            var children = panel.Children.OfType<FrameworkElement>().OrderBy(x=>x.ActualHeight).ToList();
            var remainingHeight = panel.DesiredSize.Height;
            for (int i = 0; i < children.Count; i++)
            {
                if (children[i].ActualHeight > remainingHeight / (children.Count - i))
                {
                    remainingHeight -= children[i].MaxHeight = remainingHeight / (children.Count - i);
                }
                else
                {
                    remainingHeight -= children[i].ActualHeight;
                    children[i].MaxHeight = children[i].ActualHeight;
                }
            }
        }
    }
}

您只需添加附加属性,如下所示:

<Grid ui:PanelHeightManagerExtension.ManageHeights="True">

仍然可以获得更好的答案

答案 1 :(得分:-1)

StackPanel将为其子级提供他们想要的所有空间,因此您可以看到如果ListOne包含足够的项目,ListOne可以将ListTwo推出视图。 您可以将StackPanel包装在ScrollViewer中,但我建议您使用Grid而不是

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ListBox x:Name="ListOne"/>
        <ListBox x:Name="ListTwo" Grid.Row="1"/>
    </Grid>