Settings, setting settings, and settings handlers
So, back in this question, I built a set of settings. Now, I am trying to clean the entire system up.
This is the abstract
base class:
public class SettingChangedEventArgs : EventArgs
{
public int NewSetting { get; private set; }
public SettingChangedEventArgs(int newSetting)
{
NewSetting = newSetting;
}
}
public abstract class ApplicationSettingsProvider
{
public abstract int GetCurrentSetting();
public abstract void SetCurrentSetting(int setting);
public event EventHandler<SettingChangedEventArgs> SettingChanged;
public void OnSettingChanged(int newSetting)
{
var handler = SettingChanged;
if (handler != null)
{
handler(this, new SettingChangedEventArgs(newSetting));
}
}
}
Here is a setting built on it:
public class ApplicationThemeProvider : ApplicationSettingsProvider
{
public ApplicationThemeProvider()
{
ApplicationData.Current.DataChanged += (a, o) =>
{
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
OnSettingChanged((int)ApplicationData.Current.RoamingSettings.Values["Theme"]);
});
};
}
public override int GetCurrentSetting()
{
if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("Theme"))
{
int value = (int)ApplicationData.Current.RoamingSettings.Values["Theme"];
return (value >= 0 && value <= 2) ? value : 0;
}
return 0;
}
public override void SetCurrentSetting(int theme)
{
ApplicationData.Current.RoamingSettings.Values["Theme"] = theme;
ApplicationData.Current.SignalDataChanged();
}
}
I create an instance of the setting like this:
private static ApplicationSettingsProvider _ThemeProvider = new ApplicationThemeProvider();
private static HomePageVM Data = new HomePageVM(_ThemeProvider);
private static Settings settings = new Settings(_ThemeProvider);
public MainPage()
{
this.InitializeComponent();
SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;
this.DataContext = Data;
_ThemeProvider.SettingChanged += (s, e) => { Data.Theme = e.NewSetting; };
}
In the settings
SettingsPane
:
<StackPanel>
<TextBlock FontSize="15" Margin="0,5">Text and background color:</TextBlock>
<ComboBox Name="Theme" SelectionChanged="ThemeChanged">
<ComboBoxItem Content="Black on White/Purple" Foreground="Black" Background="White"/>
<ComboBoxItem Content="White on Black/White" Foreground="White" Background="Black"/>
<ComboBoxItem Content="Black on White/Gold" Foreground="Black" Background="White"/>
</ComboBox>
</StackPanel>
Which is handled like this:
private ApplicationSettingsProvider _ThemeProvider;
public Settings(ApplicationSettingsProvider themeProvider)
{
this.InitializeComponent();
_ThemeProvider = themeProvider;
InitSettings();
}
private void InitSettings()
{
Theme.SelectedIndex = _ThemeProvider.GetCurrentSetting();
}
private void ThemeChanged(object sender, SelectionChangedEventArgs e)
{
_ThemeProvider.SetCurrentSetting(Theme.SelectedIndex);
}
In my VM for the Page
:
private ApplicationSettingsProvider _ThemeProvider;
private int _theme = 0;
public int Theme
{
get { return _theme; }
set
{
if (_theme != value)
{
_theme = value;
OnPropertyChanged();
}
}
}
public HomePageVM(ApplicationSettingsProvider themeProvider)
{
_ThemeProvider = themeProvider;
Theme = _ThemeProvider.GetCurrentSetting();
}
This is how I am using it in HomePage.xaml
:
<ListBox Name="Items" Grid.Column="0" Grid.RowSpan="2" ItemsSource="{Binding ItemList}" DisplayMemberPath="Title" SelectionChanged="OnSelectionChanged"
Tapped="Items_Tapped" Margin="-2,-2,0,-2" KeyDown="ItemsKeyDown" Style="{Binding Theme, Converter={StaticResource LBStylePick}}"
ItemContainerStyle="{Binding Theme, Converter={StaticResource LBIStylePick}}" Padding="0,10" SelectedItem="{Binding CurrentItem, Mode=TwoWay}" />
I create my Converter
s like this:
<local:ThemeToLBStyleConverter x:Key="LBStylePick" />
<local:ThemeToLBIStyleConverter x:Key="LBIStylePick" />
And the C#:
public class ThemeToLBStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if ((int)value == 2) { return Application.Current.Resources["LBGold"]; }
else if ((int)value == 1) { return Application.Current.Resources["LBDark"]; }
else { return Application.Current.Resources["LBLight"]; }
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return new NotImplementedException();
}
}
public class ThemeToLBIStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if ((int)value == 2) { return Application.Current.Resources["LBIGold"]; }
else if ((int)value == 1) { return Application.Current.Resources["LBIDark"]; }
else { return Application.Current.Resources["LBILight"]; }
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return new NotImplementedException();
}
}
This looks rather complicated, although it is working perfectly. In addition, I don't like how I am handling all the theme values with a plain int
, an enum
looks to be in order. I am working on changing the int
s to enum
s, but before I adjust every single thing that uses it, I would like to know if I should change this process in any way so all my work doesn't go to waste.
My other two settings can be viewed on PasteBin in the provided link.