在 WPF 块资源管理器中拖放



在我的 WPF 应用程序中,我接受拖放文件,在检查它们是否是我想要的输入后,我打开一个弹出窗口供用户输入有关已删除文件的所有必要信息。我只使用拖放事件中的文件名。

我的应用程序运行没有任何问题。但是,我注意到当我删除文件时,Windows 资源管理器变得无响应,如果我将鼠标指针悬停在它上面,我会得到一个"拖动"鼠标指针,直到应用程序中的弹出窗口再次关闭。

如果这很重要,我会赢 10。我该如何解决这个问题?

XAML:

 <Grid AllowDrop="True" Drop="Grid_Drop"> ... </Grid>

XAML.CS:

private void Grid_Drop(object sender, DragEventArgs e)
{
    if(e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        var files = (string[])e.Data.GetData(DataFormats.FileDrop);
        foreach (var file in files)
        {
            // ... Check if file is acceptable and if so, open window
            ShowCreateEditWindow(file);                       
        }
    }
}
private void ShowCreateEditWindow(string filePath)
{
    var win2 = new CreateEditWindow();
    win2.DataContext = this;
    win2.CreateEdit.Title = "Adding entry";
    win2.fileLabel.Content = filePath;
    if (win2.ShowDialog() == true)
    {
        // If everything is ok, do other stuff
    }
    else return;
}

我遇到了同样的问题,并使用以下方法解决了它:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.timer = new DispatcherTimer();
        this.timer.Interval = TimeSpan.FromSeconds(1);
        this.timer.Tick += new EventHandler(timer_Tick);
        this.timer.Start();
    }
    void timer_Tick(object sender, EventArgs e)
    {
        if (this.dropData != null) {
            ProcessDropData(this.dropData);
            this.dropData = null;
        }
    }
    private void Window_Drop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
            this.dropData = e.Data.GetData(DataFormats.FileDrop);
        }
    }
    private void ProcessDropData(object data)
    {
        string[] paths = (string[])data;
        // do work here
    }
    private DispatcherTimer timer;
    private object dropData;
}

使用DispatcherTimer允许在 UI 线程中的稍后点处理数据。

使用 win2.Show() 而不是win2.ShowDialog ,ShowDialog 会创建一个阻止窗口。这意味着您不能使用

if (win2.ShowDialog() == true)

了。您可能应该将其替换为某些事件系统。

您可以使用

Dispatcher.BeginInvoke() 来解决此问题。这将安排委托在 UI 线程的下一个空闲时段运行。这意味着拖放操作将首先完成,并且资源管理器不会被锁定。

最新更新