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