Last active
May 17, 2021 15:25
-
-
Save Mywk/eeea638ef2c56c437fe3642be2a5497c to your computer and use it in GitHub Desktop.
AcrylicWindow - Extension of MetroWindow with BlurBehind and compatibility with both MahApps and MaterialDesignInXamlToolkit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Extended MetroWindow with BlurBehind and compatibility with both MahApps and MaterialDesignInXamlToolkit | |
/// </summary> | |
public class AcrylicWindow : MetroWindow | |
{ | |
internal enum AccentState | |
{ | |
ACCENT_DISABLED = 1, // Disabled | |
ACCENT_ENABLE_GRADIENT = 0, // No idea, it's gray no matter what | |
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, // Painted with accent colour | |
ACCENT_ENABLE_BLURBEHIND = 3, // Blurbehind effect | |
ACCENT_INVALID_STATE = 4 // Invalid state | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
internal struct AccentPolicy | |
{ | |
public AccentState AccentState; | |
public int AccentFlags; | |
public int GradientColor; | |
public int AnimationId; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
internal struct WindowCompositionAttributeData | |
{ | |
public WindowCompositionAttribute Attribute; // Query attributes | |
public IntPtr Data; // Data buffer | |
public int SizeOfData; // Data size | |
} | |
internal enum WindowCompositionAttribute // Same as NtUserGetWindowCompositionAttribute? | |
{ | |
WCA_ACCENT_POLICY = 19 | |
} | |
public AcrylicWindow() : base() { | |
// Transparency is required for this to work | |
this.AllowsTransparency = true; | |
} | |
/// <summary> | |
/// Sets various DWM window attributes | |
/// </summary> | |
/// <param name="hwnd">The window to modify</param> | |
/// <param name="data">Pointer to the structure with the attribute data</param> | |
/// <returns> Nonzero on success, zero otherwise. You can call GetLastError on failure.</returns> | |
[DllImport("user32.dll")] | |
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data); | |
private bool isDarkTheme = false; | |
/// <summary> | |
/// This property can be used to find out if the current window is using the dark theme | |
/// </summary> | |
public bool IsDarkTheme | |
{ | |
get { return isDarkTheme; } | |
private set { isDarkTheme = value; } | |
} | |
/// <summary> | |
/// Copy the current MahApps theme to MaterialDesignTheme | |
/// </summary> | |
public void FixMaterialDesignTheme() | |
{ | |
// Detect the current theme | |
ControlzEx.Theming.Theme currentTheme = ThemeManager.Current.DetectTheme(Application.Current); | |
IsDarkTheme = currentTheme.BaseColorScheme.ToUpperInvariant() == "DARK"; | |
// Compatibility for MaterialDesignTheme | |
var paletteHelper = new PaletteHelper(); | |
ITheme theme = paletteHelper.GetTheme(); | |
IBaseTheme baseTheme = IsDarkTheme ? new MaterialDesignDarkTheme() : (IBaseTheme)new MaterialDesignLightTheme(); | |
theme.SetBaseTheme(baseTheme); | |
theme.SetPrimaryColor(currentTheme.PrimaryAccentColor); | |
theme.SetSecondaryColor(currentTheme.PrimaryAccentColor); | |
paletteHelper.SetTheme(theme); | |
// Set correct ThemeBackground and background transparency | |
this.SetResourceReference(BackgroundProperty, "MahApps.Brushes.ThemeBackground"); | |
var color = this.Background.Clone(); | |
color.Opacity = 0.90; | |
this.Background = color; | |
} | |
/// <summary> | |
/// Invoked whenever application code or internal processes (such as a rebuilding layout pass) call ApplyTemplate. | |
/// </summary> | |
public override void OnApplyTemplate() | |
{ | |
base.OnApplyTemplate(); | |
EnableBlurBehind(); | |
// Set theme for whole window | |
ThemeManager.Current.ThemeSyncMode = ThemeSyncMode.SyncAll; | |
ThemeManager.Current.SyncTheme(); | |
ThemeManager.Current.ThemeChanged += Current_ThemeChanged; | |
FixMaterialDesignTheme(); | |
} | |
/// <summary> | |
/// Called when the windows theme changes | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
private void Current_ThemeChanged(object sender, ControlzEx.Theming.ThemeChangedEventArgs e) | |
{ | |
FixMaterialDesignTheme(); | |
} | |
/// <summary> | |
/// Enables BlurBehind for our fancy window | |
/// </summary> | |
internal void EnableBlurBehind() | |
{ | |
var windowHelper = new WindowInteropHelper(this); | |
var accent = new AccentPolicy(); | |
var accentStructSize = Marshal.SizeOf(accent); | |
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; | |
accent.AccentFlags = 2; | |
accent.GradientColor = 0x00FFFFFF; | |
var accentPtr = Marshal.AllocHGlobal(accentStructSize); | |
Marshal.StructureToPtr(accent, accentPtr, false); | |
var data = new WindowCompositionAttributeData(); | |
data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; | |
data.SizeOfData = accentStructSize; | |
data.Data = accentPtr; | |
SetWindowCompositionAttribute(windowHelper.Handle, ref data); | |
Marshal.FreeHGlobal(accentPtr); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Application.Resources> | |
<ResourceDictionary> | |
<ResourceDictionary.MergedDictionaries> | |
<!-- This should be all you need to setup the color theme --> | |
<materialDesignMahApps:MahAppsBundledTheme x:Name="mahAppsBundledTheme" BaseTheme="Inherit" PrimaryColor="DeepPurple" SecondaryColor="Purple"/> | |
<!-- MahApps --> | |
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> | |
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> | |
<!-- Material Design --> | |
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> | |
<!-- Material Design: MahApps Compatibility --> | |
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Defaults.xaml"/> | |
</ResourceDictionary.MergedDictionaries> | |
</ResourceDictionary> | |
</Application.Resources> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment