public class DragOnCanvasBehavior : Behavior<DependencyObject>
{
// the mouse over adorner template property
public static readonly DependencyProperty MouseOverAdornerTemplateProperty =
DependencyProperty.Register(
"MouseOverAdornerTemplate",
typeof(DataTemplate),
typeof(DragOnCanvasBehavior),
new PropertyMetadata(new PropertyChangedCallback((d, o) =>
{
if (((DragOnCanvasBehavior)d).mouseOverAdornerControl != null)
{
((DragOnCanvasBehavior)d).mouseOverAdornerControl.ContentTemplate = (DataTemplate)o.NewValue;
}
})));
// the template
public DataTemplate MouseOverAdornerTemplate
{
get { return (DataTemplate)this.GetValue(MouseOverAdornerTemplateProperty); }
set { this.SetValue(MouseOverAdornerTemplateProperty, value); }
}
// stores the adorner instance
private TemplateAdorner mouseOverAdorner;
// stores the visual control
private ContentControl mouseOverAdornerControl;
// whether the adorner is initialized
private bool mouseOverAdornerInitialized = false;
// whether the adorner is shown
private bool mouseOverAdornerShown = false;
// the commands to hide/show the adorner
public ICommand HideMouseOverAdorner { get; private set; }
public ICommand ShowMouseOverAdorner { get; private set; }
// binds the commands with the methods
public DragOnCanvasBehavior()
{
// [...]
this.ShowMouseOverAdorner = new RelayCommand((o) =>
{
this.OnShowMouseOverAdorner();
});
this.HideMouseOverAdorner = new RelayCommand((o) =>
{
this.OnHideMouseOverAdorner();
});
}
// shows the adorner
private void OnShowMouseOverAdorner()
{
if (this.mouseOverAdornerShown)
{
return;
}
this.InitializeAdorner(this.MouseOverAdornerTemplate, ref this.mouseOverAdornerControl, ref this.mouseOverAdorner, ref this.mouseOverAdornerInitialized);
this.mouseOverAdornerControl.Visibility = Visibility.Visible;
this.mouseOverAdornerShown = true;
}
// hides the adorner
private void OnHideMouseOverAdorner()
{
this.mouseOverAdornerControl.Visibility = Visibility.Collapsed;
this.mouseOverAdornerShown = false;
}
// initializes an adorner (we'll need to reuse this later on)
private void InitializeAdorner(DataTemplate template, ref ContentControl control, ref TemplateAdorner adorner, ref bool initialized)
{
if (initialized)
{
return;
}
if (template != null)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.AssociatedObject as UIElement);
if (adornerLayer == null)
{
throw new NullReferenceException(string.Format("No adorner found in attached object: {0}", this.AssociatedObject));
}
control = new ContentControl();
adornerLayer.Add(adorner = new TemplateAdorner(this.AssociatedObject as UIElement, control));
control.Content = template.LoadContent();
Binding bindingMargin = new Binding("AdornerMargin");
bindingMargin.Source = this;
BindingOperations.SetBinding(adorner, ContentControl.MarginProperty, bindingMargin);
}
var dataContext = (this.AssociatedObject as FrameworkElement).DataContext;
if (control.DataContext == null)
{
control.DataContext = dataContext;
}
control.Visibility = Visibility.Collapsed;
initialized = true;
}
}