Как сохранить область холста в центре ScrollViewer при увеличении или уменьшении, и не все может отображаться в окне просмотра - PullRequest
7 голосов
/ 23 июня 2011

Все,

У меня есть приложение WPF с холстом, который я завернул в Средство просмотра с прокруткой.У меня есть ползунок в строке состояния, который позволяет пользователю увеличивать и уменьшать масштаб (точно так же, как Win7's mspaint).

Вот некоторые из XAML:

<ScrollViewer Name="Map"
              VerticalScrollBarVisibility="Auto"
              HorizontalScrollBarVisibility="Auto">
    <Canvas x:Name="WallsCanvas" Height="800" Width="1000" ClipToBounds="True">
        <Canvas.LayoutTransform>
            <ScaleTransform x:Name="WallsCanvasScale"
                            ScaleX="1" ScaleY="1" />
        </Canvas.LayoutTransform>
    </Canvas>
</ScrollViewer>

Когда я увеличиваю масштаб и видимы полосы прокрутки, полосы прокрутки, независимо от того, где они установлены, переходят к середине.

Это точно так же, как если бы значения полос прокрутки остались прежними, но максимальное значение увеличивается.

Что я могу сделать, чтобы заставить их ... скажем, если бы они были в нижнейв правом нижнем углу, чтобы остаться в правом нижнем углу после увеличения или уменьшения масштаба?

Кстати, вот мой код увеличения и уменьшения:

private void SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    var scales = new []{.125, .25, .5, 1, 2, 4, 8};
    var scale = scales[(int)((Slider) sender).Value];

    ScaleChanged(scale, WallsCanvasScale);
}

private static void ScaleChanged(double scale, ScaleTransform st)
{
    st.ScaleX = scale;
    st.ScaleY = scale;
}

Итак, в моей науке о ракетостроении неткод, но ...

Обновить идею: если бы у меня был доступ к значению и максимальному значению полос прокрутки, мог бы я получить процент между этими двумя значениями, а затем после масштабирования (масштабирования) я мог бы повторно применитьзначение полосы прокрутки в процентах от максимального значения ?????Но где доступно значение и максимальное значение?

Любая помощь будет оценена.Я не могу думать, что я единственный, у кого есть эта проблема, так как MSPaint (версия для Windows 7) работает правильно, и я предполагаю, что это приложение XAML.

Вот ссылка (http://www.leesaunders.net/examples/zoomexample/zoomexample.zip) до минимального рабочего примера проекта (VS 2010). Когда вы запустите его, просто переместите полосы прокрутки, затем увеличьте уровень, и вы сразу увидите проблему.

1 Ответ

3 голосов
/ 24 июня 2011

Вам просто нужно сместить смещение, которое возникает из-за масштаба, потому что оно масштабируется от (0,0). Это немного сложно, но вот эскиз того, как метод в вашем примере может выглядеть:

private void SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    var slider = (Slider)sender;
    if (!slider.IsLoaded)
    {
        slider.Loaded += (s, le) => SliderValueChanged(sender, e);
        return;
    }

    var scales = new[] { .125, .25, .5, 1, 2, 4, 8 };
    var scale = scales[(int)((Slider)sender).Value];

    // The "+20" are there to account for the scrollbars... i think. Not perfectly accurate.
    var relativeMiddle = new Point((Map.ActualWidth + 20) / 2, (Map.ActualHeight + 20) / 2);
    var oldLocation = CanvasScale.Transform(TemplateCanvas.PointFromScreen(relativeMiddle));

    ScaleChanged(scale, CanvasScale);

    var newLocation = CanvasScale.Transform(TemplateCanvas.PointFromScreen(relativeMiddle));

    var shift = newLocation - oldLocation;

    Map.ScrollToVerticalOffset(Map.VerticalOffset + shift.Y);
    Map.ScrollToHorizontalOffset(Map.HorizontalOffset + shift.X);

    lblScale.Content = scale.ToString("P1").Replace(".0", string.Empty);
}

Должно быть достаточно очевидным местоположение центра измеряется до и после масштабирования, чтобы вычислить смещение этой точки, которое затем добавляется к текущей позиции прокрутки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...