I've got a WPF application using datagrid. The application worked fine until I installed Visual Studio 2012 and Blend+SketchFlow preview. Now, when I'm trying to copy the data from the grid into the clipboard with Ctrl + C (in any application), I'm getting the following exception:
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.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode, IntPtr errorInfo)
at System.Windows.Clipboard.Flush()
at System.Windows.Clipboard.CriticalSetDataObject(Object data, Boolean copy)
at System.Windows.Controls.DataGrid.OnExecutedCopy(ExecutedRoutedEventArgs args)
at System.Windows.Controls.DataGrid.OnExecutedCopy(Object target, ExecutedRoutedEventArgs args)
at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
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.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
at System.Windows.Input.CommandManager.TranslateInput(IInputElement targetElement, InputEventArgs inputEventArgs)
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 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
at System.Windows.Interop.HwndSource.OnPreprocessMessageThunk(MSG& msg, Boolean& handled)
at System.Windows.Interop.HwndSource.WeakEventPreprocessMessage.OnPreprocessMessage(MSG& msg, Boolean& handled)
at System.Windows.Interop.ComponentDispatcherThread.RaiseThreadMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
This is really annoying.
I've seen some references to this problem here and on various locations on the web, with no real solution.
I can verify that the clipboard is locked when this exception is raised in Visual Studio, as I couldn't copy paste the message (had to write it to a file). Also, the clipboard wasn't locked before the copy process started.
How to solve this problem?
I had the same problem in copying Excel cells to the clipboard and getting data from the clipboard as an HTML string.
You can use (while-try-catch) like in the below code.
Also, you can have a counter in the
while
if the loop is more than 10 times or more, exception occur. I test its maximum counter is one and in one time loop clipboard work.We are using .NET 4.0. We had the same problem, but after logging off the system, code used to work fine for some time.
Finally we found the alternative.
If you want to copy a string to the clipboard,
Till now I was using the following method
It was failing again and again. Then I looked at other methods available to set text in the clipboard in Clipboard Class and tried the following:
And it worked :). I never had the issue again.
There's a DataGrid event/method signature for this exact purpose CopyingRowClipboardContent(object sender, DataGridRowClipboardEventArgs e) and is more reliable than Clipboard.SetDataObject(data) or Clipboard.SetText(data).
Here's how to use it.
Set "FullRow" at the SelectionUnit mode for dataGrid called myDataGrid
We have a method, myDataGrid_CopyingRowClipboardContent, that gets called for each row in the dataGrid to copy its contents to the clipboard. For example,for a datagrid with seven rows this is called seven times.
It is a bug in the WPF Clipboard handler. You need to handle the unhandled exception in the Application.DispatcherUnhandledException event.
Add this attribute to the
Application
element in your App.xamlAdd this code to your App.xaml.cs file
Adding my answer from mentioned SO question for reference -
Found this from Andrew Smith at http://blogs.infragistics.com/forums/t/35379.aspx -
Same thing is explained and some ways to fix it are mentioned on this italian blog -
Following MSDN forum thread suggests that this could be machine specific problem, can you reproduce this on other machines? -
Update:
Blog link seems to be down but a cached version can be accessed through this link -
WPF DataGrid Clipboard BUG (?) & Work (Cached translation)
I, too, have been having a problem in an application where I copy information into the clipboard as users peruse a ListBox. The information that's copied is related to the selected item, and it permits them to paste it (said info) into other applications for convenience. Occasionally I get the CLIPBRD_E_CANT_OPEN on some user's systems, but not on others.
While I still haven't been able to fix the contention, I was able to create some code to find the application causing the contention. I'd like to at least share this code in the hope it helps someone. I will add the using statement, attributes, and method I created to find the Process object of the culprit. From the Process item you can obtain the process' name, PID, main window title (if it has one), and other potentially useful data. Here's the lines of code I added without the code that calls it. (NOTE: Below the code snippet I have one more tidbit to share):
...
...
OTHER NOTE: One other thing I changed which simplified my code a bit was to convert from using System.Windows.Clipboard to System.Windows.Forms.Clipboard (see System.Windows.Forms.Clipboard Class)because the latter has a 4-parameter SetDataObject() method which includes a retry count and a retry delay in milliseconds. This at least removed some of the retry noise from my code.
Your mileage may vary...plus there may be side effects in this which I've not yet stumbled upon, so if anyone knows of them please comment. In any event, I hope this proves useful to someone.