当ScrollBar变为可见时,WPF Scrollviewer DesiredSize不会增加

时间:2013-02-19 16:58:19

标签: wpf resize scrollbar scrollviewer elementhost

我有一个WPF UserControl(位于ElementHost内),ScrollViewer包含ItemsControlHorizontalScrollbarVisibility设置为Auto,因此如果不需要滚动,ScrollBar将被隐藏。

我的要求是,如果显示/隐藏ScrollBarElementHost会相应地调整它的高度。为实现这一目标,我正在收听SizeChanged事件,我获得了DesiredSizeScrollViewer的{​​{1}},然后我通过EventHandlerDesiredSize.Height

  1. visible 2. hidden 3. incorrect, overlaid
  2. 一种方法,这样做:ElementHost可见(情况1),我放大窗口,直到ScrollBar的所有项目都可见,ItemsControl消失,{{1调整到降低的高度(情况2)。 <{1}}实际上在隐藏ScrollBar时变小了。

    另一方面,它不起作用:ElementHost不可见(情况2),我缩小窗口大小,直到需要DesiredSize并出现。 ScrollBar保持不变,ScrollBar无法调整(情况3)。

    有什么想法吗?

    这是ScrollBar的xaml,有一些MVVM的东西,但是不要挂在这上面,关键是,为什么DesiredSizeElementHost没有增加时{ {1}}出现了?它为什么只缩小?

    Scrollviewer

    ScrollViewer样式(基本上是默认的WPF):

    DesiredSize

1 个答案:

答案 0 :(得分:0)

我必须通过获取ScrollViewer的内容所需高度来计算所需的高度,并在可见时添加ScrollBar高度。

这对我来说仍然感觉有点尴尬,所以如果你有更好的解决方案,我会很乐意改变接受的答案。

public class HeightChangedBehavior : Behavior<ScrollViewer>
{
    public ICommand HeightChangedCommand { get { return (ICommand)GetValue(HeightChangedCommandProperty); } set { SetValue(HeightChangedCommandProperty, value); } }
    public static readonly DependencyProperty HeightChangedCommandProperty = DependencyProperty.Register("HeightChangedCommand", typeof(ICommand), typeof(HeightChangedBehavior), new PropertyMetadata(null));


    protected override void OnAttached()
    {
        this.AssociatedObject.ScrollChanged += AssociatedObject_ScrollChanged;
        base.OnAttached();
    }

    /// <summary>
    /// Calculates the desired height for the scrollviewer, as the sum of its content
    /// desired height and, if visible, the horizontal scrollbar height.
    /// </summary>
    void AssociatedObject_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        ScrollViewer sv = (ScrollViewer)sender;

        // get content height
        double height = ((FrameworkElement)sv.Content).DesiredSize.Height;

        if (sv.ComputedHorizontalScrollBarVisibility == Visibility.Visible)
        {
            // add scrollbar height
            height += (double)sv.FindResource(SystemParameters.HorizontalScrollBarHeightKey); // template of scrollbar should use this key
        }

        int intHeight = (int)Math.Ceiling(height); // whole pixels

        // execute the command
        ICommand cmd = this.HeightChangedCommand;
        if (cmd != null && intHeight != sv.ActualHeight)
            cmd.Execute(intHeight);
    }
}