WPF中的拖放(二)
上一篇,我们实现了基本拖拽操作,今天,我们来实现,拖拽过程中鼠标跟随效果,这里我们要用到WPF新对象Adorner(装饰器)用来显示拖拽内容,如我们今天拖拽的矩形。首先,我们新建一个DragAdorner类,继承Adorner用来显示拖拽内容,代码如下
public class DragAdorner : Adorner
{
#region 变量
protected UIElement _child;
protected VisualBrush _brush;
protected UIElement _owner;
protected double XCenter;
protected double YCenter;
private double _leftOffset;
private double _topOffset;
public double Scale = 1.0;
#endregion
#region 构造函数
public DragAdorner(UIElement owner) : base(owner) { }
public DragAdorner(UIElement owner, UIElement adornElement, double opacity)
: base(owner)
{
this._owner = owner;
VisualBrush _brush = new VisualBrush(adornElement);
_brush.Opacity = opacity;
Rectangle r = new Rectangle();
r.RadiusX = 3;
r.RadiusY = 3;
r.Width = adornElement.DesiredSize.Width;
r.Height = adornElement.DesiredSize.Height;
XCenter = adornElement.DesiredSize.Width / 2;
YCenter = adornElement.DesiredSize.Height / 2;
r.Fill = _brush;
this._child = r;
}
#endregion
#region 属性
public double LeftOffset
{
get { return this._leftOffset; }
set
{
this._leftOffset = value - XCenter;
this.UpdatePosition();
}
}
public double TopOffset
{
get { return this._topOffset; }
set
{
this._topOffset = value - YCenter;
this.UpdatePosition();
}
}
protected override int VisualChildrenCount
{
get
{
return 1;
}
}
#endregion
#region 方法
private void UpdatePosition()
{
AdornerLayer adorner = (AdornerLayer)this.Parent;
if (adorner != null)
{
adorner.Update(this.AdornedElement);
}
}
protected override Visual GetVisualChild(int index)
{
return _child;
}
protected override Size MeasureOverride(Size finalSize)
{
this._child.Measure(finalSize);
return this._child.DesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
this._child.Arrange(new Rect(_child.DesiredSize));
return finalSize;
}
public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
{
GeneralTransformGroup result = new GeneralTransformGroup();
result.Children.Add(base.GetDesiredTransform(transform));
result.Children.Add(new TranslateTransform(this._leftOffset, this._topOffset));
return result;
}
#endregion
}
我们声明几个对象,并且修改上篇代码中矩形的PreviewMouseMove事件
/// <summary>
/// 拖动的区域
/// </summary>
private FrameworkElement _dragScope;
/// <summary>
/// 用于显示鼠标跟随效果的装饰器
/// </summary>
private DragAdorner _adorner;
/// <summary>
/// 用于呈现DragAdorner的图画
/// </summary>
private AdornerLayer _layer;
void rectangle1_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
this.StartDrag(e);
}
}
private void StartDrag(MouseEventArgs e)
{
this._dragScope = Application.Current.MainWindow.Content as FrameworkElement;
this._dragScope.AllowDrop = true;
DragEventHandler draghandler = new DragEventHandler(DragScope_PreviewDragOver);
this._dragScope.PreviewDragOver += draghandler;
this._adorner = new DragAdorner(this._dragScope, (UIElement)this.rectangle1, 0.5);
this._layer = AdornerLayer.GetAdornerLayer(this._dragScope as Visual);
this._layer.Add(this._adorner);
DataObject data = new DataObject(typeof(Rectangle), this.rectangle1);
DragDrop.DoDragDrop(this.rectangle1, data, DragDropEffects.Move);
AdornerLayer.GetAdornerLayer(this._dragScope).Remove(this._adorner);
this._adorner = null;
this._dragScope.PreviewDragOver -= draghandler;
}
void DragScope_PreviewDragOver(object sender, DragEventArgs args)
{
if (this._adorner != null)
{
this._adorner.LeftOffset = args.GetPosition(this._dragScope).X;
this._adorner.TopOffset = args.GetPosition(this._dragScope).Y;
}
这样,就实现了,拖拽过程中显示跟随效果。关键代码就在StartDrag(MouseEventArgs)方法中,开始拖放的时候创建显示拖拽的对象,移动过程中更改装饰坐标,鼠标释放的时候移除装饰对象。看懂了之后,会发现WPF的拖拽并不复杂,但是,如何实现不同窗体之间的拖拽呢?后面我们会做介绍。
原创文章,转载请注明: 转载自.NET开发者
本文链接地址: WPF中的拖放(二)
文章的脚注信息由WordPress的wp-posturl插件自动生成
Related posts:
