原文:
DragControl
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Vblegend_2013/article/details/83791159
<UserControl x:Class="ImageView.DragControl"
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:local="clr-namespace:ImageView"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<Style TargetType="{x:Type Thumb}" x:Key="CornerThumbStyle">
<Setter Property="Width" Value="{Binding CornerWidth, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
<Setter Property="Height" Value="{Binding CornerWidth, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
<Setter Property="BorderBrush" Value="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border SnapsToDevicePixels="True"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Thumb}" x:Key="AreaThumbStyle">
<Setter Property="BorderBrush" Value="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Rectangle Margin="0"
Fill="{TemplateBinding Background}" SnapsToDevicePixels="True"
Stroke="{TemplateBinding BorderBrush}" Stretch="Fill"
StrokeThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness.Top, Mode=OneWay}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="PART_MainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--MiddleCenter-->
<Thumb Tag="8"
Focusable="True"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
BorderThickness="1"
Style="{StaticResource AreaThumbStyle}" Grid.RowSpan="3" Grid.ColumnSpan="3" Cursor="SizeAll" />
<!--TopLeft-->
<Thumb Tag="7" Visibility="{Binding ThumbVisible, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
BorderThickness="2.5"
Margin="-2,-2,0,0"
Opacity="{Binding ThumbOpacity, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource CornerThumbStyle}" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Cursor="SizeNWSE"/>
<!--TopCenter-->
<Thumb Tag="0" Visibility="{Binding ThumbVisible, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
BorderThickness="2.5"
Margin="0,-2,0,0"
Style="{StaticResource CornerThumbStyle}"
Grid.Row="0"
Opacity="{Binding ThumbOpacity, UpdateSourceTrigger=PropertyChanged}"
Grid.Column="1"
HorizontalAlignment="Center" VerticalAlignment="Top" Cursor="SizeNS"/>
<!--TopRight-->
<Thumb Tag="1" Visibility="{Binding ThumbVisible, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
Margin="0,-2,-2,0"
Opacity="{Binding ThumbOpacity, UpdateSourceTrigger=PropertyChanged}"
BorderThickness="2.5"
Style="{StaticResource CornerThumbStyle}" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Top" Cursor="SizeNESW"/>
<!--MiddleLeft-->
<Thumb Tag="6" Visibility="{Binding ThumbVisible, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
Margin="-2,0,0,0"
BorderThickness="2.5"
Opacity="{Binding ThumbOpacity, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource CornerThumbStyle}" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" Cursor="SizeWE"/>
<!--MiddleRight-->
<Thumb Tag="2" Visibility="{Binding ThumbVisible, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
Margin="0,0,-2,0"
BorderThickness="2.5"
Opacity="{Binding ThumbOpacity, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource CornerThumbStyle}" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Cursor="SizeWE"/>
<!--BottomLeft-->
<Thumb Tag="5" Visibility="{Binding ThumbVisible, UpdateSourceTrigger=PropertyChanged}"
Margin="-2,0,0,-2"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
BorderThickness="2.5"
Opacity="{Binding ThumbOpacity, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource CornerThumbStyle}" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Bottom" Cursor="SizeNESW"/>
<!--BottomCenter-->
<Thumb Tag="4" Visibility="{Binding ThumbVisible, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
Margin="0,0,0,-2"
BorderThickness="2.5"
Opacity="{Binding ThumbOpacity, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource CornerThumbStyle}" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Cursor="SizeNS"/>
<!--BottomRight-->
<Thumb Tag="3" Visibility="{Binding ThumbVisible, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=BorderBrush}"
BorderThickness="2.5"
Margin="0,0,-2,-2"
Opacity="{Binding ThumbOpacity, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource CornerThumbStyle}" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE"/>
</Grid>
</UserControl>
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
namespace ImageView
{
/// <summary>
/// DragControl.xaml 的交互逻辑
/// </summary>
public partial class DragControl : UserControl, INotifyPropertyChanged
{
public DragControl()
{
InitializeComponent();
AddHandler(Thumb.DragStartedEvent, new RoutedEventHandler(Drag_Started));
AddHandler(Thumb.DragDeltaEvent, new DragDeltaEventHandler(Drag_Delta));
AddHandler(Thumb.DragCompletedEvent, new RoutedEventHandler(Drag_Completed));
AddHandler(Thumb.GotFocusEvent, new RoutedEventHandler(OnGotFocus));
AddHandler(Thumb.LostFocusEvent, new RoutedEventHandler(OnLostFocus));
this.DataContext = this;
ThumbOpacity = 1.0f;
}
private void OnLostFocus(object sender, RoutedEventArgs e)
{
ThumbVisible = Visibility.Collapsed;
}
private void OnGotFocus(object sender, RoutedEventArgs e)
{
ThumbVisible = Visibility.Visible;
}
private void Drag_Started(object sender, RoutedEventArgs e)
{
ThumbOpacity = 0.1;
this.RaiseEvent( new RoutedEventArgs() { Source = this, RoutedEvent = OnDragStartedEvent });
}
private void Drag_Delta(object sender, DragDeltaEventArgs e)
{
Thumb thumb = e.OriginalSource as Thumb;
if (thumb == null)
{
return;
}
Int32 DragDirection = -1;
if (!Int32.TryParse((String)thumb.Tag, out DragDirection))
{
return;
}
double VerticalChange = e.VerticalChange;
double HorizontalChange = e.HorizontalChange;
Double left = Canvas.GetLeft(this);
Double top = Canvas.GetTop(this);
Double width = this.Width;
Double height = this.Height;
switch (DragDirection)
{
case 7:
height = this.Height - VerticalChange < 1 ? 1 : this.Height - VerticalChange;
top = Canvas.GetTop(this) + (this.Height - height);
width = this.Width - HorizontalChange < 1 ? 1 : this.Width - HorizontalChange;
left = Canvas.GetLeft(this) + (this.Width - width);
break;
case 0:
height = this.Height - VerticalChange < 1 ? 1 : this.Height - VerticalChange;
top = Canvas.GetTop(this) + (this.Height - height);
break;
case 1:
height = this.Height - VerticalChange < 1 ? 1 : this.Height - VerticalChange;
top = Canvas.GetTop(this) + (this.Height - height);
width = this.Width + HorizontalChange;
break;
case 6:
width = this.Width - HorizontalChange < 1 ? 1 : this.Width - HorizontalChange;
left = Canvas.GetLeft(this) + (this.Width - width);
break;
case 8:
left = Canvas.GetLeft(this) + HorizontalChange;
top = Canvas.GetTop(this) + VerticalChange;
break;
case 2:
width = this.Width + HorizontalChange;
break;
case 5:
width = this.Width - HorizontalChange < 1 ? 1 : this.Width - HorizontalChange;
left = Canvas.GetLeft(this) + (this.Width - width);
height = this.Height + VerticalChange;
break;
case 4:
height = this.Height + VerticalChange;
break;
case 3:
width = this.Width + HorizontalChange;
height = this.Height + VerticalChange;
break;
default:
break;
}
width = width < 1 ? 1 : width;
this.Width = width;
height = height < 1 ? 1 : height;
this.Height = height;
Canvas.SetTop(this, top);
Canvas.SetLeft(this, left);
this.RaiseEvent(new RoutedEventArgs() { Source = this, RoutedEvent = OnDragDeltaEvent });
//
e.Handled = true;
}
private void Drag_Completed(object sender, RoutedEventArgs e)
{
Rect NewBound = new Rect
{
Y = Canvas.GetTop(this),
X = Canvas.GetLeft(this),
Width = this.ActualWidth,
Height = this.ActualHeight
};
this.RaiseEvent(new RoutedEventArgs() { Source = this, RoutedEvent = OnDragCompletedEvent });
ThumbOpacity = 1;
e.Handled = true;
}
/// <summary>
/// 声明路由事件
/// 参数:要注册的路由事件名称,路由事件的路由策略,事件处理程序的委托类型(可自定义),路由事件的所有者类类型
/// </summary>
public static readonly RoutedEvent OnDragStartedEvent = EventManager.RegisterRoutedEvent("OnDragStarted", RoutingStrategy.Bubble, typeof(RoutedEventArgs), typeof(DragControl));
/// <summary>
/// 处理各种路由事件的方法
/// </summary>
public event RoutedEventHandler OnDragStarted
{
//将路由事件添加路由事件处理程序
add { AddHandler(OnDragStartedEvent, value, false); }
//从路由事件处理程序中移除路由事件
remove { RemoveHandler(OnDragStartedEvent, value); }
}
/// <summary>
/// 声明路由事件
/// 参数:要注册的路由事件名称,路由事件的路由策略,事件处理程序的委托类型(可自定义),路由事件的所有者类类型
/// </summary>
public static readonly RoutedEvent OnDragCompletedEvent = EventManager.RegisterRoutedEvent("OnDragCompleted", RoutingStrategy.Bubble, typeof(RoutedEventArgs), typeof(DragControl));
/// <summary>
/// 处理各种路由事件的方法
/// </summary>
public event RoutedEventHandler OnDragCompleted
{
//将路由事件添加路由事件处理程序
add { AddHandler(OnDragCompletedEvent, value, false); }
//从路由事件处理程序中移除路由事件
remove { RemoveHandler(OnDragCompletedEvent, value); }
}
/// <summary>
/// 声明路由事件
/// 参数:要注册的路由事件名称,路由事件的路由策略,事件处理程序的委托类型(可自定义),路由事件的所有者类类型
/// </summary>
public static readonly RoutedEvent OnDragDeltaEvent = EventManager.RegisterRoutedEvent("OnDragDelta", RoutingStrategy.Bubble, typeof(RoutedEventArgs), typeof(DragControl));
/// <summary>
/// 处理各种路由事件的方法
/// </summary>
public event RoutedEventHandler OnDragDelta
{
//将路由事件添加路由事件处理程序
add { AddHandler(OnDragDeltaEvent, value, false); }
//从路由事件处理程序中移除路由事件
remove { RemoveHandler(OnDragDeltaEvent, value); }
}
public Double ThumbOpacity
{
get
{
return __thumbopacity;
}
set
{
__thumbopacity = value;
RaisePropertyChanged("ThumbOpacity");
}
}
private Double __thumbopacity { get; set; }
public Visibility ThumbVisible
{
get
{
return __thumbvisible;
}
set
{
__thumbvisible = value;
RaisePropertyChanged("ThumbVisible");
}
}
private Visibility __thumbvisible { get; set; }
protected void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}