MatrixTransform в сочетании с шириной / высотой холста

При увеличении масштаба рисунка на холсте у меня есть требование показать полосы прокрутки.
Холст находится в ScrollViewer, и я увеличиваю ширину / высоту холста, чтобы появлялись полосы прокрутки (в противном случае они не отображаются).

Чтобы увеличить масштаб в 1,1 раза, я использую этот код:

Matrix m = this.LayoutTransform.Value;
if (e.Delta > 0) f = 1.1;
else f = 1.0 / 1.1;
m.Scale(f, f);
this.LayoutTransform = new MatrixTransform(m);
this.Height = this.ActualHeight * f;
this.Width = this.ActualWidth * f;

Оказывается, холст становится слишком большим. Рисунок увеличивается на 10%, но ширина кажется на 20% больше, чем квадрат 1,1. Поэтому я использую Math.Sqrt(f); вместо f.

Кто-нибудь может объяснить, почему он так себя ведет?


person Gerard    schedule 04.03.2014    source источник
comment
Кажется, вы применяете коэффициент масштабирования дважды, сначала с помощью LayoutTransform, а во-вторых, умножая ширину и высоту. Вы должны сделать только один из них, желательно только LayoutTransform.   -  person Clemens    schedule 04.03.2014
comment
Тогда полосы прокрутки не появляются (что является обязательным).   -  person Gerard    schedule 04.03.2014


Ответы (1)


Вам следует изменить только LayoutTransform холста, как в этом упрощенном примере:

<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
    <Canvas Width="1000" Height="1000" Background="Transparent"
            MouseWheel="Canvas_MouseWheel">
        <Canvas.LayoutTransform>
            <MatrixTransform/>
        </Canvas.LayoutTransform>
    </Canvas>
</ScrollViewer>

Обработчик события MouseWheel:

private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
    var element = (FrameworkElement)sender;
    var transform = (MatrixTransform)element.LayoutTransform;
    var matrix = transform.Matrix;
    var scale = e.Delta >= 0d ? 1.1 : (1d / 1.1);

    matrix.Scale(scale, scale);
    transform.Matrix = matrix;

    e.Handled = true;
}
person Clemens    schedule 04.03.2014
comment
Без Width="1000" Height="1000" работает? Мой холст не имеет начального размера, он соответствует своему родительскому размеру и размерам чертежа. - person Gerard; 04.03.2014
comment
У него должен быть начальный размер, иначе ScrollViewer не имеет смысла. Однако вы можете установить начальный размер в программном коде, как только он станет доступен. - person Clemens; 04.03.2014
comment
Еще один вопрос: когда я сбрасываю Transform обратно в Identity, полосы прокрутки остаются видимыми, хотя изначально они не видны (что хорошо), а размер Canvas не изменился. - person Gerard; 04.03.2014
comment
Еще один вопрос: при использовании RenderTransform вместо LayoutTransform полосы прокрутки не отображаются, несмотря на настройку ширины и высоты. - person Gerard; 04.03.2014
comment
Первый вопрос: сложно сказать, не видя своего кода. Во-вторых: RenderTransform не влияет на макет, но вам это нужно. Здесь нельзя использовать RenderTransform. - person Clemens; 04.03.2014
comment
Возможно ли объединить Render- и LayoutTransform, потому что RenderTransform масштабирует намного лучше. - person Gerard; 04.03.2014
comment
Я так не думаю. Как было сказано ранее, вам необходимо пересчитать макет, чтобы обновить полосы прокрутки. - person Clemens; 04.03.2014