324 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			324 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
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
 | 
						|
{
 | 
						|
    /// <summary>
 | 
						|
    /// 为窗口提供自定义标题栏的行为
 | 
						|
    /// </summary>
 | 
						|
    [ContentProperty("ICON")]
 | 
						|
    public class CustomTitleBar : Behavior<Window>
 | 
						|
    {
 | 
						|
        //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 = "" +
 | 
						|
                    "<ResourceDictionary    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\r\n" +
 | 
						|
                    "                       xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\r\n" +
 | 
						|
                    "   <ControlTemplate x:Key=\"dpButtonTemplate\" TargetType=\"Button\">\r\n" +
 | 
						|
                    "       <Border BorderBrush=\"{TemplateBinding BorderBrush}\" Background=\"{TemplateBinding Background}\" BorderThickness=\"{TemplateBinding BorderThickness}\">\r\n" +
 | 
						|
                    "           <ContentPresenter Margin=\"{TemplateBinding Padding}\"/>\r\n" +
 | 
						|
                    "       </Border>\r\n" +
 | 
						|
                    "   </ControlTemplate>\r\n" +
 | 
						|
                    "</ResourceDictionary>\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(""));
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
}
 |