在WPF画布中对齐图像 [英] Align images in WPF canvas in center
问题描述
我正在使用Kinect基于手势开发图像查看器。我使用以下XAML代码在画布上显示图片。
< Canvas Background =TransparentHeight =732 VerticalAlignment =Top>
< Image x:Name =nextSource ={Binding NextPicture}StretchDirection =BothStretch =UniformClipToBounds =TrueSnapsToDevicePixels =TrueRenderOptions.BitmapScalingMode =HighQualityRenderTransformOrigin =0.5,0.5Opacity =0Grid.ColumnSpan =2Height =732Width =AutoHorizontalAlignment =Center/>
< Image x:Name =previousSource ={Binding PreviousPicture}StretchDirection =BothStretch =UniformClipToBounds =TrueSnapsToDevicePixels =TrueRenderOptions.BitmapScalingMode =HighQualityRenderTransformOrigin =0.5,0.5Opacity =0Grid.ColumnSpan =2Height =732Width =AutoHorizontalAlignment =Center/>
< Image x:Name =currentSource ={Binding Picture}StretchDirection =BothStretch =UniformClipToBounds =TrueSnapsToDevicePixels =TrueRenderOptions.BitmapScalingMode =HighQualityRenderTransformOrigin =0.5,0.5Grid.ColumnSpan =2Height =732Width =AutoHorizontalAlignment =Center/>
< / Canvas>
这是在后面运行的代码:
///< summary>
///获取显示的上一个图像。
///< / summary>
public BitmapImage PreviousPicture {get;私人集}
///< summary>
///获取要显示的当前图像。
///< / summary>
public BitmapImage Picture {get;私人集}
///< summary>
///获取显示的下一个图像。
///< / summary>
public BitmapImage NextPicture {get;私人集}
每次识别手势时,属性都会改变,如下所示:
//如果图片可用,设置相应的图片。
,
this.PreviousPicture = this.Picture;
this.Picture = this.NextPicture;
this.NextPicture = LoadPicture(Index + 1);
//通知索引和图片的变更世界。
if(this.PropertyChanged!= null)
{
this.PropertyChanged(this,new PropertyChangedEventArgs(PreviousPicture));
this.PropertyChanged(this,new PropertyChangedEventArgs(Picture));
this.PropertyChanged(this,new PropertyChangedEventArgs(NextPicture));然而,问题是,我在画布上显示的图像会随机对齐。向左或向右。它们的长宽比有时也改变。我想要的是,图像应该以原始的宽高比显示在画布的中心。任何人都可以在这方面帮助我吗?
此外,我可以使用C#代码将图像设置为中心:
Canvas.SetLeft(current,(1249 - current.ActualWidth)/ 2);
Canvas.SetTop(current,0);
其中,'current'是XAML代码中当前图像的名称。但我想让它自动发生。在XAML代码中是否可能?如果没有,我该如何实现呢?
PS:我不太好C#或WPF。
解决方案您可以通过绑定
Canvas.Left
属性使用 IMultiValueConverter ,接受Canvas.Width
和Image.Width
的参数,并返回(Canvas.Width / 2) - (Image.Width / 2)
,但是每您的评论上面它听起来像你允许用户使用手部动作重新定位图像通过设置Canvas.Left $ c
我实际上建议使用
Grid
而不是Canvas
,并使用HorizontalAlignment = Center
定位图像,并允许用户调整图像的位置通过使用RenderTransform
(请注意,您需要使用RenderTransform
,而不是LayoutTransform
,所以转换在渲染时应用,而不是当WPF尝试布局你的对象时)。
如果这不工作, BitmapImage
顶部
和<$ c的属性,从BitmapImages的图片属性到表示该图片的实际类$ c>左。要移动图像,您可以改变Picture.Left
属性,当用户切换图片时,您可以重置Picture.Left
属性恢复到其原始值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.Left
property using an IMultiValueConverter that accepts parameters of yourCanvas.Width
andImage.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.Left
of the Image, and this would overwrite your binding with the converter.I would actually recommend using a
Grid
instead 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.Left
property, and when the user switches pictures you can reset thePicture.Left
property to its original value这篇关于在WPF画布中对齐图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!