在 MVVM 中处理复制和粘贴(剪贴板)

Jie*_*eng 4 c# wpf clipboard copy-paste mvvm

如果我想使用 MVVM 访问剪贴板,我该怎么做?

Mik*_*oux 5

While you certainly can do things like Clipboard.SetText and Clipboard.GetText in your VM, if you are an MVVM purist (like me), then I would recommend creating a ClipboardService (with an appropriate interface, so you can mock it in unit tests). Something like the following:

using System.Windows;

public class ClipboardService : IClipboardService
{
    public void SetText(string value)
    {
        Clipboard.SetText(value);
    }

    public string GetText()
    {
        return Clipboard.GetText();
    }
}
Run Code Online (Sandbox Code Playgroud)

Then you can reference it as a property in your VM like so:

public IClipboardService ClipboardService { get; set; }
Run Code Online (Sandbox Code Playgroud)

And either set it directly as a property or include it in your constructor:

public FooViewModel(IClipboardService service) {
    ClipboardService = service;
}
Run Code Online (Sandbox Code Playgroud)

And when you need it, instead of calling Clipboard.SetText directly, you can use ClipboardService.SetText instead. And you can (as mentioned before) mock it in unit tests. So, if you use Moq (like I do), you could have something like:

Mock<IClipboardService> clipMock = new Mock<IClipboardService>();
clipMock.Setup(mock => mock.GetText(It.IsAny<string>())).Returns("Foo");
Run Code Online (Sandbox Code Playgroud)

And instantiate your VM like so:

var fooVm = new FooViewModel(clipMock.Object);
Run Code Online (Sandbox Code Playgroud)

And so on.

I realize this is an ancient post, but I was looking for some best practices on Clipboards and MVVM, made my own decision while reading this post and decided to share. Hope somebody finds it useful. :-)

  • 很高兴你问。如果您正在测试的方法调用可能会影响测试结果的剪贴板,那么您不希望担心在测试运行时可能会干扰剪贴板内容的任何其他内容。通过将其包装在实现接口的服务中,您可以在单元测试期间准确控制“剪贴板”中的内容,因为与实际剪贴板功能本身相比,您更感兴趣的是测试 VM 对剪贴板数据的处理方式(其中,大概可以工作,因为它是 .NET Framework 的一部分)。哼! (2认同)