「WindowHeader」与「WindowBorder」完成
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
<Button Content="打开抽屉" Click="Button_Click"/>
|
<Button Content="打开抽屉" Click="Button_Click"/>
|
||||||
<Button Content="自定义窗口标题测试" Click="Button_Click_1"/>
|
<Button Content="自定义窗口标题测试" Click="Button_Click_1"/>
|
||||||
<Button Content="自定义窗口标题栏" Click="Button_Click_2"/>
|
<Button Content="自定义窗口标题栏" Click="Button_Click_2"/>
|
||||||
|
<Button Content="自定义窗口边框" Click="Button_Click_3"/>
|
||||||
</UniformGrid>
|
</UniformGrid>
|
||||||
</AdornerDecorator>
|
</AdornerDecorator>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
|||||||
@@ -42,5 +42,10 @@ namespace Deedy
|
|||||||
{
|
{
|
||||||
new WindowHeaderTest().ShowDialog();
|
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="按钮"/>
|
<Button Content="按钮"/>
|
||||||
</UniformGrid>
|
</UniformGrid>
|
||||||
</deedy:WindowHeader>
|
</deedy:WindowHeader>
|
||||||
<Grid/>
|
<Border BorderBrush="Red" BorderThickness="1" Background="LightBlue"/>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
<Style TargetType="{x:Type local:WindowHeader}">
|
<Style TargetType="{x:Type local:WindowHeader}">
|
||||||
<Setter Property="Height" Value="40"/>
|
<Setter Property="Height" Value="40"/>
|
||||||
<Setter Property="MinHeight" Value="32"/>
|
<Setter Property="MinHeight" Value="32"/>
|
||||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
|
||||||
<Setter Property="DockPanel.Dock" Value="Top"/>
|
<Setter Property="DockPanel.Dock" Value="Top"/>
|
||||||
<Setter Property="Padding" Value="6"/>
|
<Setter Property="Padding" Value="6"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
@@ -60,13 +58,56 @@
|
|||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style TargetType="{x:Type local:WindowBorder}">
|
<Style TargetType="{x:Type local:WindowBorder}">
|
||||||
|
<Setter Property="Padding" Value="6"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="{x:Type local:WindowBorder}">
|
<ControlTemplate TargetType="{x:Type local:WindowBorder}">
|
||||||
<Border Background="{TemplateBinding Background}"
|
<ControlTemplate.Resources>
|
||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
<Style x:Key="ControlButtonStyle" TargetType="{x:Type Button}">
|
||||||
BorderThickness="{TemplateBinding BorderThickness}">
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
</Border>
|
<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>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
@@ -19,12 +20,11 @@ namespace Deedy
|
|||||||
[TemplatePart(Name = "TitleBar", Type = typeof(Control))]
|
[TemplatePart(Name = "TitleBar", Type = typeof(Control))]
|
||||||
[TemplatePart(Name = "Controller", Type = typeof(Panel))]
|
[TemplatePart(Name = "Controller", Type = typeof(Panel))]
|
||||||
[TemplatePart(Name = "Container", Type = typeof(Decorator))]
|
[TemplatePart(Name = "Container", Type = typeof(Decorator))]
|
||||||
public class WindowBorder : HeaderedContentControl
|
public class WindowBorder : ContentControl
|
||||||
{
|
{
|
||||||
static WindowBorder()
|
static WindowBorder()
|
||||||
{
|
{
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowBorder), new FrameworkPropertyMetadata(typeof(WindowBorder)));
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowBorder), new FrameworkPropertyMetadata(typeof(WindowBorder)));
|
||||||
BackgroundProperty.OverrideMetadata(typeof(WindowBorder), new FrameworkPropertyMetadata(Brushes.Gray));
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 悬停画刷
|
/// 悬停画刷
|
||||||
@@ -55,14 +55,24 @@ namespace Deedy
|
|||||||
set { SetValue(HeaderHeightProperty, value); }
|
set { SetValue(HeaderHeightProperty, value); }
|
||||||
}
|
}
|
||||||
public static readonly DependencyProperty HeaderHeightProperty =
|
public static readonly DependencyProperty HeaderHeightProperty =
|
||||||
DependencyProperty.Register("HeaderHeight", typeof(double), typeof(WindowBorder), new PropertyMetadata(40.0,
|
DependencyProperty.Register("HeaderHeight", typeof(double), typeof(WindowBorder), new PropertyMetadata(40.0));
|
||||||
(d, e) => (d as WindowBorder)?.HeaderHeight_PropertyChangedCallback(e)));
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理「WindowBorder.HeaderHeight」属性变更
|
/// 标题
|
||||||
/// </summary>
|
/// </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>
|
/// <summary>
|
||||||
/// 菜单
|
/// 菜单
|
||||||
@@ -141,12 +151,13 @@ namespace Deedy
|
|||||||
this.TitleBar = GetTemplateChild("TitleBar") as Control;
|
this.TitleBar = GetTemplateChild("TitleBar") as Control;
|
||||||
this.MainMenu = GetTemplateChild("MainMenu") as Menu;
|
this.MainMenu = GetTemplateChild("MainMenu") as Menu;
|
||||||
|
|
||||||
|
if (this.Container != null) this.Container.Child = this.Header;
|
||||||
if (this.MainMenu != null)
|
if (this.MainMenu != null)
|
||||||
{
|
{
|
||||||
this.MainMenu.Items.Clear();
|
this.MainMenu.Items.Clear();
|
||||||
if (this.Menu != null)
|
if (this.Menu != null)
|
||||||
{
|
{
|
||||||
this.Menu.Height = this.Height;
|
this.Menu.Height = this.HeaderHeight;
|
||||||
this.Menu.Background = Brushes.Transparent;
|
this.Menu.Background = Brushes.Transparent;
|
||||||
this.MainMenu.Items.Add(this.Menu);
|
this.MainMenu.Items.Add(this.Menu);
|
||||||
}
|
}
|
||||||
@@ -215,11 +226,15 @@ namespace Deedy
|
|||||||
{
|
{
|
||||||
if (this.Target != null)
|
if (this.Target != null)
|
||||||
{
|
{
|
||||||
var winContent = this.Target.Content as FrameworkElement;
|
if (this.Target.Content is not FrameworkElement winContent) return;
|
||||||
if (winContent == null) return;
|
|
||||||
if (this.Target.WindowState == WindowState.Maximized)
|
if (this.Target.WindowState == WindowState.Maximized)
|
||||||
|
{
|
||||||
winContent.Margin = new Thickness(8);
|
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)
|
private void Target_StateChanged(object? sender, EventArgs e)
|
||||||
@@ -228,9 +243,9 @@ namespace Deedy
|
|||||||
}
|
}
|
||||||
private void CommandButton_Click(object sender, RoutedEventArgs e)
|
private void CommandButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Button? button = sender as Button;
|
if (sender is Button button)
|
||||||
if (button != null)
|
|
||||||
{
|
{
|
||||||
|
e.Handled = true;
|
||||||
switch (button.Name)
|
switch (button.Name)
|
||||||
{
|
{
|
||||||
case "Minimize":
|
case "Minimize":
|
||||||
|
|||||||
@@ -204,11 +204,15 @@ namespace Deedy
|
|||||||
{
|
{
|
||||||
if (this.Target != null)
|
if (this.Target != null)
|
||||||
{
|
{
|
||||||
var winContent = this.Target.Content as FrameworkElement;
|
if (this.Target.Content is not FrameworkElement winContent) return;
|
||||||
if (winContent == null) return;
|
|
||||||
if (this.Target.WindowState == WindowState.Maximized)
|
if (this.Target.WindowState == WindowState.Maximized)
|
||||||
|
{
|
||||||
winContent.Margin = new Thickness(8);
|
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)
|
private void Target_StateChanged(object? sender, EventArgs e)
|
||||||
@@ -217,9 +221,9 @@ namespace Deedy
|
|||||||
}
|
}
|
||||||
private void CommandButton_Click(object sender, RoutedEventArgs e)
|
private void CommandButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Button? button = sender as Button;
|
if (sender is Button button)
|
||||||
if (button != null)
|
|
||||||
{
|
{
|
||||||
|
e.Handled = true;
|
||||||
switch (button.Name)
|
switch (button.Name)
|
||||||
{
|
{
|
||||||
case "Minimize":
|
case "Minimize":
|
||||||
|
|||||||
Reference in New Issue
Block a user