2

I am loving Template10 so far, very nice. I am a little stuck though on how to bind to a Setting value on the Main Page. I have added a new bool setting which is storing properly. On my main page I have a Visibility binding to the setting:

Visibility="{Binding UseAmbientLightSensor, Converter={StaticResource CollapsedWhenFalseConverter}}"

This works on app start as expected, the MainPageViewModel reads the value from Settings and a grid is visible or collapsed based on that setting.

However I cannot seem to get this binding to 'listen' to the setting, if I go to the settings page and change that value, when I go back to the Main Page the visibility does not change. It only works if I restart the app.

In the vanilla Template10 install this would be akin to Binding a little logo on MainPage to the 'UseLightThemeButton' setting in the Settings page which changes based on that setting..

Jerry Nixon
  • 31,313
  • 14
  • 117
  • 233
BGTurner
  • 307
  • 3
  • 9

2 Answers2

2

Okay, so I guess this is the "official" answer. But many approaches are valid. This one matches most closely to the templates. I would do it like this:

public class MainPageViewModel : ViewModelBase
{
    Services.SettingService.SettingService _SettingService;

    public MainPageViewModel()
    {
        _SettingService = Services.SettingService.SettingService.Instance;
    }

    public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> state)
    {
        Windows.Storage.ApplicationData.Current.DataChanged += SettingsChanged;
        await Task.CompletedTask;
    }

    public override async Task OnNavigatedFromAsync(IDictionary<string, object> pageState, bool suspending)
    {
        Windows.Storage.ApplicationData.Current.DataChanged -= SettingsChanged;
        await Task.CompletedTask;
    }

    private void SettingsChanged(Windows.Storage.ApplicationData sender, object args)
    {
        RaisePropertyChanged(nameof(FontSize));
    }

    public double FontSize { get { return _SettingService.FontSize; } }
}

With that view-model, you can easily bind to a setting (in this case FontSize).

Best of luck.

Jerry Nixon
  • 31,313
  • 14
  • 117
  • 233
  • Excellent, this answers a question that I was going to have before I even got to it. Loving template10 more every day. Thanks Jerry! – dub stylee Feb 29 '16 at 23:51
  • As an aside this also works if you choose to Roam your settings and they are changed, then, on another device elsewhere. – Jerry Nixon Mar 04 '16 at 17:11
0

There are two possible scenarios that may not be happening:

  • Raise the property change event when your bool value gets updated.
  • Set the binding to a two way mode.

In order to do this change the binding mode of your Visibility property

Visibility="{Binding UseAmbientLightSensor, Mode=TwoWay, Converter={StaticResource CollapsedWhenFalseConverter}}"

This will tell to listen to any change on the property in the view model.

Then you need to tell the View model when to let the XAML view know of its changes, if you are using Template10, then it can be done as follows:

private bool useAmbientLightSensor;

public TodoListControlViewModel UseAmbientLightSensor
{
    get
    {
        return this.useAmbientLightSensor;
    }

    set
    {
        this.Set(ref this.useAmbientLightSensor, value);
    }
}

The view model needs to extend from the ViewModelBase class which provides the Set method that raises the OnPropertyChanged event, allowing the view to know of any change in the view model.

For more info, check the INotifyPropertyChanged interface and its implementation.

Nahuel Ianni
  • 3,177
  • 4
  • 23
  • 30
  • That's the way I would normally do it but Template10 seems a little different and I am trying to keep my code in line with the defaults so the Settings are updated in the Settings Service. The SettingsViewModel saves changes through the SettingsService Instance and raises a PropertyChanged event. However the property on the MainPageViewModel does not respond to those events. I have got around it for now by using UseAmbientLightSensor = _settings.UseAmbientLightSensor; inside of my OnNavigatedToAsync handler which reloads the settings when coming back from the settings page. – BGTurner Feb 29 '16 at 10:14
  • It will never respond to the changes without the property and correct binding. Do you have those two in place? Also, are you using a compiled binding? – Nahuel Ianni Feb 29 '16 at 10:19