using Microsoft.Xaml.Behaviors; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shell; using System.Windows; using System.Windows.Shapes; using System.Windows.Media.Animation; using System.Windows.Input; using System.Windows.Markup; using System.ComponentModel; namespace Future.Contract { /// /// 为窗口提供自定义标题栏的行为 /// [ContentProperty("ICON")] public class CustomTitleBar : Behavior { //private readonly static string svgMax = "M959.72 0H294.216a63.96 63.96 0 0 0-63.96 63.96v127.92H64.28A63.96 63.96 0 0 0 0.32 255.84V959.4a63.96 63.96 0 0 0 63.96 63.96h703.56a63.96 63.96 0 0 0 63.96-63.96V792.465h127.92a63.96 63.96 0 0 0 63.96-63.96V63.96A63.96 63.96 0 0 0 959.72 0zM767.84 728.505V959.4H64.28V255.84h703.56z m189.322 0H831.8V255.84a63.96 63.96 0 0 0-63.96-63.96H294.216V63.96H959.72z"; //private readonly static string[] svgNomal = new string[] { // "M785.960424 410.377773c0-14.634419-11.871277-26.608035-26.608035-26.608035L204.677194 383.769738c-14.634419 0-26.608035 11.871277-26.608035 26.608035l0 349.998001c0 14.634419 11.871277 26.608035 26.608035 26.608035l554.675195 0c14.634419 0 26.608035-11.871277 26.608035-26.608035L785.960424 410.377773zM740.931441 741.954827 223.098141 741.954827 223.098141 428.798721l517.8333 0L740.931441 741.954827z", // "M856.471717 294.735159l-554.675195 0c-12.485309 0-22.514491 10.029182-22.514491 22.514491s10.029182 22.514491 22.514491 22.514491L838.153108 339.764142l0 331.679392c0 12.485309 10.029182 22.514491 22.514491 22.514491s22.514491-10.029182 22.514491-22.514491l0-349.998001C883.182091 306.708775 871.106136 294.735159 856.471717 294.735159z" //}; //private readonly static Geometry svgMaxGeometry; //private readonly static Geometry svgNomalGeometry; //static CustomTitleBar() //{ // svgMaxGeometry = Geometry.Parse(svgMax); // GeometryGroup nomal = new GeometryGroup(); // nomal.Children.Add(Geometry.Parse(svgNomal[0])); // nomal.Children.Add(Geometry.Parse(svgNomal[1])); // svgNomalGeometry = nomal; //} private void AssociatedObject_Loaded(object sender, RoutedEventArgs e) { FrameworkElement winContent = this.AssociatedObject.Content as FrameworkElement; if (winContent == null) return; if (this.AssociatedObject.WindowState == WindowState.Maximized) winContent.Margin = new Thickness(8); else winContent.Margin = new Thickness(0); Grid titleBarRoot = new Grid() { Height = this.TitleHeight }; titleBarRoot.Background = this.Background ?? this.AssociatedObject.Background; StackPanel spLeft = new StackPanel() { VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Left, Orientation = Orientation.Horizontal }; Border bIcon = new Border() { MinWidth = this.TitleHeight }; bIcon.Child = this.ICON ?? new Image() { Source = this.AssociatedObject.Icon }; TextBlock tbTitle = new TextBlock() { Text = this.AssociatedObject.Title, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Left, Foreground = Foreground = this.Foreground ?? this.AssociatedObject.Foreground, FontSize = this.FontSize }; spLeft.Children.Add(bIcon); spLeft.Children.Add(tbTitle); string templateString = "" + "\r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + "\r\n"; ResourceDictionary dictionary = (ResourceDictionary)XamlReader.Parse(templateString); ControlTemplate template = (ControlTemplate)dictionary["dpButtonTemplate"] as ControlTemplate; StackPanel spRight = new StackPanel() { VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Right, Orientation = Orientation.Horizontal, Width = this.TitleHeight * 4, FlowDirection = FlowDirection.RightToLeft }; Button butClose = new Button() { Name = "Close", Background = this.Background ?? this.AssociatedObject.Background, Foreground = this.Foreground ?? this.AssociatedObject.Foreground, BorderThickness = new Thickness(0), Padding = new Thickness(this.TitleHeight * 0.2), Template = template, Content = new Viewbox() { Child = new Path() { Data = Geometry.Parse("M548.992 503.744L885.44 167.328a31.968 31.968 0 1 0-45.248-45.248L503.744 458.496 167.328 122.08a31.968 31.968 0 1 0-45.248 45.248l336.416 336.416L122.08 840.16a31.968 31.968 0 1 0 45.248 45.248l336.416-336.416L840.16 885.44a31.968 31.968 0 1 0 45.248-45.248L548.992 503.744z"), Height = 1024, Width = 1024, Fill = this.AssociatedObject.Foreground } } }; Button butMax = new Button() { Name = "Max", Background = this.Background ?? this.AssociatedObject.Background, Foreground = this.Foreground ?? this.AssociatedObject.Foreground, BorderThickness = new Thickness(0), Padding = new Thickness(this.TitleHeight*0.2+3), Template = template, Content = new Viewbox() { Child = new Path() { Data = Geometry.Parse("M959.72 0H294.216a63.96 63.96 0 0 0-63.96 63.96v127.92H64.28A63.96 63.96 0 0 0 0.32 255.84V959.4a63.96 63.96 0 0 0 63.96 63.96h703.56a63.96 63.96 0 0 0 63.96-63.96V792.465h127.92a63.96 63.96 0 0 0 63.96-63.96V63.96A63.96 63.96 0 0 0 959.72 0zM767.84 728.505V959.4H64.28V255.84h703.56z m189.322 0H831.8V255.84a63.96 63.96 0 0 0-63.96-63.96H294.216V63.96H959.72z"), Height = 1024, Width = 1024, Fill = this.AssociatedObject.Foreground } } }; Button butMin = new Button() { Name = "Min", Background = this.Background ?? this.AssociatedObject.Background, Foreground = this.Foreground ?? this.AssociatedObject.Foreground, BorderThickness = new Thickness(0), Padding = new Thickness(this.TitleHeight * 0.2), Template = template, Content = new Viewbox() { Child = new Path() { Data = Geometry.Parse("M130 545.3h766c17.7 0 32-14.3 32-32s-14.3-32-32-32H130c-17.7 0-32 14.3-32 32 0 17.6 14.3 32 32 32z"), Height = 1024, Width = 1024, Fill = this.AssociatedObject.Foreground } } }; butClose.Click += ButClose_Click; butMax.Click += ButMax_Click; butMin.Click += ButMin_Click; spRight.Children.Add(butClose); spRight.Children.Add(butMax); spRight.Children.Add(butMin); butClose.AddHandler(Button.MouseEnterEvent, new RoutedEventHandler(this.ButMouseEnter)); butMax.AddHandler(Button.MouseEnterEvent, new RoutedEventHandler(this.ButMouseEnter)); butMin.AddHandler(Button.MouseEnterEvent, new RoutedEventHandler(this.ButMouseEnter)); butClose.AddHandler(Button.MouseLeaveEvent, new RoutedEventHandler(this.ButMouseLeave)); butMax.AddHandler(Button.MouseLeaveEvent, new RoutedEventHandler(this.ButMouseLeave)); butMin.AddHandler(Button.MouseLeaveEvent, new RoutedEventHandler(this.ButMouseLeave)); titleBarRoot.Children.Add(spLeft); titleBarRoot.Children.Add(spRight); titleBarRoot.Children.Add(new TextBlock() { Text = this.Header, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center, Foreground = this.Foreground ?? this.AssociatedObject.Foreground, FontSize = this.FontSize * 0.8, Opacity = 0.5 }); WindowChrome.SetIsHitTestVisibleInChrome(spRight, true); this.TitleBar.Child = titleBarRoot; } private void ButMouseEnter(object sender, RoutedEventArgs e) { var button = sender as Button; if (button != null) button.Background = this.HoverBrush; } private void ButMouseLeave(object sender, RoutedEventArgs e) { var button = sender as Button; if (button != null) button.Background = new SolidColorBrush(Colors.Transparent); } private void ButMin_Click(object sender, RoutedEventArgs e) { this.AssociatedObject.WindowState = WindowState.Minimized; } private void ButMax_Click(object sender, RoutedEventArgs e) { if (this.AssociatedObject.WindowState == WindowState.Maximized) this.AssociatedObject.WindowState = WindowState.Normal; else this.AssociatedObject.WindowState = WindowState.Maximized; } private void ButClose_Click(object sender, RoutedEventArgs e) { this.AssociatedObject.Close(); } protected override void OnAttached() { Window target = this.AssociatedObject; WindowChrome.SetWindowChrome(target, new WindowChrome() { CaptionHeight = this.TitleHeight }); this.AssociatedObject.Loaded += AssociatedObject_Loaded; this.AssociatedObject.StateChanged += AssociatedObject_StateChanged; } private void AssociatedObject_StateChanged(object sender, EventArgs e) { var winContent = this.AssociatedObject.Content as FrameworkElement; if (winContent == null) return; if (this.AssociatedObject.WindowState == WindowState.Maximized) winContent.Margin = new Thickness(8); else winContent.Margin = new Thickness(0); } protected override void OnDetaching() { this.AssociatedObject.Loaded -= AssociatedObject_Loaded; } public int TitleHeight { get { return (int)GetValue(TitleHeightProperty); } set { SetValue(TitleHeightProperty, value); } } // Using a DependencyProperty as the backing store for TitleHeight. This enables animation, styling, binding, etc... public static readonly DependencyProperty TitleHeightProperty = DependencyProperty.Register("TitleHeight", typeof(int), typeof(CustomTitleBar), new PropertyMetadata(40)); public Decorator TitleBar { get { return (Decorator)GetValue(TitleBarProperty); } set { SetValue(TitleBarProperty, value); } } // Using a DependencyProperty as the backing store for TitleBar. This enables animation, styling, binding, etc... public static readonly DependencyProperty TitleBarProperty = DependencyProperty.Register("TitleBar", typeof(Decorator), typeof(CustomTitleBar), new PropertyMetadata(null)); public Brush Background { get { return (Brush)GetValue(BackgroundProperty); } set { SetValue(BackgroundProperty, value); } } // Using a DependencyProperty as the backing store for Background. This enables animation, styling, binding, etc... public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(Brush), typeof(CustomTitleBar), new PropertyMetadata(null)); public Brush HoverBrush { get { return (Brush)GetValue(HoverBrushProperty); } set { SetValue(HoverBrushProperty, value); } } // Using a DependencyProperty as the backing store for HoverBrush. This enables animation, styling, binding, etc... public static readonly DependencyProperty HoverBrushProperty = DependencyProperty.Register("HoverBrush", typeof(Brush), typeof(CustomTitleBar), new PropertyMetadata(null)); public Brush Foreground { get { return (Brush)GetValue(ForegroundProperty); } set { SetValue(ForegroundProperty, value); } } // Using a DependencyProperty as the backing store for Foreground. This enables animation, styling, binding, etc... public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register("Foreground", typeof(Brush), typeof(CustomTitleBar), new PropertyMetadata(null)); public UIElement ICON { get { return (UIElement)GetValue(ICONProperty); } set { SetValue(ICONProperty, value); } } // Using a DependencyProperty as the backing store for ICON. This enables animation, styling, binding, etc... public static readonly DependencyProperty ICONProperty = DependencyProperty.Register("ICON", typeof(UIElement), typeof(CustomTitleBar), new PropertyMetadata(null)); public double FontSize { get { return (double)GetValue(FontSizeProperty); } set { SetValue(FontSizeProperty, value); } } // Using a DependencyProperty as the backing store for FontSize. This enables animation, styling, binding, etc... public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register("FontSize", typeof(double), typeof(CustomTitleBar), new PropertyMetadata(18.0)); public string Header { get { return (string)GetValue(HeaderProperty); } set { SetValue(HeaderProperty, value); } } // Using a DependencyProperty as the backing store for Header. This enables animation, styling, binding, etc... public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(CustomTitleBar), new PropertyMetadata("")); } }