How to apply theme and color in wpf Metro window application
In this example i am using Prism,unity and MahApps make sure you are also using same otherwise you will not get PrismApplication,BindableBase and MetroWindow.
MainWindow.xaml
<metro:MetroWindow x:Class="WpfApplication.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication"
mc:Ignorable="d"
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="Welcome To Metro ui with Prism Unity">
<metro:MetroWindow.RightWindowCommands>
<metro:WindowCommands>
<ComboBox ItemsSource="{Binding LstTheme}" SelectedItem="{Binding SelectedTheme}" Width="100" Background="Transparent" BorderBrush="Transparent">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding DataContext.ApplyThemeCommand,RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="20" Height="20" Fill="{Binding Value}"/>
<TextBlock Text="{Binding Name}" Margin="5" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox ItemsSource="{Binding LstColor}" SelectedItem="{Binding SelectedColor}" Width="100" Background="Transparent" BorderBrush="Transparent">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding DataContext.ApplyColorCommand,RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="20" Height="20" Fill="{Binding Value}"/>
<TextBlock Text="{Binding Name}" Margin="5" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</metro:WindowCommands>
</metro:MetroWindow.RightWindowCommands>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<!--here i used DynamicResource for Foreground/Background because i want to dynamically change the color-->
<TextBlock Height="30" Width="200" Text="This is TextBlock" Margin="5" Foreground="{DynamicResource AccentBaseColorBrush}"/>
<Button Content="This is Button" HorizontalAlignment="Left" Width="200" Background="{DynamicResource AccentBaseColorBrush}"/>
</StackPanel>
</metro:MetroWindow>
MainWindow.xaml.cs
public partial class MainWindow : MetroWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
MainWindowViewModel.cs
public class MainWindowViewModel : BindableBase
{
public MainWindowViewModel()
{
ApplyThemeCommand = new DelegateCommand(ApplyTheme);
ApplyColorCommand = new DelegateCommand(ApplyColor);
_lstTheme = new ObservableCollection<NameValue>()
{
new NameValue() {Name = "Light", Value = "White"},
new NameValue() {Name = "Dark", Value = "Black"}
};
SelectedTheme = LstTheme[0];
_lstColor = new ObservableCollection<NameValue>()
{
new NameValue() {Name = "blue", Value = "#2196F3"},
new NameValue() {Name = "red", Value = "#e52400"},
new NameValue() {Name = "green", Value = "#60a917"},
new NameValue() {Name = "purple", Value = "#800080"},
new NameValue() {Name = "orange", Value = "#fa6800"}
};
SelectedColor = _lstColor[0];
}
private void ApplyColor()
{
ApplyThemeColor();
}
private void ApplyTheme()
{
ApplyThemeColor();
}
private void ApplyThemeColor()
{
try
{
var accent = SelectedColor.Name ?? LstColor[0].Name;
var theme = SelectedTheme.Name ?? LstTheme[0].Name;
Accent newAccent = ThemeManager.GetAccent(accent);
AppTheme newTheme = ThemeManager.GetAppTheme("Base" + theme);
ThemeManager.ChangeAppStyle(Application.Current, newAccent, newTheme);
}
catch (System.Exception ex)
{
}
}
private ObservableCollection<NameValue> _lstTheme;
public ObservableCollection<NameValue> LstTheme
{
get { return _lstTheme; }
set { SetProperty(ref _lstTheme, value); }
}
private ObservableCollection<NameValue> _lstColor;
public ObservableCollection<NameValue> LstColor
{
get { return _lstColor; }
set { SetProperty(ref _lstColor, value); }
}
private NameValue _selectedColor;
public NameValue SelectedColor
{
get { return _selectedColor; }
set { SetProperty(ref _selectedColor, value); }
}
private NameValue _selectedTheme;
public NameValue SelectedTheme
{
get { return _selectedTheme; }
set { SetProperty(ref _selectedTheme, value); }
}
public ICommand ApplyThemeCommand { get; set; }
public ICommand ApplyColorCommand { get; set; }
}
NameValue.cs
public class NameValue : BindableBase
{
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
private string _value;
public string Value
{
get { return _value; }
set { SetProperty(ref _value, value); }
}
}
App.xaml
<prism:PrismApplication x:Class="WpfApplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml"/>
<!-- Accent and AppTheme setting -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</prism:PrismApplication>
App.xaml.cs
public partial class App : PrismApplication
{
IUnityContainer _container;
protected override Window CreateShell()
{
return _container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
_container = containerRegistry.GetContainer();
}
}
MainWindow.xaml
<metro:MetroWindow x:Class="WpfApplication.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication"
mc:Ignorable="d"
xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="Welcome To Metro ui with Prism Unity">
<metro:MetroWindow.RightWindowCommands>
<metro:WindowCommands>
<ComboBox ItemsSource="{Binding LstTheme}" SelectedItem="{Binding SelectedTheme}" Width="100" Background="Transparent" BorderBrush="Transparent">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding DataContext.ApplyThemeCommand,RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="20" Height="20" Fill="{Binding Value}"/>
<TextBlock Text="{Binding Name}" Margin="5" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox ItemsSource="{Binding LstColor}" SelectedItem="{Binding SelectedColor}" Width="100" Background="Transparent" BorderBrush="Transparent">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding DataContext.ApplyColorCommand,RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="20" Height="20" Fill="{Binding Value}"/>
<TextBlock Text="{Binding Name}" Margin="5" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</metro:WindowCommands>
</metro:MetroWindow.RightWindowCommands>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<!--here i used DynamicResource for Foreground/Background because i want to dynamically change the color-->
<TextBlock Height="30" Width="200" Text="This is TextBlock" Margin="5" Foreground="{DynamicResource AccentBaseColorBrush}"/>
<Button Content="This is Button" HorizontalAlignment="Left" Width="200" Background="{DynamicResource AccentBaseColorBrush}"/>
</StackPanel>
</metro:MetroWindow>
MainWindow.xaml.cs
public partial class MainWindow : MetroWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
MainWindowViewModel.cs
public class MainWindowViewModel : BindableBase
{
public MainWindowViewModel()
{
ApplyThemeCommand = new DelegateCommand(ApplyTheme);
ApplyColorCommand = new DelegateCommand(ApplyColor);
_lstTheme = new ObservableCollection<NameValue>()
{
new NameValue() {Name = "Light", Value = "White"},
new NameValue() {Name = "Dark", Value = "Black"}
};
SelectedTheme = LstTheme[0];
_lstColor = new ObservableCollection<NameValue>()
{
new NameValue() {Name = "blue", Value = "#2196F3"},
new NameValue() {Name = "red", Value = "#e52400"},
new NameValue() {Name = "green", Value = "#60a917"},
new NameValue() {Name = "purple", Value = "#800080"},
new NameValue() {Name = "orange", Value = "#fa6800"}
};
SelectedColor = _lstColor[0];
}
private void ApplyColor()
{
ApplyThemeColor();
}
private void ApplyTheme()
{
ApplyThemeColor();
}
private void ApplyThemeColor()
{
try
{
var accent = SelectedColor.Name ?? LstColor[0].Name;
var theme = SelectedTheme.Name ?? LstTheme[0].Name;
Accent newAccent = ThemeManager.GetAccent(accent);
AppTheme newTheme = ThemeManager.GetAppTheme("Base" + theme);
ThemeManager.ChangeAppStyle(Application.Current, newAccent, newTheme);
}
catch (System.Exception ex)
{
}
}
private ObservableCollection<NameValue> _lstTheme;
public ObservableCollection<NameValue> LstTheme
{
get { return _lstTheme; }
set { SetProperty(ref _lstTheme, value); }
}
private ObservableCollection<NameValue> _lstColor;
public ObservableCollection<NameValue> LstColor
{
get { return _lstColor; }
set { SetProperty(ref _lstColor, value); }
}
private NameValue _selectedColor;
public NameValue SelectedColor
{
get { return _selectedColor; }
set { SetProperty(ref _selectedColor, value); }
}
private NameValue _selectedTheme;
public NameValue SelectedTheme
{
get { return _selectedTheme; }
set { SetProperty(ref _selectedTheme, value); }
}
public ICommand ApplyThemeCommand { get; set; }
public ICommand ApplyColorCommand { get; set; }
}
NameValue.cs
public class NameValue : BindableBase
{
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
private string _value;
public string Value
{
get { return _value; }
set { SetProperty(ref _value, value); }
}
}
App.xaml
<prism:PrismApplication x:Class="WpfApplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml"/>
<!-- Accent and AppTheme setting -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</prism:PrismApplication>
App.xaml.cs
public partial class App : PrismApplication
{
IUnityContainer _container;
protected override Window CreateShell()
{
return _container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
_container = containerRegistry.GetContainer();
}
}
Comments
Post a Comment