2015-03-11 4 views
0

Я внедрил Crop User Control для своей программы, и я хочу добавить подвижную и изменяемую по размеру функциональность. Я в настоящее время слежу за дизайнером диаграмм Сукрама http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part-1. Но поскольку мой прямоугольник создается не до тех пор, пока пользователь не перетаскивает и не создает прямоугольник, я получаю неожиданный результат. Прямо сейчас я просто пытаюсь создать прямоугольник, который содержится внутри ContentControl, но когда я перетаскиваю мышь, чтобы создать прямоугольник, он находится в самом левом краю окна, а не в том месте, где я щелкнул мышью. Ниже приведены мои коды.Обрезка изображения после изменения размера или перемещения прямоугольника обрезки

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>  

Пользователь CodeBehind:

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); 

     } 
    } 

} 

}

Я думаю, мне нужно, чтобы получить Canvas.Top и Canvas.Bottom из прямоугольника путем связывания это в мой ContentControl, но я не знаю, как это сделать. Я везде искал, и я не мог придумать ничего. Как мне получить эти прикрепленные свойства или есть ли лучшие способы реализации перемещаемого и изменяемого размера прямоугольника обрезки?

Update:

Я сделал некоторые корректировки с моим кодом followin советы Тоби и теперь прямоугольник перемещается на полях масштабируются и, как и ожидалось. Первоначально после того, как пользователь перетаскивает мышь и создает прямоугольник, он обретает урожай, как обычно, но когда я перемещаю или изменяю размер одного и того же прямоугольника, он не обрезается. Мне нужно каким-то образом изменить размер и значение X/Y прямоугольника в моем коде, если он будет перемещен или изменен, но я не уверен, как это реализовать. Любые рекомендации будут оценены

ответ

0

Я думаю, что проблема может быть связана с тем, что 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> 

Когда прямоугольник не на холсте, а в ContentControl, который находится на холсте:

selectionRectangle.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X)); 
selectionRectangle.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y)); 

Эти присоединенные свойства проявляются не работать, как вы намерены. Если вам нужно прямоугольник, чтобы быть в ContentControl, вы можете установить вложенные свойства на самом ContentControl (что ребенок на холсте)

contentControl.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X)); 
contentControl.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y)); 
+0

@ Toby Crawford Спасибо, Ваша позже посоветует работу, где прямоугольник содержащихся внутри содержимого. Как указано в моем обновлении после изменения кода, он по-прежнему сталкивается с одной проблемой. Он не обрезается после перемещения или изменения размера прямоугольника. – mcvanta

Смежные вопросы