WPF图片查看器(为什么图像在跳舞)

本文关键字:图像 为什么 跳舞 WPF | 更新日期: 2023-09-27 18:23:45

我正在尝试创建一个简单的窗口,允许查看/缩放/移动图像。它的行为开始类似于我们调整大小时调整图像大小以适应窗口的行为。

奇怪的是,当你减少窗口的宽度时,在某一点上,图片的高度开始在不应该减少的时候减少,然后它反弹到不同的位置。然而,在代码中,图像的高度保持不变,因此"其他东西"正在改变布局。

另一件奇怪的事情是,随着宽度的增加,图像几乎保持居中,只是逐渐向右倾斜。

所以我的问题是:是什么把我的布局搞砸了?

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            x:Class="NaturalGroundingPlayer.ImageViewerWindow"
            x:Name="Window" Title="Image Viewer" Width="640" Height="480" SizeChanged="Window_SizeChanged">
    <Grid x:Name="LayoutRoot">
        <Canvas x:Name="ImgCanvas" ClipToBounds="True">
            <ContentControl x:Name="ImgContentCtrl" Height="300" Width="400">
                <Grid x:Name="ImgGrid">
                    <Image x:Name="ImgObject"/>
                    <Thumb x:Name="ImgThumb" Opacity="0" DragDelta="ImgThumb_DragDelta" MouseWheel="ImgThumb_MouseWheel"/>
                </Grid>
            </ContentControl>
        </Canvas>
    </Grid>
</Window>

public partial class ImageViewerWindow : Window {
    public static ImageViewerWindow Instance(string fileName) {
        ImageViewerWindow NewForm = new ImageViewerWindow();
        NewForm.LoadImage(fileName);
        NewForm.Show();
        return NewForm;
    }
    private double scale;
    public ImageViewerWindow() {
        InitializeComponent();
    }
    public void LoadImage(string fileName) {
        BitmapImage NewImage = new BitmapImage();
        NewImage.BeginInit();
        NewImage.UriSource = new Uri(fileName);
        NewImage.EndInit();
        ImgObject.Source = NewImage;
        //ImgContentCtrl.Width = NewImage.Width;
        //ImgContentCtrl.Height = NewImage.Height;
        BestFit();
    }
    private void ImgThumb_DragDelta(object sender, DragDeltaEventArgs e) {
        double ImgLeft = Canvas.GetLeft(ImgContentCtrl);
        double ImgTop = Canvas.GetTop(ImgContentCtrl);
        Canvas.SetLeft(ImgContentCtrl, (ImgLeft + e.HorizontalChange));
        Canvas.SetTop(ImgContentCtrl, (ImgTop + e.VerticalChange));
    }
    private void ImgThumb_MouseWheel(object sender, MouseWheelEventArgs e) {
        // Zoom in when the user scrolls the mouse wheel up and vice versa.
        if (e.Delta > 0) {
            // Limit zoom-in to 500%
            if (scale < 5) 
                scale += 0.1;
        } else {
            // When mouse wheel is scrolled down...
            // Limit zoom-out to 80%
            if (scale > 0.8) 
                scale -= 0.1;
        }
        DisplayImage();
    }
    private void BestFit() {
        // Set the scale of the ContentControl to 100%.
        scale = 1;
        // Set the position of the ContentControl so that the image is centered.
        Canvas.SetLeft(ImgContentCtrl, 0);
        Canvas.SetTop(ImgContentCtrl, 0);
    }
    private void Window_SizeChanged(object sender, SizeChangedEventArgs e) {
        DisplayImage();
    }
    private void DisplayImage() {
        double RatioWidth = LayoutRoot.ActualWidth / ImgObject.Source.Width;
        double RatioHeight = LayoutRoot.ActualHeight / ImgObject.Source.Height;
        if (RatioHeight > RatioWidth) {
            ImgContentCtrl.Width = LayoutRoot.ActualWidth * scale;
            ImgContentCtrl.Height = LayoutRoot.ActualHeight * RatioHeight * scale;
        } else {
            ImgContentCtrl.Height = LayoutRoot.ActualHeight * scale;
            ImgContentCtrl.Width = LayoutRoot.ActualWidth * RatioWidth * scale;
        }
    }
}

WPF图片查看器(为什么图像在跳舞)

Sjips,您首先需要将任何图片放入其中进行显示。

dkozl,这确实有效,我不确定图像控件是否会自动尊重比例,因为我发现演示在调整大小时不尊重比例。简单地将此代码放在DisplayImage中就可以完美地工作,即使在缩放时也可以正确地重新定位。我想我比我想象的更接近答案了!

private void DisplayImage() {
    ImgContentCtrl.Width = LayoutRoot.ActualWidth * scale;
    Canvas.SetLeft(ImgContentCtrl, LayoutRoot.ActualWidth * (1 - scale) / 2);
    ImgContentCtrl.Height = LayoutRoot.ActualHeight * scale;
    Canvas.SetTop(ImgContentCtrl, LayoutRoot.ActualHeight * (1 - scale) / 2);
}

话虽如此,我仍然不讨厌以前发生的奇怪行为。。。