c# 在 windows 商店应用程序中的 canvas 内拖动图像失败
c# Dragging images inside canvas in windows store app fails
我对 C# 和一般编程还很陌生。
我正在构建一个虚拟项目以了解拖放的工作原理。起初,我开始围绕矩形移动,限制它们在 canvas 内的移动,它们移动得很好。之后,我尝试通过添加 PointerEntered/PointerExited 并用图像替换矩形使其变得更复杂。当事件 PointerEntered/PointerExited 发生时重新调整图像大小有效,但是当我尝试拖动我的图像时没有任何反应。我尝试了一些我在 SO 和 msdn 周围看到的东西,但它仍然失败。
这是我的代码:
MainPage.xaml
<Canvas x:Name="MyCanvas" Width="800" Height="600">
<Canvas.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF5E8B83" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
<TextBlock x:Name="someTB" FontSize="30" Canvas.Left="262" Canvas.Top="25" Height="28" Width="171"/>
<Image x:Name="cauldron" Source="Assets/cauldron-md.png" AllowDrop="True" PointerExited="draggableItem_PointerExited" PointerEntered="draggableItem_PointerEntered" Width="210" Height="184" Canvas.Left="455" Canvas.Top="159"/>
<Image x:Name="antidote" Source="Assets/alchemy-green-potion-no-label.png" ManipulationDelta="dragableItem_ManipulationDelta" PointerExited="draggableItem_PointerExited" PointerEntered="draggableItem_PointerEntered" Width="45" Height="89" Canvas.Left="72" Canvas.Top="263"/>
<Image x:Name="poison" Source="Assets/alchemy-tree-poison-md-standing.png" ManipulationDelta="dragableItem_ManipulationDelta" PointerExited="draggableItem_PointerExited" PointerEntered="draggableItem_PointerEntered" Width="45" Height="89" Canvas.Left="202" Canvas.Top="159"/>
</Canvas>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
double originalWidth;
double originalHeight;
public MainPage()
{
this.InitializeComponent();
// Add clipping area to the canvas
MyCanvas.Clip = new RectangleGeometry();
MyCanvas.Clip.Rect = new Rect(0, 0, MyCanvas.ActualWidth, MyCanvas.ActualHeight);
}
private Boolean DetectCollisions(FrameworkElement rect1, FrameworkElement rect2)
{
var r1 = new Rect(Canvas.GetLeft(rect1), Canvas.GetTop(rect1), rect1.ActualWidth, rect1.ActualHeight);
var r2 = new Rect(Canvas.GetLeft(rect2), Canvas.GetTop(rect2), rect2.ActualWidth, rect2.ActualHeight);
r1.Intersect(r2);
if (r1 != Rect.Empty)
{
return true;
}
return false;
}
private void dragableItem_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
Image dragableItem = sender as Image;
dragableItem.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY;
dragableItem.RenderTransform = new CompositeTransform();
var transform = (CompositeTransform)dragableItem.RenderTransform;
var newPosX = Canvas.GetLeft(dragableItem) + transform.TranslateX + e.Delta.Translation.X;
var newPosY = Canvas.GetTop(dragableItem) + transform.TranslateY + e.Delta.Translation.Y;
if (!isBoundary(newPosX, MyCanvas.ActualWidth - dragableItem.ActualWidth, 0))
Canvas.SetLeft(dragableItem, newPosX);
if (!isBoundary(newPosY, MyCanvas.ActualHeight - dragableItem.ActualHeight, 0))
Canvas.SetTop(dragableItem, newPosY);
if (DetectCollisions(dragableItem, cauldron) == true)
{
cauldron.Source = new BitmapImage(new Uri(@"Assets/cauldron-md-autoTone.png"));
}
}
bool isBoundary(double value, double max, double min)
{
return value > max ? true : value < min ? true : false;
}
private void draggableItem_PointerEntered(object sender, PointerRoutedEventArgs e)
{
Image thatPic = sender as Image;
if (thatPic != null)
{
originalWidth = thatPic.ActualWidth;
originalHeight = thatPic.ActualHeight;
thatPic.Width = thatPic.ActualWidth + 10;
thatPic.Height = thatPic.ActualHeight + 10;
}
}
private void draggableItem_PointerExited(object sender, PointerRoutedEventArgs e)
{
Image thatPic = sender as Image;
if (thatPic != null)
{
thatPic.Width = originalWidth;
thatPic.Height = originalHeight;
}
}
}
1) 您需要将 ManipulationMode="All" 添加到图像控件中。
2) 图像 "cauldron" 缺少 ManipulationDelta 事件处理程序分配。
我对 C# 和一般编程还很陌生。
我正在构建一个虚拟项目以了解拖放的工作原理。起初,我开始围绕矩形移动,限制它们在 canvas 内的移动,它们移动得很好。之后,我尝试通过添加 PointerEntered/PointerExited 并用图像替换矩形使其变得更复杂。当事件 PointerEntered/PointerExited 发生时重新调整图像大小有效,但是当我尝试拖动我的图像时没有任何反应。我尝试了一些我在 SO 和 msdn 周围看到的东西,但它仍然失败。
这是我的代码:
MainPage.xaml
<Canvas x:Name="MyCanvas" Width="800" Height="600">
<Canvas.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF5E8B83" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
<TextBlock x:Name="someTB" FontSize="30" Canvas.Left="262" Canvas.Top="25" Height="28" Width="171"/>
<Image x:Name="cauldron" Source="Assets/cauldron-md.png" AllowDrop="True" PointerExited="draggableItem_PointerExited" PointerEntered="draggableItem_PointerEntered" Width="210" Height="184" Canvas.Left="455" Canvas.Top="159"/>
<Image x:Name="antidote" Source="Assets/alchemy-green-potion-no-label.png" ManipulationDelta="dragableItem_ManipulationDelta" PointerExited="draggableItem_PointerExited" PointerEntered="draggableItem_PointerEntered" Width="45" Height="89" Canvas.Left="72" Canvas.Top="263"/>
<Image x:Name="poison" Source="Assets/alchemy-tree-poison-md-standing.png" ManipulationDelta="dragableItem_ManipulationDelta" PointerExited="draggableItem_PointerExited" PointerEntered="draggableItem_PointerEntered" Width="45" Height="89" Canvas.Left="202" Canvas.Top="159"/>
</Canvas>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
double originalWidth;
double originalHeight;
public MainPage()
{
this.InitializeComponent();
// Add clipping area to the canvas
MyCanvas.Clip = new RectangleGeometry();
MyCanvas.Clip.Rect = new Rect(0, 0, MyCanvas.ActualWidth, MyCanvas.ActualHeight);
}
private Boolean DetectCollisions(FrameworkElement rect1, FrameworkElement rect2)
{
var r1 = new Rect(Canvas.GetLeft(rect1), Canvas.GetTop(rect1), rect1.ActualWidth, rect1.ActualHeight);
var r2 = new Rect(Canvas.GetLeft(rect2), Canvas.GetTop(rect2), rect2.ActualWidth, rect2.ActualHeight);
r1.Intersect(r2);
if (r1 != Rect.Empty)
{
return true;
}
return false;
}
private void dragableItem_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
Image dragableItem = sender as Image;
dragableItem.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY;
dragableItem.RenderTransform = new CompositeTransform();
var transform = (CompositeTransform)dragableItem.RenderTransform;
var newPosX = Canvas.GetLeft(dragableItem) + transform.TranslateX + e.Delta.Translation.X;
var newPosY = Canvas.GetTop(dragableItem) + transform.TranslateY + e.Delta.Translation.Y;
if (!isBoundary(newPosX, MyCanvas.ActualWidth - dragableItem.ActualWidth, 0))
Canvas.SetLeft(dragableItem, newPosX);
if (!isBoundary(newPosY, MyCanvas.ActualHeight - dragableItem.ActualHeight, 0))
Canvas.SetTop(dragableItem, newPosY);
if (DetectCollisions(dragableItem, cauldron) == true)
{
cauldron.Source = new BitmapImage(new Uri(@"Assets/cauldron-md-autoTone.png"));
}
}
bool isBoundary(double value, double max, double min)
{
return value > max ? true : value < min ? true : false;
}
private void draggableItem_PointerEntered(object sender, PointerRoutedEventArgs e)
{
Image thatPic = sender as Image;
if (thatPic != null)
{
originalWidth = thatPic.ActualWidth;
originalHeight = thatPic.ActualHeight;
thatPic.Width = thatPic.ActualWidth + 10;
thatPic.Height = thatPic.ActualHeight + 10;
}
}
private void draggableItem_PointerExited(object sender, PointerRoutedEventArgs e)
{
Image thatPic = sender as Image;
if (thatPic != null)
{
thatPic.Width = originalWidth;
thatPic.Height = originalHeight;
}
}
}
1) 您需要将 ManipulationMode="All" 添加到图像控件中。
2) 图像 "cauldron" 缺少 ManipulationDelta 事件处理程序分配。