Hi,
I'm searching a way to highlight all supported drop zone in a control, when a drag start (and of course reverse to normal when drag end)... and using MVVM.
Is there something already existing about this use case ?
Thanks !
Regards,
4 Answers, 1 is accepted
You would need to manually implement such a behavior by using the events of the DragDropManager for WPF. For more details about the events please check the following article from our online help documentation:
http://docs.telerik.com/devtools/wpf/controls/dragdropmanager/events
Hope this helps.
Regards,
Kalin
Telerik
Hi Dear Tech Support,
I would like to know if you have any sample for the implementation. I am kind of new to this and would appreciate any help from you.
Yours Faithfully,
Dev
Unfortunately we don't have such a sample prepared. However we will be glad to help you during the implementation - if you have any questions or concerns please let us know.
Regards,
Kalin
Telerik
Hi,
I'm now implementing the feature, but the only way I find is quite ugly.
On my DropBehavior class (to bind a ICommand to the Control drop event) , I have a static IList<DropBehavior> referencing all the instances of the class (added on OnAttached and removed on OnDetached).
Additionaly, I have a static timer ticking every 250ms, which is checking if DragDropManager.IsDragInProgress has changed. If so, it change the Background of the referenced controls, or restore the initial Background.
Thanks to propose another approach to solve this feature.
public class CommandDropBehavior : Behavior<Control> { #region statics // timer thread not stopped on exit ! static System.Timers.Timer _timer; // reference class instances (ugly) static IList<CommandDropBehavior> _attached; // current dragdrop state static bool _marked = false; // static ctor static CommandDropBehavior() { _attached = new List<CommandDropBehavior>(); _timer = new Timer(500); _timer.Elapsed += _timer_Elapsed; _timer.Start(); } static void _timer_Elapsed(object sender, ElapsedEventArgs e) { // drag and not yet marked : mark if (DragDropManager.IsDragInProgress && !_marked) Dragging(); else if(_marked) // no drag, and currently marked : restore EndDrag(); } static void Dragging() { _marked = true; foreach (var control in _attached.ToList()) // collection thread issue : copy before iterate { control.Mark(); } } static void EndDrag() { foreach (var control in _attached.ToList()) // collection thread issue : copy before iterate { control.Restore(); } } #endregion Brush _initialBackgroundBrush; // methods called by static enumeration private void Restore() { //perf issue : call dispatcher here one by one, or one for all from the enumerator ? App.Current.Dispatcher.Invoke(() => AssociatedObject.Background = _initialBackgroundBrush); } private void Mark() { App.Current.Dispatcher.Invoke(() => AssociatedObject.Background = ThemeHelper.BackGreen); } // behavior attach protected override void OnAttached() { base.OnAttached(); //reference myself _attached.Add(this); // save initial brush _initialBackgroundBrush = AssociatedObject.Background; // bind event AssociatedObject.Drop += AssociatedObject_Drop; // allow drop AssociatedObject.AllowDrop = true; } // behavior detach protected override void OnDetaching() { base.OnDetaching(); //dereference _attached.Remove(this); //derefence AssociatedObject.Drop -= AssociatedObject_Drop; } // drop event void AssociatedObject_Drop(object sender, System.Windows.DragEventArgs e) { // try get dropped file from windows explorer object payload = e.Data.GetData("FileDrop"); if (payload == null) { //if not, try to get business objects List<object> datas = (List<object>)e.Data.GetData(typeof(ResultatRecherche)); if (datas != null && datas.Any()) payload = datas.First(); else { var doc = e.Data.GetData(typeof(DocumentAssocies)); payload = doc; } } var param = new DropParameter { DraggedItem = payload, DataContext = AssociatedObject.DataContext, }; Control target = sender as Control; if (target != null) param.TargetTag = target.Tag; //Execute binded ICommand if (DropCommand != null && DropCommand.CanExecute(param))// && e.Source != e.OriginalSource) { DropCommand.Execute(param); e.Handled = true; } // set back to normal state Restore(); } public ICommand DropCommand { get { return (ICommand)GetValue(DropCommandProperty); } set { SetValue(DropCommandProperty, value); } } // Using a DependencyProperty as the backing store for DropCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty DropCommandProperty = DependencyProperty.Register("DropCommand", typeof(ICommand), typeof(CommandDropBehavior), new PropertyMetadata(null)); public string DropAcceptance { get { return (string)GetValue(DropAcceptanceProperty); } set { SetValue(DropAcceptanceProperty, value); } } // Using a DependencyProperty as the backing store for DropCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty DropAcceptanceProperty = DependencyProperty.Register("DropAcceptance", typeof(string), typeof(CommandDropBehavior), new PropertyMetadata(null)); }