「WindowHeader」与「WindowBorder」完成
This commit is contained in:
		@@ -19,6 +19,7 @@
 | 
			
		||||
                <Button Content="打开抽屉" Click="Button_Click"/>
 | 
			
		||||
                <Button Content="自定义窗口标题测试" Click="Button_Click_1"/>
 | 
			
		||||
                <Button Content="自定义窗口标题栏" Click="Button_Click_2"/>
 | 
			
		||||
                <Button Content="自定义窗口边框" Click="Button_Click_3"/>
 | 
			
		||||
            </UniformGrid>
 | 
			
		||||
        </AdornerDecorator>
 | 
			
		||||
    </DockPanel>
 | 
			
		||||
 
 | 
			
		||||
@@ -42,5 +42,10 @@ namespace Deedy
 | 
			
		||||
        {
 | 
			
		||||
            new WindowHeaderTest().ShowDialog();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Button_Click_3(object sender, RoutedEventArgs e)
 | 
			
		||||
        {
 | 
			
		||||
            new WindowBorderTest().ShowDialog();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								DeedyDesigner/Deedy.Testing/WindowBorderTest.xaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								DeedyDesigner/Deedy.Testing/WindowBorderTest.xaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
<Window x:Class="Deedy.Testing.WindowBorderTest"
 | 
			
		||||
        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:Deedy.Testing"
 | 
			
		||||
        xmlns:deedy="clr-namespace:Deedy;assembly=Deedy.Wpf"
 | 
			
		||||
        mc:Ignorable="d"
 | 
			
		||||
        Title="WindowHeaderTest" Height="450" Width="800" Foreground="White" FontSize="16" d:WindowStyle="None" Icon="/Icons/Icon.png">
 | 
			
		||||
    <deedy:WindowBorder ButtonBase.Click="WindowBorder_Click" MenuItem.Click="WindowBorder_Click_1">
 | 
			
		||||
        <deedy:WindowBorder.Menu>
 | 
			
		||||
            <MenuItem Header="CustomMenu">
 | 
			
		||||
                <MenuItem Header="Menu_1"/>
 | 
			
		||||
            </MenuItem>
 | 
			
		||||
        </deedy:WindowBorder.Menu>
 | 
			
		||||
        <deedy:WindowBorder.Header>
 | 
			
		||||
            <UniformGrid Rows="1">
 | 
			
		||||
                <Button Content="测试的标题"/>
 | 
			
		||||
                <Button Content="测试的标题"/>
 | 
			
		||||
                <Button Content="测试的标题"/>
 | 
			
		||||
            </UniformGrid>
 | 
			
		||||
        </deedy:WindowBorder.Header>
 | 
			
		||||
        <Border BorderBrush="Red" BorderThickness="1"/>
 | 
			
		||||
    </deedy:WindowBorder>
 | 
			
		||||
</Window>
 | 
			
		||||
							
								
								
									
										37
									
								
								DeedyDesigner/Deedy.Testing/WindowBorderTest.xaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								DeedyDesigner/Deedy.Testing/WindowBorderTest.xaml.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using System.Windows.Data;
 | 
			
		||||
using System.Windows.Documents;
 | 
			
		||||
using System.Windows.Input;
 | 
			
		||||
using System.Windows.Media;
 | 
			
		||||
using System.Windows.Media.Imaging;
 | 
			
		||||
using System.Windows.Shapes;
 | 
			
		||||
 | 
			
		||||
namespace Deedy.Testing
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// WindowBorderTest.xaml 的交互逻辑
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public partial class WindowBorderTest : Window
 | 
			
		||||
    {
 | 
			
		||||
        public WindowBorderTest()
 | 
			
		||||
        {
 | 
			
		||||
            InitializeComponent();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WindowBorder_Click(object sender, RoutedEventArgs e)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WindowBorder_Click_1(object sender, RoutedEventArgs e)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -24,6 +24,6 @@
 | 
			
		||||
                <Button Content="按钮"/>
 | 
			
		||||
            </UniformGrid>
 | 
			
		||||
        </deedy:WindowHeader>
 | 
			
		||||
        <Grid/>
 | 
			
		||||
        <Border BorderBrush="Red" BorderThickness="1" Background="LightBlue"/>
 | 
			
		||||
    </DockPanel>
 | 
			
		||||
</Window>
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,6 @@
 | 
			
		||||
    <Style TargetType="{x:Type local:WindowHeader}">
 | 
			
		||||
        <Setter Property="Height" Value="40"/>
 | 
			
		||||
        <Setter Property="MinHeight" Value="32"/>
 | 
			
		||||
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
 | 
			
		||||
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
 | 
			
		||||
        <Setter Property="DockPanel.Dock" Value="Top"/>
 | 
			
		||||
        <Setter Property="Padding" Value="6"/>
 | 
			
		||||
        <Setter Property="Template">
 | 
			
		||||
@@ -60,15 +58,58 @@
 | 
			
		||||
    </Style>
 | 
			
		||||
 | 
			
		||||
    <Style TargetType="{x:Type local:WindowBorder}">
 | 
			
		||||
        <Setter Property="Padding" Value="6"/>
 | 
			
		||||
        <Setter Property="Template">
 | 
			
		||||
            <Setter.Value>
 | 
			
		||||
                <ControlTemplate TargetType="{x:Type local:WindowBorder}">
 | 
			
		||||
                    <Border Background="{TemplateBinding Background}"
 | 
			
		||||
                            BorderBrush="{TemplateBinding BorderBrush}"
 | 
			
		||||
                            BorderThickness="{TemplateBinding BorderThickness}">
 | 
			
		||||
                    <ControlTemplate.Resources>
 | 
			
		||||
                        <Style x:Key="ControlButtonStyle" TargetType="{x:Type Button}">
 | 
			
		||||
                            <Setter Property="Background" Value="Transparent"/>
 | 
			
		||||
                            <Setter Property="Cursor" Value="Hand"/>
 | 
			
		||||
                            <Setter Property="Template">
 | 
			
		||||
                                <Setter.Value>
 | 
			
		||||
                                    <ControlTemplate TargetType="{x:Type Button}">
 | 
			
		||||
                                        <Border Background="{TemplateBinding Background}">
 | 
			
		||||
                                            <ContentPresenter Margin="{TemplateBinding Padding}"/>
 | 
			
		||||
                                        </Border>
 | 
			
		||||
                                    </ControlTemplate>
 | 
			
		||||
                                </Setter.Value>
 | 
			
		||||
                            </Setter>
 | 
			
		||||
                            <Style.Triggers>
 | 
			
		||||
                                <Trigger Property="IsMouseOver" Value="True">
 | 
			
		||||
                                    <Setter Property="Background" Value="{Binding HoverBrush,RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
 | 
			
		||||
                                </Trigger>
 | 
			
		||||
                            </Style.Triggers>
 | 
			
		||||
                        </Style>
 | 
			
		||||
                    </ControlTemplate.Resources>
 | 
			
		||||
                    <DockPanel Background="{TemplateBinding Background}">
 | 
			
		||||
                        <Border x:Name="TitleBar" Background="{TemplateBinding Headground}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
 | 
			
		||||
                                DockPanel.Dock="Top" MinHeight="32" Height="{TemplateBinding HeaderHeight}">
 | 
			
		||||
                            <DockPanel>
 | 
			
		||||
                                <Image Margin="{TemplateBinding Padding}" Stretch="Uniform" Source="{Binding Icon, RelativeSource={RelativeSource AncestorType=Window}}"/>
 | 
			
		||||
                                <TextBlock VerticalAlignment="Center" Margin="0,0,6,0" Text="{Binding Title, RelativeSource={RelativeSource AncestorType=Window}}"/>
 | 
			
		||||
                                <DockPanel x:Name="Controller" DockPanel.Dock="Right" MinWidth="147" Background="#01FFFFFF" VerticalAlignment="Stretch">
 | 
			
		||||
                                    <Button x:Name="CloseWin" DockPanel.Dock="Right" Style="{DynamicResource ControlButtonStyle}" Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}">
 | 
			
		||||
                                        <Path Stretch="Uniform" Margin="{TemplateBinding Padding}" Stroke="Transparent" Fill="{TemplateBinding Foreground}" 
 | 
			
		||||
                                              Data="M 1 0 L 0 1 L 23 24 L 24 23 Z M 1 24 L 0 23 L 11 12 L 12 13 Z M 12 11 L 23 0 L 24 1 L 13 12 Z"/>
 | 
			
		||||
                                    </Button>
 | 
			
		||||
                                    <Button x:Name="Maximize" DockPanel.Dock="Right" Style="{DynamicResource ControlButtonStyle}" Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}">
 | 
			
		||||
                                        <Path Stretch="Uniform" Margin="{TemplateBinding Padding}" Stroke="Transparent" Fill="{TemplateBinding Foreground}" 
 | 
			
		||||
                                              Data="M 0 6 V 24 H 18 V 6 H 16.5 V 22.5 H 1.5 V 7.5 H 16.5 V 6 Z M 6 0 H 24 V 18 H 22.5 V 1.5 H 6 Z"/>
 | 
			
		||||
                                    </Button>
 | 
			
		||||
                                    <Button x:Name="Minimize" DockPanel.Dock="Right" Style="{DynamicResource ControlButtonStyle}" Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}">
 | 
			
		||||
                                        <Path Stretch="Uniform" Margin="{TemplateBinding Padding}" Stroke="Transparent" Fill="{TemplateBinding Foreground}" 
 | 
			
		||||
                                              Data="M 0 0 V 24 M 0 11.25 V 12.75 H 24 V 11.25 Z"/>
 | 
			
		||||
                                    </Button>
 | 
			
		||||
                                    <Menu x:Name="MainMenu" Background="#01FFFFFF" Foreground="{TemplateBinding HoverBrush}"/>
 | 
			
		||||
                                </DockPanel>
 | 
			
		||||
                                <Decorator x:Name="Container" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
 | 
			
		||||
                            </DockPanel>
 | 
			
		||||
                        </Border>
 | 
			
		||||
                        <ContentPresenter/>
 | 
			
		||||
                    </DockPanel>
 | 
			
		||||
                </ControlTemplate>
 | 
			
		||||
            </Setter.Value>
 | 
			
		||||
        </Setter>
 | 
			
		||||
    </Style>
 | 
			
		||||
</ResourceDictionary>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
using System.Runtime.CompilerServices;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using System.Windows.Data;
 | 
			
		||||
@@ -19,12 +20,11 @@ namespace Deedy
 | 
			
		||||
    [TemplatePart(Name = "TitleBar", Type = typeof(Control))]
 | 
			
		||||
    [TemplatePart(Name = "Controller", Type = typeof(Panel))]
 | 
			
		||||
    [TemplatePart(Name = "Container", Type = typeof(Decorator))]
 | 
			
		||||
    public class WindowBorder : HeaderedContentControl
 | 
			
		||||
    public class WindowBorder : ContentControl
 | 
			
		||||
    {
 | 
			
		||||
        static WindowBorder()
 | 
			
		||||
        {
 | 
			
		||||
            DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowBorder), new FrameworkPropertyMetadata(typeof(WindowBorder)));
 | 
			
		||||
            BackgroundProperty.OverrideMetadata(typeof(WindowBorder), new FrameworkPropertyMetadata(Brushes.Gray));
 | 
			
		||||
        }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 悬停画刷
 | 
			
		||||
@@ -55,14 +55,24 @@ namespace Deedy
 | 
			
		||||
            set { SetValue(HeaderHeightProperty, value); }
 | 
			
		||||
        }
 | 
			
		||||
        public static readonly DependencyProperty HeaderHeightProperty =
 | 
			
		||||
            DependencyProperty.Register("HeaderHeight", typeof(double), typeof(WindowBorder), new PropertyMetadata(40.0,
 | 
			
		||||
                (d, e) => (d as WindowBorder)?.HeaderHeight_PropertyChangedCallback(e)));
 | 
			
		||||
            DependencyProperty.Register("HeaderHeight", typeof(double), typeof(WindowBorder), new PropertyMetadata(40.0));
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 处理「WindowBorder.HeaderHeight」属性变更
 | 
			
		||||
        /// 标题
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected virtual void HeaderHeight_PropertyChangedCallback(DependencyPropertyChangedEventArgs e)
 | 
			
		||||
        public UIElement Header
 | 
			
		||||
        {
 | 
			
		||||
            if ((double)e.NewValue < 32) this.HeaderHeight = 32;
 | 
			
		||||
            get { return (UIElement)GetValue(HeaderProperty); }
 | 
			
		||||
            set { SetValue(HeaderProperty, value); }
 | 
			
		||||
        }
 | 
			
		||||
        public static readonly DependencyProperty HeaderProperty =
 | 
			
		||||
            DependencyProperty.Register("Header", typeof(UIElement), typeof(WindowBorder), new PropertyMetadata(null,
 | 
			
		||||
                (d, e) => (d as WindowBorder)?.Header_PropertyChangedCallback(e)));
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 处理「WindowBorder.Header」属性变更
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected virtual void Header_PropertyChangedCallback(DependencyPropertyChangedEventArgs e)
 | 
			
		||||
        {
 | 
			
		||||
            if (e.NewValue is UIElement header && this.Container != null) this.Container.Child = header;
 | 
			
		||||
        }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 菜单
 | 
			
		||||
@@ -141,12 +151,13 @@ namespace Deedy
 | 
			
		||||
            this.TitleBar = GetTemplateChild("TitleBar") as Control;
 | 
			
		||||
            this.MainMenu = GetTemplateChild("MainMenu") as Menu;
 | 
			
		||||
 | 
			
		||||
            if (this.Container != null) this.Container.Child = this.Header;
 | 
			
		||||
            if (this.MainMenu != null)
 | 
			
		||||
            {
 | 
			
		||||
                this.MainMenu.Items.Clear();
 | 
			
		||||
                if (this.Menu != null)
 | 
			
		||||
                {
 | 
			
		||||
                    this.Menu.Height = this.Height;
 | 
			
		||||
                    this.Menu.Height = this.HeaderHeight;
 | 
			
		||||
                    this.Menu.Background = Brushes.Transparent;
 | 
			
		||||
                    this.MainMenu.Items.Add(this.Menu);
 | 
			
		||||
                }
 | 
			
		||||
@@ -215,11 +226,15 @@ namespace Deedy
 | 
			
		||||
        {
 | 
			
		||||
            if (this.Target != null)
 | 
			
		||||
            {
 | 
			
		||||
                var winContent = this.Target.Content as FrameworkElement;
 | 
			
		||||
                if (winContent == null) return;
 | 
			
		||||
                if (this.Target.Content is not FrameworkElement winContent) return;
 | 
			
		||||
                if (this.Target.WindowState == WindowState.Maximized)
 | 
			
		||||
                {
 | 
			
		||||
                    winContent.Margin = new Thickness(8);
 | 
			
		||||
                else winContent.Margin = new Thickness(0);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    winContent.Margin = new Thickness(1, 0, 1, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        private void Target_StateChanged(object? sender, EventArgs e)
 | 
			
		||||
@@ -228,9 +243,9 @@ namespace Deedy
 | 
			
		||||
        }
 | 
			
		||||
        private void CommandButton_Click(object sender, RoutedEventArgs e)
 | 
			
		||||
        {
 | 
			
		||||
            Button? button = sender as Button;
 | 
			
		||||
            if (button != null)
 | 
			
		||||
            if (sender is Button button)
 | 
			
		||||
            {
 | 
			
		||||
                e.Handled = true;
 | 
			
		||||
                switch (button.Name)
 | 
			
		||||
                {
 | 
			
		||||
                    case "Minimize":
 | 
			
		||||
 
 | 
			
		||||
@@ -204,11 +204,15 @@ namespace Deedy
 | 
			
		||||
        {
 | 
			
		||||
            if (this.Target != null)
 | 
			
		||||
            {
 | 
			
		||||
                var winContent = this.Target.Content as FrameworkElement;
 | 
			
		||||
                if (winContent == null) return;
 | 
			
		||||
                if (this.Target.Content is not FrameworkElement winContent) return;
 | 
			
		||||
                if (this.Target.WindowState == WindowState.Maximized)
 | 
			
		||||
                {
 | 
			
		||||
                    winContent.Margin = new Thickness(8);
 | 
			
		||||
                else winContent.Margin = new Thickness(0);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    winContent.Margin = new Thickness(1, 0, 1, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        private void Target_StateChanged(object? sender, EventArgs e)
 | 
			
		||||
@@ -217,9 +221,9 @@ namespace Deedy
 | 
			
		||||
        }
 | 
			
		||||
        private void CommandButton_Click(object sender, RoutedEventArgs e)
 | 
			
		||||
        {
 | 
			
		||||
            Button? button = sender as Button;
 | 
			
		||||
            if (button != null)
 | 
			
		||||
            if (sender is Button button)
 | 
			
		||||
            {
 | 
			
		||||
                e.Handled = true;
 | 
			
		||||
                switch (button.Name)
 | 
			
		||||
                {
 | 
			
		||||
                    case "Minimize":
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user