none
WPF Canvas & ScaleTransform: canvas перекрывает другие элементы на UserControl RRS feed

  • Вопрос

  • Все привет!

    Как только я начинаю использовать ScaleTransform трансформацию, то канва перекрывает другие визуальные элементы в моем контроле. Как результат - канва перекрывает все в моем окне и я вижу только канву. Я уже пробовал положить канву внутрь других контейнеров (Grid, SplitPanel) - безрезультатно. Как я могу избежать перекрытия канвой?

    Мой XAML:

    <UserControl ...>
        <Grid>
            <Button x:Name="drawButton" Click="drawButton_Click" Content="Draw" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75"/>
    
            <Canvas x:Name="canvas" Margin="10,37,10,10" MouseWheel="canvas_MouseWheel" MouseMove="canvas_MouseMove">
                <Polygon x:Name="background" Points="0,0 600,0 600,600 0,600" StrokeThickness="1">
                    <Polygon.Fill>
                        <SolidColorBrush Color="Gray"/>
                    </Polygon.Fill>
                </Polygon>            
                <Canvas.RenderTransform>
                    <ScaleTransform x:Name="scaleTransform" CenterX="0" CenterY="0" ScaleX="1.0" ScaleY="1.0"></ScaleTransform>
                </Canvas.RenderTransform>
            </Canvas>
            
        </Grid>
    </UserControl>

    Мой C#:

            private void canvas_MouseWheel(object sender, MouseWheelEventArgs e)
            {
    
                var mousePoint = Mouse.GetPosition(canvas);
                
                scaleTransform.ScaleX = scaleTransform.ScaleX + (double)e.Delta / 120.0;
                scaleTransform.ScaleY = scaleTransform.ScaleY + (double)e.Delta / 120.0;
                scaleTransform.CenterX = mousePoint.X;
                scaleTransform.CenterY = mousePoint.Y;            
            }


    31 января 2013 г. 5:31

Ответы

  • Не совсем ясно, у вас Button перекрывается? Так переместите Button ниже Canvas в разметке.
    31 января 2013 г. 5:47
  • "Если вы используете Canvas рядом с другими элементами, можно установить его свойство ClipToBounds в true. В результате элементы внутри Canvas, которые выходят за его пределы, будут усечены на гранях Canvas. (Это предотвратит перекрытие других элементов в окне.) Все прочие контейнеры компоновки всегда усекают свои дочерние элементы, выходящие за их границы, независимо от установки ClipToBounds."
    1 февраля 2013 г. 7:55

Все ответы

  • Не совсем ясно, у вас Button перекрывается? Так переместите Button ниже Canvas в разметке.
    31 января 2013 г. 5:47
  • Размещенные на Canvas Shapes начинают увеличиваться и рисуются поверх всех визуальных элементов UserControl и окна в целом.
    Да, действительно - если переместить кнопку вниз, то она не перекрывается, но canvas все же расползается. Можно ли ограничить canvas по ширине и высоте?

    31 января 2013 г. 6:30
  • Не совсем ясно, у вас Button перекрывается? Так переместите Button ниже Canvas в разметке.

    Спасибо за совет - понял в каком направлении копать. Нашел следующее решение: контейнер, в котором находится canvas, "окружил" Grid, которые размещены ниже canvas, и заполнил белым цветом. Раньше же никаких заполнений не было. Теперь canvas расширяется только в этой области. Т.е.:

    1. canvas должна быть выше элементов,
    2. элементы должны быть заполнены (чтобы канва визуально не "расползлась")

    Может как-то проще можно - например жестко ограничить область для рисования? Canvas Width/Height пробовал - не помогает.

    31 января 2013 г. 6:47
  • Поместите Canvas в элемент Viewbox:

    <ViewBox>
        <Canvas x:Name="canvas" Width="300" Height="300">
        
        </Canvas>
    </ViewBox>


    31 января 2013 г. 7:10
  • Поместите Canvas в элемент Viewbox:

    <ViewBox>
        <Canvas x:Name="canvas" Width="300" Height="300">
        
        </Canvas>
    </ViewBox>


    Поместил:

            <Viewbox Stretch="None" Margin="0,37,0,0">
                <Canvas x:Name="canvas" Height="200" Width="200" Background="LightCoral">
                    <Canvas.RenderTransform>
                        <ScaleTransform x:Name="scaleTransform" CenterX="0" CenterY="0" ScaleX="1.0" ScaleY="1.0"></ScaleTransform>
                    </Canvas.RenderTransform>
                </Canvas>
            </Viewbox>
            
            <Button x:Name="drawButton" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75"/>
            <Button x:Name="moveButton" HorizontalAlignment="Left" Margin="100,10,0,0" VerticalAlignment="Top" Width="141"/>

    Но проблема осталась! При использовании ScaleTransform элемента Canvas в контроле она и изображения на ней перекрывает все - background за кнопками окрашивается в LightCoral. В окне кнопки расположены выше Viewbox, но в XAML ниже - поэтому видны, но фон кнопок закрашивается. 

    От закрашивания фона всего окна спасает Grid'ы окрашенные в белый цвет по периметру Canvas в родительском окне. Хотелось бы иметь контейнер, который ограничил бы "расползание" Canvas.

    1 февраля 2013 г. 6:48
  • "Если вы используете Canvas рядом с другими элементами, можно установить его свойство ClipToBounds в true. В результате элементы внутри Canvas, которые выходят за его пределы, будут усечены на гранях Canvas. (Это предотвратит перекрытие других элементов в окне.) Все прочие контейнеры компоновки всегда усекают свои дочерние элементы, выходящие за их границы, независимо от установки ClipToBounds."
    1 февраля 2013 г. 7:55