Reputation: 3227
I want to have an image as the background of a grid. By default, the image should be right- and bottom-aligned. The image should also uniformly stretch to the height of the container. However, if the container gets resized such that the width is thinner than the size of the image, the image starts resizing to become smaller. Instead of this happening, I want to clip the image so that parts from the right start getting hidden.
Here is my image XAML right now:
<Image Source="blahblah.png"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Stretch="Uniform" />
Here is the behavior I want described in a picture (the black border is the container size):
Upvotes: 0
Views: 3771
Reputation: 2519
I don't see a way either by just setting some "magic" properties. I would implement a panel that hosts your image and manages the desired behaviour (scaling and positioning). That's how the panel looks like:
public class ImagePanel : Panel
{
public ImagePanel ()
{
}
protected override Size MeasureOverride (Size availableSize)
{
if (InternalChildren.Count > 0)
{
FrameworkElement child = (FrameworkElement)InternalChildren[0];
var childMaxSize = new Size (double.PositiveInfinity, availableSize.Height);
child.Measure (childMaxSize);
}
return availableSize;
}
protected override Size ArrangeOverride (Size finalSize)
{
if (InternalChildren.Count > 0)
{
FrameworkElement child = (FrameworkElement)InternalChildren[0];
double x = finalSize.Width - child.DesiredSize.Width;
if (x < 0)
{
x = 0;
}
child.Arrange (new Rect (new Point (x, 0), child.DesiredSize));
}
return finalSize; // Returns the final Arranged size
}
}
Use it this way:
<local:ImagePanel>
<Image Source="Image.jpg" Fill="Uniform"/>
</local:ImagePanel>
Upvotes: 1
Reputation: 13017
Try a mix of different panels, like this:
<Grid x:Name="mainGrid" >
<Grid x:Name="backgroundSpacer" HorizontalAlignment="Stretch"
MinWidth="{Binding ElementName=backgroundImage, Path=ActualWidth}" >
<StackPanel x:Name="backgroundPanel"
HorizontalAlignment="Right" Orientation="Horizontal" >
<Image x:Name="backgroundImage" Stretch="Fill"
Source="http://programming.enthuses.me/1.png" />
</StackPanel>
</Grid>
...
</Grid>
Here, we put the image in a horizontal (and right-aligned) StackPanel
. The StackPanel stretches vertically by default, and a feature of the StackPanel is that it tells its child items that they have unlimited width. Therefore, the Image
is always rendered as tall as it can be.
Next, we have a "backgroundSpacer" which normally stretches across the whole container grid, but through the MinWidth
binding we make sure it is always wide enough to contain the whole image. If "mainGrid" gets too thin, "backgroundSpacer" gets clipped, and WPF's default clipping behavior clips off its right side.
Upvotes: 3
Reputation: 54
Have you ever tried used a ViewBox Element? Put this on a Parent with only MaxWidth/Width defined and set the ClipToBounds to True. For more information about this Control (That helps a lot when we talking about resizing):
http://msdn.microsoft.com/pt-br/library/system.windows.controls.viewbox(v=vs.110).aspx
Upvotes: -1