【发布时间】:2020-02-12 09:31:04
【问题描述】:
我的 ViewModel 中有一个由 ObservableCollection 对象支持的 DataGrid。我还有一个上下文菜单,其中包含使用默认复制命令的复制条目。我希望能够copy data from the DataGrid,但是当我单击“复制”菜单项时,WPF 会抛出此异常:
OpenClipboard Failed (Exception from HRESULT: 0x800301D0 (CLIPBRD_E_CANT_OPEN))
视图模型
public class ViewModel
{
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public ObservableCollection<Person> People { get; set; }
public ViewModel()
{
People = new ObservableCollection<Person>
{
new Person {FirstName = "Heir", LastName = "Band"},
new Person {FirstName = "Rose", LastName = "Anne"},
new Person {FirstName = "Tim", LastName = "Poral"}
};
}
}
XAML
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Grid>
<DataGrid ItemsSource="{Binding Path=People}">
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Copy" Command="Copy" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</Grid>
</Window>
我见过其他descriptions of this exception。然而:
- 我使用的是 Visual Studio 2017,而不是 2019。
- 我没有使用 SetText 或 SetDataObject,也没有为此调用任何东西。
- 无论我是否在 Visual Studio 中运行,异常每次都会发生,而不是间歇性发生。
- 我对诸如“myDataGrid_CopyingRowClipboardContent”之类的代码隐藏不感兴趣,因为我使用的是 MVVM。
更多信息 - 2019 年 10 月 17 日
在Abin Mathew 发布his answer 之后,我做了更多的挖掘工作。虽然他的回答是一个很好的回答,而且它有效——它不使用WPF Commanding,而是使用RelayCommand。没关系。此问题未指定必须使用 WPF 命令。
但是,我仍然想知道为什么 WPF 命令复制不适用于 DataGrid。事实上,它确实有效——它只是取决于时间。如果你运行我上面贴的代码,但是在System.Windows.Clipbard.Flush和System.Windows.Controls.DataGrid.OnExecutedCopy处设置断点,然后每次遇到断点都点击运行按钮,复制就会成功:
总之:
- RelayCommand 用于执行复制。
- WPF 命令也“有效”。
- WPF 命令管理从选定的 DataGrid 行本身获取发往剪贴板的数据。
- 当从 DataGrid 复制时,出现某种竞争条件导致 WPF 命令无法访问刷新剪贴板。
- 要么我需要更多代码来防止出现这种竞争状况,要么 Microsoft 引入了一个错误,该错误会破坏 WPF 从 DataGrid 中命令复制。
【问题讨论】:
-
您能否分享您的命令代码
Copy(应该是您班级的属性Person)? -
@Corentin Pane - 我没有 Copy 的代码。这完全由 .NET 实现。
标签: c# wpf mvvm datagrid clipboard