So, back in this question this question, I built a set of settings. Now, I am trying to clean the entire system up.
So, back in this question, I built a set of settings. Now, I am trying to clean the entire system up.
So, back in this question, I built a set of settings. Now, I am trying to clean the entire system up.
My other two settings can be viewed on PasteBin in the provided link.
My other two settings can be viewed on PasteBin in the provided link.
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.