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.
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
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]
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.
foreach (var y in dataFormats)
{
containsSomething = containsSomething || Clipboard.ContainsData(y);
if (containsSomething) break;
}