Search code examples
c#multithreadinguwpuwp-xamltoggleswitch

ToggleSwitch.On & OffContent Not Updating


I'm trying to update three ToggleSwitches' OnContent as well as OffContent based on values retrieved from the UWP's Local Settings Cache (not the ToggleSwitch.IsOn property). Please note that I'm doing this on an external thread.

Here is my current code:

ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
public async void updateUI()
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        // set Test1 state in UI
        toggleSwitchTest1.OnContent = (Convert.ToBoolean(localSettings.Values["Test1"])) ? "It is: On" : "It is: Off";
        toggleSwitchTest1.OffContent = toggleSwitchTest1.OnContent;

        // set Test2 state in UI
        toggleSwitchTest2.OnContent = (Convert.ToBoolean(localSettings.Values["Test2"])) ? "It is: On" : "It is: Off";
        toggleSwitchTest2.OffContent = toggleSwitchTest2.OnContent;

        // set Test3 state in UI
        toggleSwitchTest3.OnContent = (Convert.ToBoolean(localSettings.Values["Test3"])) ? "It is: On" : "It is: Off";
        toggleSwitchTest3.OffContent = toggleSwitchTest3.OnContent;
     });
}

I have also tried doing this with normal Boolean values as parameters being passed into the method. Or Boolean values just being declared at the beginning of the class before the public constructor and just setting it. This did not work either.

Please let me know if any other code is needed.

What am I doing wrong?

Edit

I call the updateUI method somewhere by simply invoking it like this: updateUI()

Edit 2

The ToggleSwitches' XAML constructor code:

<ToggleSwitch x:Name="toggleSwitchTest1" OffContent="It is" OnContent="It is" HorizontalAlignment="Left" Margin="19,84,0,0" VerticalAlignment="Top" IsOn="False"/>
<ToggleSwitch x:Name="toggleSwitchTest2" OffContent="It is" OnContent="It is" HorizontalAlignment="Left" Margin="19,116,0,0" VerticalAlignment="Top" IsOn="False"/>
<ToggleSwitch x:Name="toggleSwitchTest3" OffContent="It is" OnContent="It is" HorizontalAlignment="Left" Margin="19,148,0,0" VerticalAlignment="Top" IsOn="False"/>

Solution

  • It will get null value, if you have never apply value to localSettings.Values["xxx"]. And if value is null, the Convert.ToBoolean method returns false. All the toggleSwitchTest OnConten will be set It is: Off.

    And I found you use toggleSwitchTest1.OffContent = toggleSwitchTest1.OnContent; It will cause OffContent and OnContento become the same value.

    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        var value = localSettings.Values["Test1"];
        // set Test1 state in UI
        toggleSwitchTest1.OnContent = (Convert.ToBoolean(localSettings.Values["Test1"])) ? "It is: On" : "It is: Off";
        // toggleSwitchTest1.IsOn = Convert.ToBoolean(localSettings.Values["Test1"]);
        toggleSwitchTest1.OffContent = !(Convert.ToBoolean(localSettings.Values["Test1"])) ? "It is: On" : "It is: Off";
    
        // set Test2 state in UI
        toggleSwitchTest2.OnContent = (Convert.ToBoolean(localSettings.Values["Test2"])) ? "It is: On" : "It is: Off";
        //  toggleSwitchTest2.IsOn= Convert.ToBoolean(localSettings.Values["Test2"]);
        toggleSwitchTest2.OffContent = !(Convert.ToBoolean(localSettings.Values["Test2"])) ? "It is: On" : "It is: Off";
    
        // set Test3 state in UI
        toggleSwitchTest3.OnContent = (Convert.ToBoolean(localSettings.Values["Test3"])) ? "It is: On" : "It is: Off";
        //   toggleSwitchTest3.IsOn= Convert.ToBoolean(localSettings.Values["Test3"]);
        toggleSwitchTest3.OffContent = !(Convert.ToBoolean(localSettings.Values["Test3"])) ? "It is: On" : "It is: Off";
    });
    

    Although you could change off and on content with the above code, it will lead to logic confusion. I suggest you set off and on content in the xaml previous and bind IsOn property with localsetting value.

    toggleSwitchTest1.IsOn = Convert.ToBoolean(localSettings.Values["Test1"]);
    

    Edit 1

    As a result of the AppServiceConnection methods not having access to the UI, trying to change the UI from a method like this (even when using the Dispatcher) would not have an effect.

    Rather call it from a method or event like ApplicationData.Current.DataChanged which you can invoke through ApplicationData.Current.SignalDataChange().