处理WPF按钮双击MVVM模式

时间:2013-07-10 21:08:28

标签: wpf mvvm event-handling double-click

我在MVVM应用程序中有一个按钮,它连接到视图模型中的命令。 view model命令的处理程序执行一些文件I / O(特别是调用File.Copy来创建或覆盖现有文件)。

现在,似乎当我双击按钮时,此命令处理程序将被调用两次。由于两个处理程序现在都在尝试访问同一个文件以同时复制/覆盖它,因此我收到了IOException。

有没有办法处理这种情况,除了捕获IOException并忽略它?这似乎不是一个有保障的捕获,尽管系统的其他部分可能存在无关的问题导致这种情况发生。

3 个答案:

答案 0 :(得分:1)

使用ViewModel中的值来保护发生单击时将运行的代码。设置如下值:bool bFileIO = false;

然后在你的处理函数中:

 if (!bFileIO)
 {
      bFileIO = true;
      //file IO here

      bFileIO = false;
 }

这样的事情可以保护多次点击免于尝试多次运行。

答案 1 :(得分:1)

执行此操作的最简单方法是在执行时让命令在CanExecute中返回false。这将阻止第二次点击发生(因为您的按钮将被禁用)。如果使用DelegateCommand from prism

private readonly DelegateCommand<object> copyCommand;
private bool isCopying = false;

public MyViewModel()
{
    copyCommand = new DelegateCommand<object>(
        _ => !isCopying,
        _ => 
        {
            if (isCopying) return;  // this shouldn't be required, but here for safety
            isCopying = true;
            copyCommand.RaiseCanExecuteChanged();
            // do copy
            isCopying = false;
            copyCommand.RaiseCanExecuteChanged();
        });
}

答案 2 :(得分:1)

我认为您应该使用命令的CanExecute来控制按钮。

<Button Command="{Binding WriteFileCommand}" Content="Button" Height="23" HorizontalAlignment="Left" Margin="273,194,0,0" Name="button1" VerticalAlignment="Top" Width="75" />

和viewmodel

public class MyViewModel
{
    private bool isWritingFile = false;

    public DelegateCommand WriteFileCommand
    {
        get;
        private set;
    }

    public bool IsWritingFile
    {
        get
        {
            return isWritingFile;
        }
        set
        {
            isWritingFile = value;
            WriteFileCommand.RaiseCanExecuteChanged();
        }
    }

    public MyViewModel()
    {
        WriteFileCommand = new DelegateCommand(WriteFile, CanWriteFile);
    }

    private void WriteFile()
    {
        IsWritingFile = true;

        // write the file
        // FileStream stream = new FileStrem(...)
        //

        IsWritingFile = false;
    }
}