/// <summary>
        /// Defines a target control for the drag and drop operation.
        /// </summary>
        /// <typeparam name="TControl">The type of the control to drop on</typeparam>
        /// <param name="target">The target control to drop on</param>
        /// <param name="dragDrop">A function to handle the drop on the target control</param>
        /// <returns></returns>
        public DragOperation <T> To <TControl>(TControl target, Action <TControl, T> dragDrop) where TControl : Control
        {
            var handler = DragHandler <T> .CreateDefault();

            handler.DragDrop = (value, _) =>
            {
                _previewFormController?.Stop(target, wasCancelled: false);
                dragDrop?.Invoke(target, value);
            };

            return(To(target, handler));
        }
        /// <summary>
        /// Starts the drag and drop operation
        /// </summary>
        /// <param name="effect">The desired drag and drop effect like Copy, Move or Link</param>
        private void Start(DragDropEffects effect)
        {
            StopTrackingForDeferredStartOnMouseMove();

            var canProceed = _conditionEvaluator.Invoke();

            if (!canProceed)
            {
                return;
            }

            _previewFormController = new PreviewFormController();

            var preview = _previewEvaluator?.Invoke();

            var hookId = IntPtr.Zero;

            var resultEffect = DragDropEffects.None;

            try
            {
                hookId = NativeMethods.HookMouseMove(() => _previewFormController.Move());

                _previewFormController.Start(SourceControl, _effects, preview, _cursorOffset);

                var data = Data == null ? (object)new NullPlaceholder() : Data;
                resultEffect = SourceControl.DoDragDrop(data, effect);
            }
            finally
            {
                NativeMethods.RemoveHook(hookId);

                // always send "canceled" here -> if the drag and drop operation was successful
                // this call is too late and will not do anything
                _previewFormController.Stop(null, wasCancelled: true);

                CleanUp();
            }
        }
        /// <summary>
        /// Starts the drag and drop operation
        /// </summary>
        /// <param name="effect">The desired drag and drop effect like Copy, Move or Link</param>
        private void Start(DragDropEffects effect)
        {
            StopTrackingForDeferredStartOnMouseMove();

            var canProceed = _conditionEvaluator.Invoke();

            if (!canProceed)
            {
                return;
            }

            OnSafeguardedBeforeStart();

            _previewFormController = new PreviewFormController();

            var preview = _previewEvaluator?.Invoke();

            var hookId = IntPtr.Zero;

            var resultEffect = DragDropEffects.None;

            try
            {
                if (_allowMouseHooks)
                {
                    hookId = NativeMethods.HookMouseMove(() => _previewFormController.Move());
                }
                else
                {
                    SourceControl.GiveFeedback += SourceControl_GiveFeedback;
                }

                var offset = _offsetEvaluator?.Invoke(CalculatePreviewSize()) ?? Point.Empty;
                _previewFormController.Start(SourceControl, _effects, preview, offset);

                var data = Data == null ? (object)new NullPlaceholder() : Data;

                OnSafeguardedAfterStart();

                resultEffect = SourceControl.DoDragDrop(data, effect);
            }
            finally
            {
                if (_allowMouseHooks)
                {
                    NativeMethods.RemoveHook(hookId);
                }
                else
                {
                    SourceControl.GiveFeedback -= SourceControl_GiveFeedback;
                }

                // always send "canceled" here -> if the drag and drop operation was successful
                // this call is too late and will not do anything
                _previewFormController.Stop(null, wasCancelled: true);

                InvokeCancelIfNotDroppedAction();

                CleanUp();
            }
        }