Sunday, April 17, 2011

Determine path dynamically in Silverlight 2

I have a border with rounded corners within a canvas and want to add a clipping region to the canvas so that anything I add is clipped to the region within the border. I know that I can set the Clip property of the canvas but as the canvas and object are sized dynamically rather than having sizes assigned in the XAML, I can't figure out how to calculate the path to use. Is there some way to derive a PathGeometry from a UIElement (the border in this case)? If not what is the best way to approach this? Here is the XAML for the test page I'm working with.

<UserControl x:Class="TimelinePrototype.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot">
 <Grid.RowDefinitions>
  <RowDefinition Height="auto" />
  <RowDefinition />
 </Grid.RowDefinitions>
 <StackPanel Orientation="Horizontal" Margin="10">
  <Button x:Name="cmdDraw" FontSize="18" Click="cmdDraw_Click" Content="Draw" Margin="0,0,5,0" VerticalAlignment="Bottom" />
  <TextBlock x:Name="txtDateRange" FontSize="18" Margin="10,0,10,10" VerticalAlignment="Bottom" />
 </StackPanel>
 <Canvas x:Name="TimelineCanvas" Grid.Row="1" HorizontalAlignment="Stretch" 
    SizeChanged="TimelineCanvas_SizeChanged">
  <Border x:Name="TimelineBorder" 
    Background="LightGray" 
    BorderBrush="Black" 
    BorderThickness="2" 
    CornerRadius="15" 
    Margin="10"
    Grid.Row="1"
    VerticalAlignment="Top">
  </Border>
 </Canvas>
</Grid>

From stackoverflow
  • Try using the ActualHeight and ActualWidth properties

    var height = TimelineCanvas.ActualHeight;
    var width = TimelineCanvas.ActualWidth;
    
    Steve Crane : I had thought of using those but was wondering if there might be some other, more clever way of doing this.
  • I ended up using this code, but would still be interested in any alternate methods.

    RectangleGeometry clipRect = new RectangleGeometry();
    clipRect.Rect = new Rect(TimelineBorder.Margin.Left, TimelineBorder.Margin.Top, TimelineCanvas.ActualWidth - (TimelineBorder.Margin.Left + TimelineBorder.Margin.Right), TimelineCanvas.ActualHeight - (TimelineBorder.Margin.Top + TimelineBorder.Margin.Bottom));
    clipRect.RadiusX = TimelineBorder.CornerRadius.TopLeft;
    clipRect.RadiusY = TimelineBorder.CornerRadius.TopLeft;
    TimelineCanvas.Clip = clipRect;
    
    MojoFilter : I'd have to endorse that method; if only because I've done it that way dozens of times without seeing a nicer approach.
  • Try blacklight

    The blacklight toolpack has a rounded corner clipping tool and is free.

    Steve Crane : Thanks, I'll check it out.

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.