Jitendra Jadav
Jitendra Jadav

Reputation: 923

Silverlight CliptoBound property issue

I am working on a Silverlight application and my problem is like this: I have a WrapPanel and inside the WrapPanel I am adding a number of images. Then, I rotate these images either by 90 degrees or -90 degrees.

So if my image size is 200 by 250, when I rotate it it will go out of the WrapPanel by 50 pixels. Is there a way to clip this image to the WrapPanel's actual bounds?

Upvotes: 4

Views: 1121

Answers (2)

ColinE
ColinE

Reputation: 70142

Just to add to AnthonyWJones answer above, which is entirely correct, you need to rotate during layout rather than render. Silverlight Panels do not clip their contents, in order to perform clipping you must set their Clip property to the required geometry manually.

The following blog post provides an attached behaviour that will automatically clip the bounds of a panel:

http://www.scottlogic.co.uk/blog/colin/2009/05/silverlight-cliptobounds-can-i-clip-it-yes-you-can/

You simply set the property as follows:

    <Canvas util:Clip.ToBounds="true"
            Grid.Column="1"  Background="Aqua" Margin="20" >
        <Ellipse Fill="Red" Canvas.Top="-10"
                 Canvas.Left="-10" Width="130" Height="130"/>
    </Canvas>

Upvotes: 2

AnthonyWJones
AnthonyWJones

Reputation: 189457

Sounds to me like you are using the RenderTransform to rotate the image. The problem is the transform is applied after the size and position of the image has been allocated hence the rotated image bleads outside of its original rectangle.

One solution is to use the LayoutTransfomer to effect that transform instead. This would cause the WrapPanel to re-flow the elements even moving the image to the next row. Here is an example using rectangles for simplicity:-

    <ScrollViewer HorizontalScrollBarVisibility="Disabled">
        <ItemsControl ItemsSource="{StaticResource TestData}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <toolkit:WrapPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <toolkit:LayoutTransformer RenderTransformOrigin="0.5, 0.5" Margin="5">
                        <toolkit:LayoutTransformer.LayoutTransform  >
                            <RotateTransform Angle="0" />
                        </toolkit:LayoutTransformer.LayoutTransform>
                        <Rectangle Width="100" Height="150" Fill="Blue" MouseLeftButtonUp="Rectangle_MouseLeftButtonUp"  />
                    </toolkit:LayoutTransformer>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>

I've added code-behind:-

    private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        LayoutTransformer lt = ((FrameworkElement)sender).Parent as LayoutTransformer;
        RotateTransform rt = (RotateTransform)lt.LayoutTransform;
        rt.Angle += 90;
        lt.ApplyLayoutTransform();
    }

My TestData items source is an arbitary List<T>, doesn't really matter what is in the list just that it contains a few items.

Using the ScrollViewer as dynamic clipping region

Note that its normal to place a WrapPanel in a ScrollViewer which naturally clips its content anywar.

Perhaps you really do want to clip the WrapPanel and you don't want any scrolling. Obviously you could apply a RectangleGeometry its Clip property but you would have to ensure the clip rectangle always matched the actual size of the WrapPanel. You could do that by monitoring its SizeChanged event and using a bit of code.

Another approach is to put it in a ScrollViewer then disable both scroll bars.

Upvotes: 3

Related Questions