.net - 如何在不违反 MVVM 原则的情况下处理拖放?

标签 .net wpf mvvm drag-and-drop

目前我在我的 XAML

<TabControl  
    AllowDrop="True"
    PreviewDragOver="DragOver"
    PreviewDrop="Drop" />

我所有的拖放代码都存在于我的 View 的代码隐藏中,而不是我的 ViewModel 中。

如何在 ViewModel 中处理拖放而不在 View 上添加任何依赖项?

最佳答案

这是我编写的一些代码,允许您在不违反 MVVM 的情况下将文件拖放到控件上。它可以很容易地修改为传递实际对象而不是文件。

/// <summary>
/// IFileDragDropTarget Interface
/// </summary>
public interface IFileDragDropTarget
{
    void OnFileDrop(string[] filepaths);
}

/// <summary>
/// FileDragDropHelper
/// </summary>
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");
        }
    }
}

用法:

<ScrollViewer AllowDrop="True" Background="Transparent" utility:FileDragDropHelper.IsFileDragDropEnabled="True" utility:FileDragDropHelper.FileDragDropTarget="{Binding}"/>

确保 DataContext 继承自 IFileDragDropTarget 并实现 OnFileDrop。

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

关于.net - 如何在不违反 MVVM 原则的情况下处理拖放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5916154/

相关文章:

.net - 使用 Windows Identity Foundation 和 MVC 使声明过期

c# - 在 WPF 中使用 CollectionView 时无法从数据集中的连接表中获取数据

c# - 未启用时更改按钮背景

wpf - WCF服务中的CommunicationObjectAbortedException和CommunicationObjectFaultedException

c# - 我应该如何过滤绑定(bind)到网格的 IReactiveList?

c# - 如何使用tabControl在XAML中使用两个ViewModels代码

c# - 为什么未使用的物理线程数在 .NET 应用程序中波动?

c# - 检查 Get-NetTCPConnection 对象是否存在

swift - 如何在 MVVM 模式中设置托管对象之间的关系?

.net - VB.NET中捕获功能键F1..F12