[英]Cropping image after resizing or moving of cropping rectangle
我已經為程序實現了“裁剪用戶控件”,並且想添加可移動和可調整大小的功能。 我目前正在關注Sukrahms Diagram Designer http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part-1 。 但是由於我的矩形不是在用戶拖動並創建矩形后才創建的,所以我得到了意外的結果。 現在,我只是想創建一個包含在ContentControl中的矩形,但是當我拖動鼠標以創建一個矩形時,它的起始位置在窗口的最左側,而不是單擊mouseleftbuttondown的位置。 以下是我的代碼。
XAML:
<UserControl x:Class="Klein_Tools_Profile_Pic_Generator.CropControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="clr-namespace:Klein_Tools_Profile_Pic_Generator"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ControlTemplate x:Key="MoveThumbTemplate" TargetType="{x:Type s:MoveThumb}">
<Rectangle Fill="Transparent"/>
</ControlTemplate>
<!-- ResizeDecorator Template -->
<ControlTemplate x:Key="ResizeDecoratorTemplate" TargetType="{x:Type Control}">
<Grid>
<s:ResizeThumb Height="3" Cursor="SizeNS" Margin="0 -4 0 0"
VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
<s:ResizeThumb Width="3" Cursor="SizeWE" Margin="-4 0 0 0"
VerticalAlignment="Stretch" HorizontalAlignment="Left"/>
<s:ResizeThumb Width="3" Cursor="SizeWE" Margin="0 0 -4 0"
VerticalAlignment="Stretch" HorizontalAlignment="Right"/>
<s:ResizeThumb Height="3" Cursor="SizeNS" Margin="0 0 0 -4"
VerticalAlignment="Bottom" HorizontalAlignment="Stretch"/>
<s:ResizeThumb Width="7" Height="7" Cursor="SizeNWSE" Margin="-6 -6 0 0"
VerticalAlignment="Top" HorizontalAlignment="Left"/>
<s:ResizeThumb Width="7" Height="7" Cursor="SizeNESW" Margin="0 -6 -6 0"
VerticalAlignment="Top" HorizontalAlignment="Right"/>
<s:ResizeThumb Width="7" Height="7" Cursor="SizeNESW" Margin="-6 0 0 -6"
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
<s:ResizeThumb Width="7" Height="7" Cursor="SizeNWSE" Margin="0 0 -6 -6"
VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
</Grid>
</ControlTemplate>
<!-- Designer Item Template-->
<ControlTemplate x:Key="DesignerItemTemplate" TargetType="ContentControl">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
<s:MoveThumb Template="{StaticResource MoveThumbTemplate}" Cursor="SizeAll"/>
<Control Template="{StaticResource ResizeDecoratorTemplate}"/>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
</Grid>
</ControlTemplate>
</UserControl.Resources>
<Canvas x:Name="BackPanel"
MouseLeftButtonDown="LoadedImage_MouseLeftButtonDown"
MouseMove="LoadedImage_MouseMove"
MouseLeftButtonUp="LoadedImage_MouseLeftButtonUp"
Background="Transparent">
<ContentControl x:Name="contControl" Visibility="Collapsed"
Template="{StaticResource DesignerItemTemplate}">
<Rectangle x:Name="selectionRectangle" Fill="#220000FF"
IsHitTestVisible="False"/>
</ContentControl>
</Canvas>
</UserControl>
用戶控制代碼背后:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Shapes;
namespace Klein_Tools_Profile_Pic_Generator
{
/// <summary>
/// Interaction logic for CropControl.xaml
/// </summary>
public partial class CropControl : UserControl
{
private bool isDragging = false;
private Point anchorPoint = new Point();
public CropControl()
{
InitializeComponent();
}
//Register the Dependency Property
public static readonly DependencyProperty SelectionProperty =
DependencyProperty.Register("Selection", typeof(Rect), typeof(CropControl), new PropertyMetadata(default(Rect)));
public Rect Selection
{
get { return (Rect)GetValue(SelectionProperty); }
set { SetValue(SelectionProperty, value); }
}
// this is used, to react on changes from ViewModel. If you assign a
// new Rect in your ViewModel you will have to redraw your Rect here
private static void OnSelectionChanged(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs e)
{
Rect newRect = (Rect)e.NewValue;
Rectangle selectionRectangle = d as Rectangle;
if (selectionRectangle != null)
return;
selectionRectangle.SetValue(Canvas.LeftProperty, newRect.X);
selectionRectangle.SetValue(Canvas.TopProperty, newRect.Y);
selectionRectangle.Width = newRect.Width;
selectionRectangle.Height = newRect.Height;
}
private void LoadedImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (isDragging == false)
{
anchorPoint.X = e.GetPosition(BackPanel).X;
anchorPoint.Y = e.GetPosition(BackPanel).Y;
Canvas.SetZIndex(selectionRectangle, 999);
isDragging = true;
BackPanel.Cursor = Cursors.Cross;
}
}
private void LoadedImage_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
double x = e.GetPosition(BackPanel).X;
double y = e.GetPosition(BackPanel).Y;
contControl.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X));
contControl.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y));
contControl.Width = Math.Abs(x - anchorPoint.X);
contControl.Height = Math.Abs(y - anchorPoint.Y);
if (contControl.Visibility != Visibility.Visible)
contControl.Visibility = Visibility.Visible;
}
}
private void LoadedImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (isDragging)
{
isDragging = false;
if (contControl.Width > 0)
{
//Crop.IsEnabled = true;
//Cut.IsEnabled = true;
BackPanel.Cursor = Cursors.Arrow;
}
contControl.GetValue(Canvas.LeftProperty);
// Set the Selection to the new rect, when the mouse button has been released
Selection = new Rect(
(double)contControl.GetValue(Canvas.LeftProperty),
(double)contControl.GetValue(Canvas.TopProperty),
contControl.Width,
contControl.Height);
}
}
}
}
我想我需要通過將Rectangle綁定到我的ContentControl來檢索Canvas.Top和Canvas.Bottom,但我不知道如何。 我到處看,什么也想不出來。 我應該如何檢索此附加屬性,或者有更好的方法來實現可移動且可調整大小的裁剪矩形?
更新:
我按照Toby的建議對代碼進行了一些調整,現在裁切矩形按預期方式移動並調整大小。 最初,在用戶拖動鼠標並創建矩形后,它會正常裁剪,但是當我移動或調整相同矩形的大小時,它不會裁剪。 如果需要移動或調整矩形的尺寸,我需要某種方法來更改矩形的尺寸和X / Y值,但是我不確定如何實現。 任何建議將不勝感激
我認為問題可能與Rectangle嵌入到ContentControl中有關。 請嘗試以下操作:
<Canvas x:Name="BackPanel" MouseLeftButtonDown="LoadedImage_MouseLeftButtonDown" MouseMove="LoadedImage_MouseMove" MouseLeftButtonUp="LoadedImage_MouseLeftButtonUp" Background="Transparent">
<Canvas.Resources>
<ControlTemplate x:Key="DesignerItemTemplate" TargetType="ContentControl">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
</ControlTemplate>
</Canvas.Resources>
<Rectangle x:Name="selectionRectangle" Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" />
</Canvas>
當Rectangle不是在畫布上,而是在Canvas上的ContentControl中時:
selectionRectangle.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X));
selectionRectangle.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y));
這些附加的屬性似乎無法按預期工作。 如果需要Rectangle位於ContentControl中,則可以在ContentControl本身(在Canvas上為子級)上設置附加屬性。
contentControl.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X));
contentControl.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.