Я являюсь новым в Silverlight, и я делаю некоторые тесты. С моим текущим тестом я пытаюсь отобразить в режиме реального времени текущее содержание Буфера обмена. Но существует странные поведения с этим кодом:
namespace SilverlightTest
{
public partial class MainPage : UserControl
{
private Timer _timer;
public MainPage()
{
InitializeComponent();
var dispatcher_timer = new DispatcherTimer {Interval = new TimeSpan(0, 0, 0, 5)};
dispatcher_timer.Tick += new EventHandler(timer_Callback);
dispatcher_timer.Start();
}
private void timer_Callback(object state, EventArgs eventArgs)
{
current_clip_board.Content = Clipboard.GetText();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
current_clip_board.Content = Clipboard.GetText();
}
}
}
Кнопка Event и Событие таймера, предполагают, чтобы сделать точно то же действие. Но это не делает! Кнопка хорошо работает и установила текст буфера обмена в маркировку, но таймер выдает исключение:
Доступ буфера обмена не предоставляется
Вопрос: почему?:)
Спасибо.
PS: Я держал бы пари на проблеме потока :p
Доступ к буферу обмена в частично доверенном (в браузере) приложении Silverlight (сценарий, который вы, вероятно, имеете в виду выше) ограничен. Свойство GetText доступно только в сценариях, которые, по определению среды выполнения Silverlight, были инициированы пользователем. Ваш пример идеален - например, нажатие кнопки. Однако таймер диспетчеризации не инициируется пользователем, поэтому свойство выбрасывает исключение (это особенно важно в контексте приложения в браузере, что могло бы стать большой дырой в безопасности, если бы вы могли создать приложение Silverlight, которое просто тихо запускается в браузере, наблюдая за обновлениями буфера обмена пользователя без его ведома).
Более подробную информацию см. в этой документации по буферу обмена.
Вы пробовали это:
private void timer_Callback(object state, EventArgs eventArgs)
{
Dispatcher.Invoke(new System.Threading.ThreadStart(delegate()
{
current_clip_board.Content = Clipboard.GetText();
}
}
редактировать
После быстрого поиска выясняется, что Буфер обмена
доступен только в ответе для действий пользователя см. здесь и здесь .
При частичном доверии (режим по умолчанию для приложений на основе Silverlight , размещенных в браузере) Silverlight также ограничивает доступ к буферу обмена двумя своими ключевыми API GetText и SetText. Эти API могут быть вызваны только из контекста , который определяется средой выполнения Silverlight как ответ на действие, инициированное пользователем. Для примера доступ к буферу обмена действителен из обработчика события Click или KeyDown. Напротив, доступ к буферу обмена недействителен из обработчика для загруженного или из конструктора, а попытки доступа вызывают исключения.
Если ваш единственный выход - использовать таймер, не делайте этого вообще. Буфер обмена является общим ресурсом, и вы будете вызывать ошибки «не удается открыть буфер обмена» в других программах, когда они пытаются получить доступ к буферу обмена. т.е. пользователь копирует что-то из WinWord, WinWord пытается открыть буфер обмена, но не может, потому что он заблокирован, пока вы его исследуете.