How to handle drag/drop without violating MVVM principals?

前端 未结 5 693
时光说笑
时光说笑 2020-12-24 07:40

Currently I have in my XAML


All of

5条回答
  •  半阙折子戏
    2020-12-24 08:11

    Here is some code I wrote that allows you to drag and drop files onto a control without violating MVVM. It could easily be modified to pass the actual object instead of a file.

    /// 
    /// IFileDragDropTarget Interface
    /// 
    public interface IFileDragDropTarget
    {
        void OnFileDrop(string[] filepaths);
    }
    
    /// 
    /// FileDragDropHelper
    /// 
    public class FileDragDropHelper
    {
        public static bool GetIsFileDragDropEnabled(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsFileDragDropEnabledProperty);
        }
    
        public static void SetIsFileDragDropEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsFileDragDropEnabledProperty, value);
        }
    
        public static bool GetFileDragDropTarget(DependencyObject obj)
        {
            return (bool)obj.GetValue(FileDragDropTargetProperty);
        }
    
        public static void SetFileDragDropTarget(DependencyObject obj, bool value)
        {
            obj.SetValue(FileDragDropTargetProperty, value);
        }
    
        public static readonly DependencyProperty IsFileDragDropEnabledProperty =
                DependencyProperty.RegisterAttached("IsFileDragDropEnabled", typeof(bool), typeof(FileDragDropHelper), new PropertyMetadata(OnFileDragDropEnabled));
    
        public static readonly DependencyProperty FileDragDropTargetProperty =
                DependencyProperty.RegisterAttached("FileDragDropTarget", typeof(object), typeof(FileDragDropHelper), null);
    
        private static void OnFileDragDropEnabled(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue == e.OldValue) return;
            var control = d as Control;
            if (control != null) control.Drop += OnDrop;
        }
    
        private static void OnDrop(object _sender, DragEventArgs _dragEventArgs)
        {
            DependencyObject d = _sender as DependencyObject;
            if (d == null) return;
            Object target = d.GetValue(FileDragDropTargetProperty);
            IFileDragDropTarget fileTarget = target as IFileDragDropTarget;
            if (fileTarget != null)
            {
                if (_dragEventArgs.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    fileTarget.OnFileDrop((string[])_dragEventArgs.Data.GetData(DataFormats.FileDrop));
                }
            }
            else
            {
                throw new Exception("FileDragDropTarget object must be of type IFileDragDropTarget");
            }
        }
    }
    

    Usage:

    
    

    Ensure the DataContext inherits from IFileDragDropTarget and implements the OnFileDrop.

    public class MyDataContext : ViewModelBase, IFileDragDropTarget
    {
        public void OnFileDrop(string[] filepaths)
        {
            //handle file drop in data context
        }
    }
    

提交回复
热议问题