tags:

views:

751

answers:

2

I want to place a static rectangle on top of an image.

The rectangle should be a percentage of the image size (like 80%) regardless of the image size.

I have tried to put the image in a Canvas and as a Canvas background but then I can't get the image to fill the surrounding area.

<Canvas Grid.Row="1" Grid.Column="0">
    <Canvas.Background>
        <ImageBrush ImageSource="{Binding Path=Image1}"/>
    </Canvas.Background>
 </Canvas>
+1  A: 

Put it in a grid, and then put the rectangle in the same row and column. And use a converter to get 80% the size.

XAML:

<Window.Resources>
 <local:RectangleSizeConverter x:Key="RectangleSizeConverter" />
</Window.Resources>
<Grid>
 <Grid.RowDefinitions>
  <RowDefinition Height="Auto" />
 </Grid.RowDefinitions>
 <Grid.ColumnDefinitions>
  <ColumnDefinition Width="Auto" />
 </Grid.ColumnDefinitions>
 <Image x:Name="image" Grid.Row="0" Grid.Column="0" Source="C:\on.jpg" />
 <Rectangle Height="{Binding ElementName=image, Path=ActualHeight, Converter={StaticResource RectangleSizeConverter}}" 
      Width="{Binding ElementName=image, Path=ActualWidth, Converter={StaticResource RectangleSizeConverter}}" 
      Fill="Red" Opacity=".5" />
</Grid>

C# (Converter):

public class RectangleSizeConverter : IValueConverter
{
 #region IValueConverter Members

 public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  return System.Convert.ToDouble(value) * .8;
 }

 public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  throw new System.NotImplementedException();
 }

 #endregion
}
Carlo
Thanks. Didn't know that multiple items in a grid cell will overlap. I'll try it
adrianm
There's a simpler way than this (no code necessary), but you didn't answer my question in the comments on your original post.
Drew Marsh
Tested and it works fine. Marked it as answer. Prefer to use codebehind instead of IValueConverter for special conversions like this. DependencyPropertyDescriptor.FromProperty(Image.ActualHeightProperty, typeof(Image)).AddValueChanged( Image1, (sender, args) => { Image1Rect.Height = (sender as Image).ActualHeight*0.9; });
adrianm
+1  A: 

Here's a way you can do it with pure XAML using a DrawingBrush to fill the overlying Rectangle only partially:

<Grid>    
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <Image Source="http://sstatic.net/so/img/logo.png" Stretch="None" />
    <Rectangle>
        <Rectangle.Fill>
            <DrawingBrush Viewbox="0,0,1,1" ViewboxUnits="Absolute">
                <DrawingBrush.Drawing>
                    <GeometryDrawing Brush="#66FF0000">
                        <GeometryDrawing.Geometry>
                            <RectangleGeometry Rect="0,0,.9,.9" />
                        </GeometryDrawing.Geometry>
                    </GeometryDrawing>
                </DrawingBrush.Drawing>
            </DrawingBrush>
         </Rectangle.Fill>
     </Rectangle>
</Grid>
Drew Marsh
That is also a good solution which works fine. I changed the Brush to a Pen to just see the rectangle outline.
adrianm