I am developing an image viewer based on gestures using Kinect. I am using the following XAML code to display images on a canvas.
<Canvas Background="Transparent" Height="732" VerticalAlignment="Top">
<Image x:Name="next" Source="{Binding NextPicture}" StretchDirection="Both" Stretch="Uniform" ClipToBounds="True" SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin="0.5,0.5" Opacity="0" Grid.ColumnSpan="2" Height="732" Width="Auto" HorizontalAlignment="Center" />
<Image x:Name="previous" Source="{Binding PreviousPicture}" StretchDirection="Both" Stretch="Uniform" ClipToBounds="True" SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin="0.5,0.5" Opacity="0" Grid.ColumnSpan="2" Height="732" Width="Auto" HorizontalAlignment="Center" />
<Image x:Name="current" Source="{Binding Picture}" StretchDirection="Both" Stretch="Uniform" ClipToBounds="True" SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin="0.5,0.5" Grid.ColumnSpan="2" Height="732" Width="Auto" HorizontalAlignment="Center" />
</Canvas>
This is code that runs in the back:
/// <summary>
/// Gets the previous image displayed.
/// </summary>
public BitmapImage PreviousPicture { get; private set; }
/// <summary>
/// Gets the current image to be displayed.
/// </summary>
public BitmapImage Picture { get; private set; }
/// <summary>
/// Gets the next image displayed.
/// </summary>
public BitmapImage NextPicture { get; private set; }
Every time a gesture is recognized, the properties are changed as shown:
// Setup corresponding picture if pictures are available.
this.PreviousPicture = this.Picture;
this.Picture = this.NextPicture;
this.NextPicture = LoadPicture(Index + 1);
// Notify world of change to Index and Picture.
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("PreviousPicture"));
this.PropertyChanged(this, new PropertyChangedEventArgs("Picture"));
this.PropertyChanged(this, new PropertyChangedEventArgs("NextPicture"));
}
The problem however is, the images that I display on the canvas get aligned randomly to the left or right. Also their aspect ratio changes sometimes. What I want is, the images should be displayed on the center of the canvas in their original aspect ratio. Can anyone help me in that regard?
Also, I am able to set the image to the center using the C# code as follows:
Canvas.SetLeft(current, (1249 - current.ActualWidth) / 2);
Canvas.SetTop(current, 0);
where, ‘current’ is the name of the current image in the XAML code. But I want it to happen automatically. Is it possible in the XAML code? If not, how do I achieve it?
PS: I am not so good at C# or WPF. So please explain in layman terms if possible.
You could center the image in the XAML by binding the
Canvas.Leftproperty using an IMultiValueConverter that accepts parameters of yourCanvas.WidthandImage.Width, and returns(Canvas.Width / 2) - (Image.Width / 2), however per your comment above it sounds like you are allowing users to re-position an image using hand movements by settingCanvas.Leftof the Image, and this would overwrite your binding with the converter.I would actually recommend using a
Gridinstead of aCanvas, and positioning your image usingHorizontalAlignment=Center, and allowing users to adjust the image’s position by using aRenderTransform(Note that you need to useRenderTransform, notLayoutTransform, so the transformation gets applied at render time, not when WPF is trying to layout your objects).If that doesn’t work, I would change the Picture properties from BitmapImages to an actual class representing that image, with properties for
BitmapImage,Top, andLeft. To move around images, you would alter thePicture.Leftproperty, and when the user switches pictures you can reset thePicture.Leftproperty to its original value