0

I'm trying to update my UWP App's UI from a non-UI thread. I'm using Dispatcher.RunAsync to make the changes. I have tried changing:

  • ToggleSwitch.OnContent and OffContent
  • Image.Source
  • Checkbox.IsChecked
  • Checkbox.Content

Nothing changes.

Currently, I'm reading values from the local settings cache (ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings), but I have tried using bools. No difference.

When debugging, Visual Studio indicates that the properties like Checkbox.IsChecked, etc. do change. However, in the app itself, no changes occur visually.

My current XAML code for the Checkboxes:

<CheckBox x:Name="checkBox1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="200,93,0,0"/>
<CheckBox x:Name="checkBox2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="200,125,0,0"/>
<CheckBox x:Name="checkBox3" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="200,157,0,0"/>

The cs code:

public async void updateUI()
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            // change checkBox1 UI State
            checkBox1.IsChecked = (Convert.ToBoolean(localSettings.Values["test1"])) ? true : false;
            checkBox1.Content = (checkBox1.IsChecked.Value) ? "On" : "Off";

            // change checkBox2 UI State
            checkBox2.IsChecked = (Convert.ToBoolean(localSettings.Values["test2"])) ? true : false;
            checkBox2.Content = (checkBox2.IsChecked.Value) ? "On" : "Off";

            // change checkBox3 UI State
            checkBox3.IsChecked = (Convert.ToBoolean(localSettings.Values["test3"])) ? true : false;
            checkBox3.Content = (checkBox3.IsChecked.Value) ? "On" : "Off";
        });
}

I call updateUI by simply invoking it, like this: updateUI(). And, no, there is no exception or error. Just nothing happens visually.

Any ideas on what I'm doing wrong??

Edit

I am unable to use Dispatcher.BeginInvoke as it is absent in a UWP Environment.

Edit 2

What I've noticed is that: if I put the same code (without the Dispatcher.RunAsync) in a UI event like a button click event, it runs perfectly. Can't one, somehow replicate this programmatically?

I have tried simply invoking an eventhandler method (like btnClickMe_Click) both with and without the Dispatcher.RunAsync code. However, that also does not cause any visual change whatsoever.

  • Can you tell from where you are calling updateUI()? – Dishant Apr 11 '18 at 09:07
  • I am calling it from such a method: `public async void Connection_OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)` which is triggered when my WinForm Component sends data to the UWP App through the `AppServices` API – user9618595 Apr 11 '18 at 09:14
  • 2
    As a note, an expression like `IsChecked = someBool ? true : false` could be simplified to just `IsChecked = someBool`. – Clemens Apr 11 '18 at 09:26
  • Note taken, thank you @Clemens – user9618595 Apr 11 '18 at 09:29
  • Your question's title sounds odd. *RunAsync not working*, seriously? When you put a breakpoint somewhere in the Dispatcher Action, does it get hit? – Clemens Apr 11 '18 at 09:31
  • Yes, the action gets hit, but the visuals do not change. Only the 'virtual' properties change (according to Visual Studio) – user9618595 Apr 11 '18 at 09:38
  • Anyone have ideas? – user9618595 Apr 11 '18 at 10:42
  • 1
    [Which dispatcher](https://stackoverflow.com/q/16477190/60761) are you using? – H H Apr 11 '18 at 11:10
  • And `async void` is always murky. Make it an `async Task` and do `updateUI().Wait()` in the caller - more chance to see exceptions. – H H Apr 11 '18 at 11:11
  • So the `Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync` with `updateUI() .Wait()` and `async Task` respectively, throws an exception which VS "is unconfigured to catch". `Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync` with `await updateUI()` does not throw an exception, however, it doesn't work either. `Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher` with `await updateUI()` throws a `System.Runtime.InteropServices.COMException: 'Element not found.'` exception. Testing 3rd now. – user9618595 Apr 11 '18 at 12:09
  • `Window.Current.Dispatcher` with `await updateUI()` throws a `NullReferenceException` – user9618595 Apr 11 '18 at 12:19
  • Not much chance of help this way. Start writing a [mcve], a new project with just 1 checkbox. Add only the essentials. – H H Apr 11 '18 at 17:10
  • Hi, thx for offering, however, I've figured it out. I had to run the code in a loop on a `BackgroundWorker` thread, because the `updateUI()` method was secretly throwing an exception as a result of it being called too quickly before the method could complete. – user9618595 Apr 13 '18 at 15:38
  • Hi @HenkHolterman, I know its a month later; however, I found that my solution isn't efficient. If you're still interested in helping me, it'll be greatly appreciated. I've uploaded a sample here: https://github.com/dilvermaak/UINotUpdatingFromDispatcher – user9618595 May 14 '18 at 16:46
  • @user9618595 is the GitHub repo updated for reproducing this issue? I can look sometime this week if you still have the issue. – saurabh Jun 13 '18 at 09:51
  • 1
    Hi @saurabh, I finally solved the problem by subscribing to the `ApplicationData.Current.DataChanged` event and calling updateUI() from there. The DataChanged event gets invoked when I call the `ApplicationData.Current.SignalDataChange()` method. Thanks though. – user9618595 Jul 02 '18 at 09:18

0 Answers0