UWP обновляет текущее окно из фона - PullRequest
0 голосов
/ 08 апреля 2020

Я портирую приложение из WinRT в UWP. (Я уже перенес его на iOS и Android)

Мое приложение имеет несколько страниц. Мне нужно иметь возможность определить, какая страница просматривается в данный момент, а затем обновить содержимое. (По разным причинам DataBinding не является опцией.)

У меня есть подпрограмма, которая запускается в фоновом режиме (не в потоке пользовательского интерфейса), вызывается из таймера отправки.

В WinRT Я обработал это следующим образом:

            // If current window is MainPage, then update the displayed fields 
        var _Frame = Window.Current.Content as Frame;
        Page _Page = _Frame.Content as Page;
        if (_Page is MainPage)
        {
            MainPage _XPage = _Frame.Content as MainPage;
            _XPage.SetFieldsTick(spoton);
        }

Поскольку UWP возвращает значение NULL для Windows .Current.Content, я установил флаги в процедуре навигации, чтобы отслеживать текущий вид. Я бы хотел исправить этот kludge правильно.

Следующий шаг - как на самом деле изменить поля.

У меня есть подпрограмма в коде XAML, которая устанавливает поля

        public void SetFieldsTick(bool spot)
    {
        UTC_Data.Text = Vars.DateStrZ;
    }

Если я хочу сослаться на это из своей фоновой подпрограммы, тогда подпрограмма должна быть stati c. Если я внесу это изменение, то подпрограмма не сможет ссылаться на поля на странице, так как они не уста- новлены c.

Я знаю, что это, вероятно, что-то очевидное, но я в замешательстве.

Заранее спасибо.

1 Ответ

0 голосов
/ 10 апреля 2020

Используемый вами Таймер обеспечит механизм для выполнения метода в потоке пула потоков через заданные интервалы. Это работает в отдельном потоке. Поэтому, если вы хотите обработать пользовательский интерфейс приложения, оно должно выполняться в потоке диспетчера пользовательского интерфейса. В этом случае вы можете использовать метод Dispatcher.RunAsyn c для обратного вызова в потоке пользовательского интерфейса. Например:

App.xaml.cs:

public void StartTimer() 
{ 
    DateTime startTime; 
    startTime = DateTime.UtcNow; 
    var dispatcherTimer = new System.Threading.Timer(DispatcherTimer_Tick, startTime, 0, 1000); 
}

private async void DispatcherTimer_Tick(object state)
{
    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        var _Frame = Window.Current.Content as Frame;
        Page _Page = _Frame.Content as Page;
        if (_Page is MainPage)
        {
            MainPage _XPage = _Frame.Content as MainPage;
            _XPage.SetFieldsTick(true);
        }
    });
}

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

public void StartTimer() 
{ 
    var dispatcherTimer = new DispatcherTimer();
    dispatcherTimer.Tick += dispatcherTimer_Tick;
    dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
    dispatcherTimer.Start();
}

private void dispatcherTimer_Tick(object sender, object e)
{
    var _Frame = Window.Current.Content as Frame;
    Page _Page = _Frame.Content as Page;
    if (_Page is MainPage)
    {
        MainPage _XPage = _Frame.Content as MainPage;
        _XPage.SetFieldsTick(true);
    }
}
...