在 Canvas 上拖放和调整图像大小
Drag, drop and resize images on Canvas
我想在我的通用 Windows 应用程序中创建一个拖放界面。用户将能够将图像从 ListView
(或类似)拖放到 Canvas
,他们可以在其中调整图像大小和移动图像。
我找到了移动图像的方法,但现在我似乎找不到接受多点触控、找到要调整大小的适当图像以及调整图像本身大小的方法。
有没有简单的方法可以做到这一点?
这就是我最终选择的:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
namespace KindEnGezin.Windows.Views.MenuItems
{
public sealed partial class DrawView : Page
{
public DrawView()
{
InitializeComponent();
}
private void Image_OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
((Image)sender).Opacity = 0.4;
}
private void Image_OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var image = (Image)sender;
var transform = (CompositeTransform)image.RenderTransform;
// LEFT-RIGHT bounds
if (e.Delta.Translation.X < 0) // Going left
{
if (DrawingArea.ActualWidth / 2 + (transform.TranslateX + e.Delta.Translation.X) - image.ActualWidth / 2 > 0)
{
// Staying inside, apply translation
transform.TranslateX += e.Delta.Translation.X;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateX = image.ActualWidth / 2 - DrawingArea.ActualWidth / 2;
}
}
else // Going right
{
if (DrawingArea.ActualWidth / 2 - (transform.TranslateX + e.Delta.Translation.X) +
image.ActualWidth * (0.5 - transform.ScaleX) > 0)
{
// Staying inside, apply translation
transform.TranslateX += e.Delta.Translation.X;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateX = image.ActualWidth * (0.5 - transform.ScaleX) + DrawingArea.ActualWidth / 2;
}
}
// UP-DOWN bounds
if (e.Delta.Translation.Y < 0) // Going up
{
if (DrawingArea.ActualHeight / 2 + (transform.TranslateY + e.Delta.Translation.Y) - image.ActualHeight / 2 > 0)
{
// Staying inside, apply translation
transform.TranslateY += e.Delta.Translation.Y;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateY = image.ActualHeight / 2 - DrawingArea.ActualHeight / 2;
}
}
else // Going down
{
if (DrawingArea.ActualHeight / 2 - (transform.TranslateY + e.Delta.Translation.Y) +
image.ActualHeight * (0.5 - transform.ScaleY) > 0)
{
// Staying inside, apply translation
transform.TranslateY += e.Delta.Translation.Y;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateY = image.ActualHeight * (0.5 - transform.ScaleY) + DrawingArea.ActualHeight / 2;
}
}
}
// Only allow scaling when both dimensions are smaller than the drawingarea
if (image.ActualHeight*(transform.ScaleY*e.Delta.Scale) < DrawingArea.ActualHeight &&
image.ActualWidth*(transform.ScaleX*e.Delta.Scale) < DrawingArea.ActualWidth)
{
transform.ScaleX *= e.Delta.Scale;
transform.ScaleY *= e.Delta.Scale;
}
private void Image_OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
((Image)sender).Opacity = 1;
}
}
}
和 XAML:
<Grid
Name="DrawingArea">
<Image
Source="../../Assets/Images/BigLogo.png"
Width="150"
Height="150"
ManipulationMode="TranslateX , TranslateY, Scale"
ManipulationStarted="Image_OnManipulationStarted"
ManipulationDelta="Image_OnManipulationDelta"
ManipulationCompleted="Image_OnManipulationCompleted">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
</Grid>
对于包含这些图像的 Grid
,这仅使用一个静态名称。这样做允许将图像动态添加到 Grid
.
我一直在试图阻止图像超出范围时缩放图像,但我在尝试实现它时遇到了很多麻烦,所以当我检测到它正在尝试时,我只是将它移动到边界移出边界。
我想在我的通用 Windows 应用程序中创建一个拖放界面。用户将能够将图像从 ListView
(或类似)拖放到 Canvas
,他们可以在其中调整图像大小和移动图像。
我找到了移动图像的方法,但现在我似乎找不到接受多点触控、找到要调整大小的适当图像以及调整图像本身大小的方法。
有没有简单的方法可以做到这一点?
这就是我最终选择的:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
namespace KindEnGezin.Windows.Views.MenuItems
{
public sealed partial class DrawView : Page
{
public DrawView()
{
InitializeComponent();
}
private void Image_OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
((Image)sender).Opacity = 0.4;
}
private void Image_OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var image = (Image)sender;
var transform = (CompositeTransform)image.RenderTransform;
// LEFT-RIGHT bounds
if (e.Delta.Translation.X < 0) // Going left
{
if (DrawingArea.ActualWidth / 2 + (transform.TranslateX + e.Delta.Translation.X) - image.ActualWidth / 2 > 0)
{
// Staying inside, apply translation
transform.TranslateX += e.Delta.Translation.X;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateX = image.ActualWidth / 2 - DrawingArea.ActualWidth / 2;
}
}
else // Going right
{
if (DrawingArea.ActualWidth / 2 - (transform.TranslateX + e.Delta.Translation.X) +
image.ActualWidth * (0.5 - transform.ScaleX) > 0)
{
// Staying inside, apply translation
transform.TranslateX += e.Delta.Translation.X;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateX = image.ActualWidth * (0.5 - transform.ScaleX) + DrawingArea.ActualWidth / 2;
}
}
// UP-DOWN bounds
if (e.Delta.Translation.Y < 0) // Going up
{
if (DrawingArea.ActualHeight / 2 + (transform.TranslateY + e.Delta.Translation.Y) - image.ActualHeight / 2 > 0)
{
// Staying inside, apply translation
transform.TranslateY += e.Delta.Translation.Y;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateY = image.ActualHeight / 2 - DrawingArea.ActualHeight / 2;
}
}
else // Going down
{
if (DrawingArea.ActualHeight / 2 - (transform.TranslateY + e.Delta.Translation.Y) +
image.ActualHeight * (0.5 - transform.ScaleY) > 0)
{
// Staying inside, apply translation
transform.TranslateY += e.Delta.Translation.Y;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateY = image.ActualHeight * (0.5 - transform.ScaleY) + DrawingArea.ActualHeight / 2;
}
}
}
// Only allow scaling when both dimensions are smaller than the drawingarea
if (image.ActualHeight*(transform.ScaleY*e.Delta.Scale) < DrawingArea.ActualHeight &&
image.ActualWidth*(transform.ScaleX*e.Delta.Scale) < DrawingArea.ActualWidth)
{
transform.ScaleX *= e.Delta.Scale;
transform.ScaleY *= e.Delta.Scale;
}
private void Image_OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
((Image)sender).Opacity = 1;
}
}
}
和 XAML:
<Grid
Name="DrawingArea">
<Image
Source="../../Assets/Images/BigLogo.png"
Width="150"
Height="150"
ManipulationMode="TranslateX , TranslateY, Scale"
ManipulationStarted="Image_OnManipulationStarted"
ManipulationDelta="Image_OnManipulationDelta"
ManipulationCompleted="Image_OnManipulationCompleted">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
</Grid>
对于包含这些图像的 Grid
,这仅使用一个静态名称。这样做允许将图像动态添加到 Grid
.
我一直在试图阻止图像超出范围时缩放图像,但我在尝试实现它时遇到了很多麻烦,所以当我检测到它正在尝试时,我只是将它移动到边界移出边界。