简体   繁体   中英

How to find the actual scrollbar height inside a scrollviewer control

I'm trying to make smart scrolling for a canvas that expands in size. I want the scrollbars to automatically go to the center of their range. So I use:

eagleViewer.ScrollToVerticalOffset(drawingSpace.Height/2);
eagleViewer.ScrollToHorizontalOffset(drawingSpace.Width/2);

Which works but when the scrollbars scroll they go beyond the half point, it seems it's top aligned. So I wanted to subtract the scrollbar Height or Width so the scrollbars would be perfectly centered at the canvas.

I read in other posts that I can do this is at

SystemParameters.ScrollHeight 

or

SystemParameters.ScrollWidth

But how does that work? I have multiple scrollviewers in the window. I want the height or width of the scrollbars of this specific scrollviewer.

Any other way I'm not aware off?

Thanks

Edit:

Adding XAML section:

<ScrollViewer Name="eagleViewer" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" Height="Auto" Width="Auto">
                        <Grid Name="eagleGrid" Background="LightGray">
                            <Canvas Name="drawingSpace" Background="WhiteSmoke" Width="100" Height="100">
                                <Canvas.LayoutTransform>
                                    <ScaleTransform CenterX="0" CenterY="0" ScaleX="{Binding ElementName=zoomEagleSlider,Path=Value}" ScaleY="{Binding ElementName=zoomEagleSlider,Path=Value}"/>
                                </Canvas.LayoutTransform>
                            </Canvas>
                        </Grid>
                    </ScrollViewer>

I add another answer here because I like to post some more code. You gave the right keyword: "The canvas height change happens on the line before i run the scrolltoverticaloffset code". By doing this I can reproduce the problem. The problem is the ScrollViewer obviously evaluates the ScrollableHeight property at a later point. Which means you need to delay using ScrollableHeight. It is a bit tricky to find the right point. In my following test application I use the first ScrollChanged event after the content's height was changed to center the scrollbar.

<Window x:Class="ScrollViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Grid>
        <ScrollViewer Name="SV"
                      Margin="71,62,10,10"
                      HorizontalContentAlignment="Stretch"
                      VerticalContentAlignment="Stretch"
                      HorizontalScrollBarVisibility="Auto"
                      VerticalScrollBarVisibility="Auto">
                <Border x:Name="SVContent" Background="#FFFFA6A6"
                        BorderBrush="#FF005DFF"
                        Width="200"
                        Height="200"
                        BorderThickness="1" />
        </ScrollViewer>
        <Button Width="75"
                Margin="28,20,0,0"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                Click="Button_Click"
                Content="Button" />
    </Grid>
</Window>

cs:

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

namespace ScrollViewer
{
    public partial class MainWindow : Window
    {
        public MainWindow ()
        {
            InitializeComponent ();
            SV.ScrollChanged += ScrollChangedEventHandler;
        }

        bool firstScrollAfterContenChanged;

        private void Button_Click (object sender, RoutedEventArgs e)
        {
            firstScrollAfterContenChanged = true;
            SVContent.Height = 1000;
        }

        public void ScrollChangedEventHandler(Object sender, ScrollChangedEventArgs e)
        {
            if (firstScrollAfterContenChanged)
            {
                firstScrollAfterContenChanged = false;
                SV.ScrollToVerticalOffset (SV.ScrollableHeight / 2);
            }
        }
    }
}

这应该做的工作:

        scrollviewer.ScrollToVerticalOffset(scrollviewer.ScrollableHeight/2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM