C# WPF图片查看器(为什么图像在跳舞)
我正在尝试创建一个简单的窗口,允许查看/缩放/移动图像。当我们调整大小时,它的行为开始与调整图像大小以适应窗口类似 奇怪的是,当你缩小窗口的宽度时,在某一点上,图片的高度在不应该的时候开始降低,然后它反弹到不同的位置。然而,在代码中,图像的高度保持不变,因此“其他东西”正在改变布局 另一件奇怪的事情是,随着宽度的增加,图像几乎保持居中,只是逐渐向右倾斜 所以我的问题是:是什么把我的布局搞砸了C# WPF图片查看器(为什么图像在跳舞),c#,wpf,image,stretch,C#,Wpf,Image,Stretch,我正在尝试创建一个简单的窗口,允许查看/缩放/移动图像。当我们调整大小时,它的行为开始与调整图像大小以适应窗口类似 奇怪的是,当你缩小窗口的宽度时,在某一点上,图片的高度在不应该的时候开始降低,然后它反弹到不同的位置。然而,在代码中,图像的高度保持不变,因此“其他东西”正在改变布局 另一件奇怪的事情是,随着宽度的增加,图像几乎保持居中,只是逐渐向右倾斜 所以我的问题是:是什么把我的布局搞砸了 <Window xmlns="http://schemas.microsoft.com/winfx
<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;
}
}
}
公共部分类ImageViewerWindow:窗口{
公共静态ImageViewerWindow实例(字符串文件名){
ImageViewerWindow NewForm=新的ImageViewerWindow();
LoadImage(文件名);
NewForm.Show();
返回新表单;
}
私人双标度;
公共图像查看窗口(){
初始化组件();
}
公共void LoadImage(字符串文件名){
BitmapImage NewImage=新BitmapImage();
NewImage.BeginInit();
NewImage.UriSource=新Uri(文件名);
NewImage.EndInit();
ImgObject.Source=NewImage;
//ImgContentCtrl.Width=NewImage.Width;
//ImgContentCtrl.Height=NewImage.Height;
最佳拟合();
}
私有无效ImgThumb_DragDelta(对象发送方,DragDeltaEventArgs e){
double ImgLeft=Canvas.GetLeft(ImgContentCtrl);
double ImgTop=Canvas.GetTop(ImgContentCtrl);
SetLeft(ImgContentCtrl,(ImgLeft+e.HorizontalChange));
Canvas.SetTop(ImgContentCtrl,(ImgTop+e.VerticalChange));
}
私有无效ImgThumb_鼠标滚轮(对象发送器,鼠标滚轮事件参数e){
//当用户向上滚动鼠标滚轮时放大,反之亦然。
如果(e.Delta>0){
//限制放大到500%
如果(刻度<5)
标度+=0.1;
}否则{
//当鼠标滚轮向下滚动时。。。
//限制缩小到80%
如果(比例>0.8)
刻度-=0.1;
}
显示图像();
}
私人空间最佳拟合(){
//将ContentControl的比例设置为100%。
比例=1;
//设置ContentControl的位置,使图像居中。
SetLeft(ImgContentCtrl,0);
Canvas.SetTop(ImgContentCtrl,0);
}
私有无效窗口\u SizeChanged(对象发送方,SizeChangedEventArgs e){
显示图像();
}
私有void DisplayImage(){
double RatioWidth=LayoutRoot.ActualWidth/ImgObject.Source.Width;
双比率高度=LayoutRoot.ActualHeight/ImgObject.Source.Height;
如果(比率高度>比率宽度){
ImgContentCtrl.Width=LayoutRoot.ActualWidth*scale;
ImgContentCtrl.Height=LayoutRoot.ActualHeight*比率Height*比例;
}否则{
ImgContentCtrl.Height=LayoutRoot.ActualHeight*scale;
ImgContentCtrl.Width=LayoutRoot.ActualWidth*RatioWidth*scale;
}
}
}
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);
}
尽管如此,我仍然不理解在尝试运行它之前发生的奇怪行为。应用程序失败,在
DisplayImage()
的第一行出现NullReferenceException<代码>ImgObject。未分配源。我错过了什么,还是你需要添加什么?@EtienneCharland我不知道你想在这里实现什么,但你只是尝试了ImgContentCtrl.Width=LayoutRoot.ActualWidth*scale代码>和ImgContentCtrl.Height=LayoutRoot.ActualHeight*scale代码>,无需比率宽度
和比率高度
?