Visual Studio Dark Theme with light designer background color

I found this extremely useful at times because I like to use a Dark theme in Visual Studio. Making the following change in App.xaml means I can see all of my controls properly in the designer while I’m developing my app.

<Style TargetType="{x:Type UserControl}">
    <Style.Triggers>
        <Trigger Property="ComponentModel:DesignerProperties.IsInDesignMode" Value="true">
            <Setter Property="Background" Value="White" />
        </Trigger>
    </Style.Triggers>
</Style>

WPF Switch Color Theme at Runtime

This very simple class will allow you to switch Themes in a WPF application. Its not the only way to do it and is not a MVVM implementation, but can be modified easily if needed.

Here is the resource (theme) switching code:

public static class ThemeHelper
{
	public static void SwitchTheme(string stylefile)
	{
		if (File.Exists(stylefile))
		{
			using (FileStream fs = new FileStream(stylefile, FileMode.Open))
			{
				ResourceDictionary dic = (ResourceDictionary) XamlReader.Load(fs);
				Application.Current.Resources.MergedDictionaries.Clear();
				Application.Current.Resources.MergedDictionaries.Add(dic);
			}
		}   
	}

	public static void SwitchTheme(Uri themeUri)
	{
		var theme = new ResourceDictionary();
		theme.Source = themeUri;
		Application.Current.Resources.MergedDictionaries.Clear();            
		Application.Current.Resources.MergedDictionaries.Add(theme);
	}
}

For this to work just create a folder called “Themes” add your Theme files into there and mark as content. Each theme file must be in the same structure (i.e. use the same Key names obviously) for this to work.

Here is an example of a theme file:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="ThemeColor1">Green</SolidColorBrush>
    <SolidColorBrush x:Key="ThemeColor2">Red</SolidColorBrush>
    <SolidColorBrush x:Key="ThemeColor3">Orange</SolidColorBrush>
</ResourceDictionary>

Then anywhere in code you can changes themes like so (assuming you added a file called MangoTheme.xaml into the \Themes\ directory:

ThemeHelper.SwitchTheme(new Uri("/Themes/MangoTheme.xaml", UriKind.Relative));

Make sure you use DynamicResource markup extension in your bindings for anything that could change during runtime, i.e.

Background="{DynamicResource ThemeColor1}"

Generic Storage Manager

All of my apps make use of a common class for data storage management. Its simple and works for my needs, even providing a way to create a default context if one does not already exist.

Obviously any type you want to use with this must be decorated with the DataContractAttribute.

class StorageManager<T> where T : class 
{
	private readonly string _filename;
	private readonly Func<T> _defCtxFunc;
	
	public StorageManager(string filename, Func<T> defaultContextCreation)
	{
		_filename = filename;
		_defCtxFunc = defaultContextCreation;
	}
	
	public async Task<T> Load(Func<T> defaultContextCreation)
	{
		object existingData = null;

		try
		{
			var serializer = new DataContractSerializer(typeof (T));
			using (
				var stream =
					await
						ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(_filename))

			{
				existingData = serializer.ReadObject(stream);
				stream.Flush();
			}
		}
		catch (Exception e)
		{
			Debug.WriteLine("StorageManager.Load({1}) failed with exception :: {0}", _filename, e);
		}

		return (existingData ?? defaultContextCreation.Invoke()) as T;
	}

	public async Task<bool> Save(T data)
	{
		try
		{
			var serializer = new DataContractSerializer(typeof (T));
			using (
				var stream =
					await
						ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(_filename,
							CreationCollisionOption.ReplaceExisting))
			{
				serializer.WriteObject(stream, data);
				stream.Flush();                    
			}

			Debug.WriteLine("Save [{0}] to [{1}] success", _filename, ApplicationData.Current.LocalFolder.Path);
			return true;
		}
		catch(Exception e)
		{
			Debug.WriteLine("Save [{0}] failed with exception :: {1}", _filename, e);
			return false;
		}
	}
}