在WPF画布中对齐图像 [英] Align images in WPF canvas in center

查看:183
本文介绍了在WPF画布中对齐图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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 =AutoHorizo​​ntalAlignment =Center/>
< Image x:Name =previousSource ={Binding PreviousPicture}StretchDirection =BothStretch =UniformClipToBounds =TrueSnapsToDevicePixels =TrueRenderOptions.BitmapScalingMode =HighQualityRenderTransformOrigin =0.5,0.5Opacity =0Grid.ColumnSpan =2Height =732Width =AutoHorizo​​ntalAlignment =Center/>
< Image x:Name =currentSource ={Binding Picture}StretchDirection =BothStretch =UniformClipToBounds =TrueSnapsToDevicePixels =TrueRenderOptions.BitmapScalingMode =HighQualityRenderTransformOrigin =0.5,0.5Grid.ColumnSpan =2Height =732Width =AutoHorizo​​ntalAlignment =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

我实际上建议使用 Grid 而不是 Canvas ,并使用 Horizo​​ntalAlignment = 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 your Canvas.Width and Image.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 setting Canvas.Left of the Image, and this would overwrite your binding with the converter.

I would actually recommend using a Grid instead of a Canvas, and positioning your image using HorizontalAlignment=Center, and allowing users to adjust the image's position by using a RenderTransform (Note that you need to use RenderTransform, not LayoutTransform, 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, and Left. To move around images, you would alter the Picture.Left property, and when the user switches pictures you can reset the Picture.Left property to its original value

这篇关于在WPF画布中对齐图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆