Hi,
We having a problem when trying to use the Clipboard in our Xaml application with enabled Clipboard copy functionality. The clipboard functionality works perfectly fine on any other hardware, however the failing ones are virtual PC's with installed VMWare application (provided by VMWare Horizon Client) limiting the clipboard access due policies. Here is a stack trace:
System.Runtime.InteropServices.COMException (0x800401D0): OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN)) at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) at System.Windows.Clipboard.Flush() at System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy) at System.Windows.Clipboard.SetDataInternal(String format, Object data) at System.Windows.Clipboard.SetText(String text, TextDataFormat format) at Infragistics.Controls.Editors.ClipboardManager.SetText(String text) at Infragistics.Controls.Editors.ViewSelectionManager.Copy() at Infragistics.Controls.Editors.ViewKeyboardHandler.OnKeyDown(KeyEventArgs& e) at Infragistics.Controls.Editors.Primitives.EditorDocumentViewPresenter.OnKeyDown(KeyEventArgs e) at System.Windows.UIElement.OnKeyDownThunk(Object sender, KeyEventArgs e) at System.Windows.Input.KeyEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32 scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey) at System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(MSG& msg, Boolean& handled) at System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(MSG& msg, ModifierKeys modifiers) at System.Windows.Interop.HwndSource.OnPreprocessMessage(Object param) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
We have tried various combinations with clipboard sample application and we face same problem when we try to use Clipboard.SetText(). However, we found a workaround for this error to use Clipboard.SetDataObject(object) for text and this works without any exception. Is there any chance to enhance logic to cover for Xaml to handle this at Infragistics side?
However, based on our tests it looks like this approach is affecting paste and application is hanging. We enabled in various places copy functionality like this:
<igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings SelectionTypeCell="Range" AllowClipboardOperations="Copy" CopyFieldLabelsToClipboard="True" SelectionTypeRecord="Extended" ...../> </igDP:XamDataGrid.FieldLayoutSettings>
Any suggestions on this topic?
best regards,
Tomas
Hello Tomas,
I have been investigating into the behavior you are reporting, and this issue is known, but it is not a bug that is specific to Infragistics. This issue is a bug in the .NET implementation of the clipboard in that only a single process can have the clipboard “open” at a time. If another process has the clipboard “open” on your machine in this case, it will throw this error when it tries to open. Interestingly, it is also known that the SetDataObject method tends to prevent this error from happening, and SetText tends to set it off.
For more information, I would recommend taking a look at these StackOverflow threads where the issue, and various workarounds are also discussed:
- https://stackoverflow.com/questions/68666/clipbrd-e-cant-open-error-when-setting-the-clipboard-from-net - https://stackoverflow.com/questions/12769264/openclipboard-failed-when-copy-pasting-data-from-wpf-datagrid
Please let me know if you have any other questions or concerns on this matter.
Hi Andrew,
Thanks for quick response. Based on provided links it looks like using native API problem we should not face this problem. I've tested this approach and it seems solving this problem. This raises few questions:
I've tested another suggested solution to use Clipboard.Clear() in MainWindow view but it does not solve original problem.
Took a while to find out another misleading error message which turned out outside of our control. This error message shown on copy to Clipboard with fallowing stack trace:
[External Code] win32u.dll![Frames below may be incorrect and/or missing, no symbols loaded for win32u.dll] Unknown [Managed to Native Transition] PresentationFramework.dll!System.Windows.MessageBox.ShowCore(System.IntPtr owner, string messageBoxText, string caption, System.Windows.MessageBoxButton button, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult, System.Windows.MessageBoxOptions options) Unknown PresentationFramework.dll!System.Windows.MessageBox.Show(System.Windows.Window owner, string messageBoxText, string caption, System.Windows.MessageBoxButton button, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult) Unknown InfragisticsWPF.dll!Infragistics.Windows.Utilities.ShowMessageBox(System.Windows.DependencyObject element, string messageBoxText, string caption, System.Windows.MessageBoxButton button, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.SpreadsheetUtilities.ShowMessageBox(System.Windows.FrameworkElement associatedControl, string message, string caption, System.Windows.MessageBoxButton buttons, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.XamSpreadsheet.Infragistics.Controls.Grids.Core.ISpreadsheetView.ShowMessageBox(string message, string caption, System.Windows.MessageBoxButton buttons, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.Spreadsheet.OnUserPrompt(Infragistics.Controls.Grids.Core.SpreadsheetUserPromptInfo promptInfo) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.Spreadsheet.CopyToClipboard.AnonymousMethod__265_4(object o, Infragistics.Controls.Grids.Core.WorkbookSerializationErrorEventArgs e) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.WorkbookDataObjectManager.RaiseSerializationError(bool isLoading, System.Exception exception) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.WorkbookDataObjectManager.CopyToClipboard(System.Func<bool> shouldProcessLargeCellCount) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.Spreadsheet.CopyToClipboard(bool cut) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.Spreadsheet.ExecuteCommand(Infragistics.Controls.Grids.Core.SpreadsheetCommandType command, object commandParameter, object sourceElement, Infragistics.Core.LongValue currentState) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.Spreadsheet.ProcessKeyDown(System.Windows.Input.Key key, System.Windows.Input.ModifierKeys modifierKeys) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.XamSpreadsheet.ProcessKeyDown(System.Windows.Input.KeyEventArgs e) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Primitives.SpreadsheetCellEditorBase.OnKeyDown(System.Windows.Input.KeyEventArgs e) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Primitives.SpreadsheetCellEditor.OnKeyDown(System.Windows.Input.KeyEventArgs e) Unknown PresentationCore.dll!System.Windows.UIElement.OnKeyDownThunk(object sender, System.Windows.Input.KeyEventArgs e) Unknown PresentationCore.dll!System.Windows.Input.KeyEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) Unknown PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Unknown PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Unknown PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) Unknown PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) Unknown PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Unknown PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) Unknown PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) Unknown PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawKeyboardActions actions, int scanCode, bool isExtendedKey, bool isSystemKey, int virtualKey) Unknown PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(ref System.Windows.Interop.MSG msg, ref bool handled) Unknown PresentationCore.dll!System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(ref System.Windows.Interop.MSG msg, System.Windows.Input.ModifierKeys modifiers) Unknown PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessage(object param) Unknown WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority priority, System.Delegate method, object arg) Unknown PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessageThunk(ref System.Windows.Interop.MSG msg, ref bool handled) Unknown PresentationCore.dll!System.Windows.Interop.HwndSource.WeakEventPreprocessMessage.OnPreprocessMessage(ref System.Windows.Interop.MSG msg, ref bool handled) Unknown WindowsBase.dll!System.Windows.Interop.ComponentDispatcherThread.RaiseThreadMessage(ref System.Windows.Interop.MSG msg) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Unknown PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Unknown PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) Unknown PresentationFramework.dll!System.Windows.Application.Run() Unknown> EafClient.exe!EafClient.Client.App.Main(string[] args) Line 109 C#
The error mentioned for "Paste" operation but it was copy to clipboard operation.
Thank you for your update(s) on this matter.
Regarding the message box from the XamSpreadsheet control, it appears that there is an issue with the resource strings internally, where we are using the “Paste error” resource string rather than a copy one in the case of an error with a copy operation. I will be writing this up and fixing it shortly and it should be available in an upcoming release patch.
Regarding your questions on this matter, I will answer them in the order they were asked:
1. By the “selected control context,” I imagine you are referring to getting what Infragistics control may be focused at a particular time in this case. The best thing I can recommend in that case is to use the static, .NET Keyboard.FocusedElement property, as this will return you the element that has keyboard focus at any particular time. There is no “selected control context” that we expose that will tell you for certain which Infragistics control is focused at a particular time.
2. The reason that we do not implement the native clipboard API code in our code as a workaround is because this would cause quite a bit of unnecessary code pollution for a bug that isn’t actually ours, and only happens in edge cases where something else has the Clipboard open. In all other cases, this issue does not occur. This is a bug in the Clipboard in .NET, and to prove it, I would recommend you take a look at the description and sample project posted at the end of the following forum thread, which reproduces the same error without the use of any Infragistics controls: https://es.infragistics.com/community/forums/f/ultimate-ui-for-wpf/120008/xamdatagrid-ctrl-c-copy-operation-on-a-single-cell-or-on-multiple-cells-is-throwing-copy-error.
I do believe that I recall reading somewhere that this behavior was resolved in later versions of .NET as well. I am curious what version of the .NET Framework you are using?
Our team has suggested to have other approach: to catch and ignore this error message. However, I see a problem here that this message comes from Infragistics and not from our side. How it is possible to customize the messages raised by Infragistics?
PresentationFramework.dll!System.Windows.MessageBox.ShowCore(System.IntPtr owner, string messageBoxText, string caption, System.Windows.MessageBoxButton button, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult, System.Windows.MessageBoxOptions options) Unknown PresentationFramework.dll!System.Windows.MessageBox.Show(System.Windows.Window owner, string messageBoxText, string caption, System.Windows.MessageBoxButton button, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult) Unknown InfragisticsWPF.dll!Infragistics.Windows.Utilities.ShowMessageBox(System.Windows.DependencyObject element, string messageBoxText, string caption, System.Windows.MessageBoxButton button, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.SpreadsheetUtilities.ShowMessageBox(System.Windows.FrameworkElement associatedControl, string message, string caption, System.Windows.MessageBoxButton buttons, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.XamSpreadsheet.Infragistics.Controls.Grids.Core.ISpreadsheetView.ShowMessageBox(string message, string caption, System.Windows.MessageBoxButton buttons, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.Spreadsheet.OnUserPrompt(Infragistics.Controls.Grids.Core.SpreadsheetUserPromptInfo promptInfo) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.Spreadsheet.CopyToClipboard.AnonymousMethod__265_4(object o, Infragistics.Controls.Grids.Core.WorkbookSerializationErrorEventArgs e) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.WorkbookDataObjectManager.RaiseSerializationError(bool isLoading, System.Exception exception) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.WorkbookDataObjectManager.CopyToClipboard(System.Func<bool> shouldProcessLargeCellCount) Unknown InfragisticsWPF.Controls.Grids.XamSpreadsheet.dll!Infragistics.Controls.Grids.Core.Spreadsheet.CopyToClipboard(bool cut) Unknown
We should be able to customize all Infragistics shown messages. If this is not possible then we would request to have ability since this is not the first message we see but we can't even control or change it. Not to mention that text is misleading: on copy says error on paste.
Thank you for confirming that you are using the XamDataGrid, XamSpreadsheet, and XamSyntaxEditor and that you are targeting .NET 6.
Regarding copying text from the XamDataGrid, the best thing I can recommend is to utilize the SelectedItems collection of the grid. This collection has Records and Cells sub-collections that can return you the selected rows or cells. The XamSpreadsheet can be retrieved using its ActiveSelection property.
Regarding the XamSyntaxEditor, I believe the best option would likely be to utilize the ClipboardOperationExecuting/Executed events. The event arguments will return you the type of operation that is executing as well as the data object that is being copied in the case of the Copy clipboard operation.
Hello Andrew,
Sorry for confusion, we are using xamDataGrid and not GridView. With regards mentioned controls - we use most of time xamSpreadhsheet and xamSyntaxEditor for clipboard actions. The xamDataGrid is less used but it is enabled in few places for copy only. We will have to discuss with team and product owners to make decision on next actions.
The .NET 6 is our target. However, we have a huge challenge since we provide lots of products which are incorporated to work together very tightly, thus this challenge is very high and fragile to make it backwards compatible with all other products since upgrade for some products is slow and for some is quick. Not to mention that we are still using unsupported in .NET WCF as well as depended on few third party libraries. So upgrade wont be fast but first step is planned for next year.
I noticed in your most recent update that you mentioned a “XamGridView” – if at all possible I would recommend upgrading to the XamDataGrid if you are not using it already. The XamGrid is a retired and unsupported control at this point and has been marked obsolete to the XamDataGrid.
Regarding a workaround for this behavior though, I am unsure if the ViewSelectionManager will really help you in this case. The ViewSelectionManager is a public class, but it is used with the XamRichTextEditor and XamSyntaxEditor for copying and pasting text in those controls – it will not help you with cell-based controls like the XamSpreadsheet and XamDataGrid. The ClipboardManager is an internal class and so is not publicly accessible.
Both the XamSpreadsheet and XamDataGrid do expose ways to get the current selected cells though. The XamSpreadsheet through its ActiveSelection property and the XamDataGrid through its SelectedItems collection. My best recommendation would be to utilize these to construct the item that should go to the clipboard.
It’s also worth noting that most of the occurrences of this error seem to be referenced in older forum threads from various sources. I am curious if perhaps this issue has been fixed in later versions of the .NET Framework or potentially .NET Core / .NET 5 / .NET 6. What version of .NET are you currently targeting?
Thanks for clarification. I was able to reproduce same clipboard problem with simple console application on virtual PC and this is really problem inside of .NET framework.
Considering a workaround to replace .NET clipboard functionality I've tried to access the Keyboard.FocusedElement to get text for setting clipboard value but I did not found a sample on stackoverflow how to create text from selected range of cells in xamGridview or xamSpreadsheet controls. Based on testing I see I can iterate all cells and grab labels with values and manually generate text. Is there any other quick way to create text for clipboard? I was expecting I could access to Infragistics.Controls.Editors.ClipboardManager or Infragistics.Controls.Editors.ViewSelectionManager to get text before setting the clipboard.