'How to update xamarin essentials preferences within the same app session
I've created a settings page within xamarin that works just fine to update preferences when the app restarts. The purpose of this is to change the language of the app according to the bool value saved by the preference. It works great between app sessions (closing and restarting the app). However, I can't seem to get it to update within the SAME app session. Example, you tap the switch and everything changes to spanish instantly without the app needing to restart.
Settings.xaml
<ContentPage.BindingContext>
<vm:SettingsViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Accent">#74cee2</Color>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<views:Header/>
<Label Text="Change Lang"/>
<Switch x:Name="LangSwitch" OnColor="#bbbbbb" ThumbColor="#74cee2" IsToggled="{Binding ChangeLang}" Toggled="LangSwitch_Toggled"/>
</StackLayout>
Settings.xaml.cs (just to make sure i'm able to reach the switch toggled event)
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Settings : ContentPage
{
public Settings()
{
InitializeComponent();
}
async void LangSwitch_Toggled(object sender, ToggledEventArgs e)
{
await DisplayAlert("ok", "ok", "ok");
}
}
SettingsViewModel
public class SettingsViewModel : BaseViewModel
{
public SettingsViewModel()
{
Title = "Settings";
}
public bool ChangeLang
{
get => Preferences.Get("ChangeLang", false);
set
{
Preferences.Set("ChangeLang", value);
OnPropertyChanged("ChangeLang");
}
}
}
HomeViewModel (where the ChangeLang bool is used to determine data)
public class HomeViewModel : SettingsViewModel
{
public HomeViewModel()
{
if (ChangeLang == true)
{
Title = "NICU";
secondaryTitle = "Spanish";
}
else
{
Title = "NICU";
secondaryTitle = "English";
}
}
}
BaseViewModel (if you were wondering)
public class BaseViewModel : INotifyPropertyChanged
{
string title = string.Empty;
string secTitle = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
public string secondaryTitle
{
get { return secTitle; }
set { SetProperty(ref secTitle, value); }
}
string logo = "logo.png";
public string Logo
{
get { return logo; }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName] string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
UPDATE
Like Jason said in the comments just use messaging center.
public class HomeViewModel : SettingsViewModel
{
public HomeViewModel()
{
setLang();
MessagingCenter.Subscribe<BaseViewModel>(this, "lang", (sender) =>
{
setLang();
});
}
void setLang()
{
if (ChangeLang == true)
{
Title = Preferences.Get("ChangeLang", false).ToString();
secondaryTitle = "Spanish";
}
else
{
Title = Preferences.Get("ChangeLang", false).ToString();
secondaryTitle = "English";
}
}
}
I moved the ChangLang bool to my BaseViewModel but here's the updated one.
public bool ChangeLang
{
get => Preferences.Get("ChangeLang", false);
set
{
Preferences.Set("ChangeLang", value);
OnPropertyChanged("ChangeLang");
MessagingCenter.Send(this, "lang");
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
