using System.Windows.Shell; using WPFluent.Appearance; namespace WPFluent.Controls; /// /// If you use to extend the UI elements to the non-client area, you can include this /// container in the template of so that the content inside automatically fills the client area. /// Using this container can let you get rid of various margin adaptations done in Setter/Trigger of the style of when the window state changes. /// /// /// <Style x:Key="MyWindowCustomStyle" BasedOn="{StaticResource {x:Type Window}}" /// TargetType="{x:Type controls:FluentWindow}"> <Setter Property="Template" > <Setter.Value> /// <ControlTemplate TargetType="{x:Type Window}"> <AdornerDecorator> <controls:ClientAreaBorder /// Background="{TemplateBinding Background}" ControlBorderBrush="{TemplateBinding ControlBorderBrush}" /// BorderThickness="{TemplateBinding BorderThickness}"> <ContentPresenter x:Name="ContentPresenter" /> /// </controls:ClientAreaBorder> </AdornerDecorator> </ControlTemplate> </Setter.Value> /// </Setter> </Style> /// public class ClientAreaBorder : System.Windows.Controls.Border/*, IThemeControl*/ { /*private const int SM_CXFRAME = 32; private const int SM_CYFRAME = 33; private const int SM_CXPADDEDBORDER = 92;*/ private static Thickness? _resizeFrameBorderThickness; private static Thickness? _windowChromeNonClientFrameThickness; //private bool borderBrushApplied = false; private System.Windows.Window? _oldWindow; //public ClientAreaBorder() //{ // ApplicationTheme = Appearance.ThemeManager.GetAppTheme(); // Appearance.ThemeManager.Changed += OnThemeChanged; //} //private void ApplyDefaultWindowBorder() //{ // if (_oldWindow == null) // { // return; // } // borderBrushApplied = true; // // SystemParameters.WindowGlassBrush // Color borderColor = // ApplicationTheme == ThemeType.Light // ? Color.FromArgb(0xFF, 0x7A, 0x7A, 0x7A) // : Color.FromArgb(0xFF, 0x3A, 0x3A, 0x3A); // _oldWindow.SetCurrentValue( // System.Windows.Controls.Control.BorderBrushProperty, // new SolidColorBrush(borderColor)); // _oldWindow.SetCurrentValue(System.Windows.Controls.Control.BorderThicknessProperty, new Thickness(1)); //} //private void OnThemeChanged(ThemeType currentApplicationTheme, Color systemAccent) //{ // ApplicationTheme = currentApplicationTheme; // if (!borderBrushApplied || _oldWindow == null) // { // return; // } // ApplyDefaultWindowBorder(); //} private void OnWindowClosing(object? sender, CancelEventArgs e) { //Appearance.ThemeManager.Changed -= OnThemeChanged; if (_oldWindow != null) { _oldWindow.Closing -= OnWindowClosing; } } private void OnWindowStateChanged(object? sender, EventArgs e) { if (sender is not System.Windows.Window window) { return; } Thickness padding = window.WindowState == WindowState.Maximized ? WindowChromeNonClientFrameThickness : default; SetCurrentValue(PaddingProperty, padding); } /// protected override void OnVisualParentChanged(DependencyObject oldParent) { base.OnVisualParentChanged(oldParent); if (_oldWindow is { } oldWindow) { oldWindow.StateChanged -= OnWindowStateChanged; oldWindow.Closing -= OnWindowClosing; } var newWindow = System.Windows.Window.GetWindow(this); if (newWindow is not null) { newWindow.StateChanged -= OnWindowStateChanged; // Unsafe newWindow.StateChanged += OnWindowStateChanged; newWindow.Closing += OnWindowClosing; } _oldWindow = newWindow; //ApplyDefaultWindowBorder(); } //public ThemeType ApplicationTheme { get; set; } = ThemeType.Unknow; /// /// Gets the system and values in WPF units. /// public static Thickness ResizeFrameBorderThickness => _resizeFrameBorderThickness ??= new Thickness( SystemParameters.ResizeFrameVerticalBorderWidth, SystemParameters.ResizeFrameHorizontalBorderHeight, SystemParameters.ResizeFrameVerticalBorderWidth, SystemParameters.ResizeFrameHorizontalBorderHeight); /// /// Gets the thickness of the window's non-client frame used for maximizing the window with a custom chrome. /// /// /// If you use a to extend the client area of a window to the non-client area, you need /// to handle the edge margin issue when the window is maximized. Use this property to get the correct margin value /// when the window is maximized, so that when the window is maximized, the client area can completely cover the /// screen client area by no less than a single pixel at any DPI. The method /// cannot obtain this value directly. /// public Thickness WindowChromeNonClientFrameThickness => _windowChromeNonClientFrameThickness ??= new Thickness( ClientAreaBorder.ResizeFrameBorderThickness.Left, ClientAreaBorder.ResizeFrameBorderThickness.Top, ClientAreaBorder.ResizeFrameBorderThickness.Right, ClientAreaBorder.ResizeFrameBorderThickness.Bottom); }