2013-09-15 4 views
8

Я пытаюсь обновить содержимое ярлыков каждую секунду. Поэтому я определяю два метода, как показано ниже. Я использую startStatusBarTimer() в моем конструкторе Window.Обновление содержимого ярлыков каждый раз WPF

кода:

private void startStatusBarTimer() 
{ 
    System.Timers.Timer statusTime = new System.Timers.Timer(); 

    statusTime.Interval = 1000; 

    statusTime.Elapsed += new System.Timers.ElapsedEventHandler(statusTimeElapsed); 

    statusTime.Enabled = true; 
} 

private void statusTimeElapsed(object sender, ElapsedEventArgs e) 
{ 
    lblNow.Content = DateTime.Now.ToString("yyyy/MM/dd");  
} 

Но я получаю эту ошибку:

Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет.

Что не так? Или что я могу сделать?

+0

http://www.c-sharpcorner.com/uploadfile/mahesh/timer-in-wpf/ – I4V

+0

Нить не может получить доступ к управлению. В основном потому, что «корневой» поток уже контролирует его, а 2 потока не могут управлять им вместе. Есть доступ к этим элементам управления, только «Управление потоками WPF» или «Управление потоками C#» – GroundZero

ответ

10

Вы столкнулись с проблемой thread affinity. Поскольку прошедшее событие вызывается на background thread, вы не можете получить доступ к элементам управления пользовательского интерфейса из фонового потока. Вы должны поместить свое действие на UI dispatcher так, что он получает депешу UI нить -

private void statusTimeElapsed(object sender, ElapsedEventArgs e) 
{ 
    App.Current.Dispatcher.Invoke((Action)delegate 
    { 
     lblNow.Content = DateTime.Now.ToString("yyyy/MM/dd"); 
    }); 
} 

ИЛИ

Вы можете использовать DispatcherTimer, который построен специально для этой цели. Вы можете получить доступ к элементам управления пользовательского интерфейса из своего обработчика событий Tick. См. Образец здесь: MSDN.

2

просто используйте следующий код для обновления любого элемента управления в приложении WPF. Вы должны пройти этот класс в том же пространстве имен.

public static class ExtensionMethods 
    { 
     private static Action EmptyDelegate = delegate() { }; 

     public static void Refresh(this UIElement uiElement) 
     { 
      uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate); 
     } 
    } 

после этого использование подобный нижеследующий.

lable1.Refresh(); 
+0

По какой-то причине это работает только для меня, когда я использую сборку релизов. Когда я в режиме отладки, uielements не обновляются. – brandonstrong

Смежные вопросы