Click here to Skip to main content
15,879,474 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I would like to check with a custom C# method alike "IsClipBoardEmpty" if my ClipBoard is really empty of anything. The method shall be in pure C# and not require any STA_THREAD or external API or whatever. I have tried different solutions which weren't working for me. I have a menu item "Clear Clipboard". This menu item I want to disable when the clipboard is empty. With empty I mean: it is clear and has no text, no images, no filedrops, no graphics or any other custom objects inside. I have seen different methods with requiring a "STA_THREAD", but I need a function not requiring a STA_THREAD.

Here my custom code attempts which weren't working:

C#
//1
DataObject retrievedData = (DataObject)Clipboard.GetDataObject();
if(retrievedData==null)
{
toolStripMenuItem1.enabled=false;
}

//2
object retrievedData = ClipBoard.GetText();
if(retrievedData==null)
{
toolStripMenuItem1.enabled=false;
}

//3
if((Clipboard.GetText().toString()!="")
{
toolStripMenuItem1.enabled=true;
}
else
{
toolStripMenuItem1.enabled=false;
}


What I have tried:

I posted the functions which I have tried. Nothing worked.

This also doesn't work. the function returns always false,
even if the Clipboard is already empty.

C#
public static bool IsClipboardEmpty() {
   return (Clipboard.GetDataObject() == null);
}


And what I need would be an extension method like "Clipboard.IsEmpty()".
I already tried to add all existing using statements and references for C# and increased the size of my application to 300 MB. Anyway the extension method stays with all the references to all compatible DLL's in the system still unknown. Any ideas which DLL could contain such function?
Posted
Updated 22-Mar-17 1:59am
v2

According to the documentation at Clipboard.GetDataObject Method (System.Windows)[^] it should be NULL when there are no data:
Quote:
A data object that enables access to the entire contents of the system Clipboard, or null if there is no data on the Clipboard.

If this is not NULL, you may check the available formats using DataObject.GetFormats Method (Boolean) (System.Windows)[^].

I have not tested it but the returned string array should be empty when there are no data on the clipboard.

If this does not work too (and there are data for the returned formats), it might be impossible without using a STA thread.
 
Share this answer
 
Comments
Jochen Arndt 1-Apr-16 11:45am    
Thank you for feedback and accepting the solution.

Good to know that this works because this is asked sometimes.
Instead of using the Clipboard.Getxxxx methods use the Clipboard.ContainsData method.

You need to pass this a parameter which is the textual description of the DataFormat you are looking for.
This function first enumerates all of the DataFormats and then checks the clipboard for data in that format.
C#
using System.Linq;
...
public static bool IsClipboardEmpty()
{
    var dataFormats = typeof(DataFormats).GetFields(BindingFlags.Public | BindingFlags.Static)
                       .Select(f => f.Name)
                       .ToList();
    var containsSomething = dataFormats.Aggregate(false, (current, x) => current || Clipboard.ContainsData(x));

    return (!containsSomething);
}

I tested this by using a simple timer
C#
private void timer1_Tick(object sender, EventArgs e)
{
    menuStrip1.Items[0].Enabled = !IsClipboardEmpty();
}
and by copying various items (pictures, text, files) and the menu toggled between enabled and disabled.

[EDIT - for completeness here is the same thing targeting .NET 2.0]
C#
using System.Collections.Generic;
using System.Reflection;
...
public static bool IsClipboardEmpty()
{
    var dataFormats = new List<string>();
    foreach (var x in typeof (DataFormats).GetFields(BindingFlags.Public | BindingFlags.Static))
        dataFormats.Add(x.Name);

    var containsSomething = false;
    foreach(var y in dataFormats)
        containsSomething = containsSomething || Clipboard.ContainsData(y);

    return (!containsSomething);
}


[EDIT] See Solution 5 below from Matt T Heffron for an efficiency improvement to this solution i.e. use .Any instead of .Aggregate in the Linq version and in the .NET2 version break out of the loop once something is found, e.g.
C#
foreach (var y in dataFormats)
{
    containsSomething = containsSomething || Clipboard.ContainsData(y);
    if (containsSomething) break;
}
 
Share this answer
 
v3
Comments
CHill60 1-Apr-16 12:14pm    
Just for completeness I've added a version to my solution which targets .Net 2.0 in case anyone else hits a similar problem.
All the best.
Slight improvement on Solution 3 by @CHill60
It looks like the .Aggregate(...) could be more efficient as .Any(...), like:
C#
using System.Linq;
...
public static bool IsClipboardEmpty()
{
    var dataFormats = typeof(DataFormats).GetFields(BindingFlags.Public | BindingFlags.Static)
                       .Select(f => f.Name);
    var containsSomething = dataFormats.Any(x => Clipboard.ContainsData(x));
 
    return (!containsSomething);
}

The .Any(...) will stop as soon as one is found. .Aggregate(...) will proceed through the whole collection of dataFormats.
The .NET 2.0 version could, likewise, early exit once the Clipboard.ContainsData(y) returns true.
 
Share this answer
 
Comments
CHill60 2-Apr-16 7:56am    
Nice one!
I shall now go and hang my head in shame :)
There is a GetDataObject method that you can use; if it returns a null value, then the clipboard is empty:
C#
public static bool IsClipboardEmpty() {
   return (Clipboard.GetDataObject() == null);
}
 
Share this answer
 
The only time the clipboard is ever truly empty is right after you login or something calls the equivalent of Clipboard.Clear(), which rarely ever happens.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900