完成新版窗口自定义标题栏

This commit is contained in:
zengwenjie
2025-09-29 19:45:41 +08:00
parent 72e57764ec
commit 28157aa9a6
4 changed files with 65 additions and 10 deletions

View File

@@ -6,10 +6,19 @@
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="18" d:WindowStyle="None" Icon="/Icons/Icon.png">
Title="WindowHeaderTest" Height="450" Width="800" Foreground="White" FontSize="16" d:WindowStyle="None" Icon="/Icons/Icon.png">
<DockPanel>
<deedy:WindowHeader ButtonBase.Click="WindowHeader_Click">
<UniformGrid Rows="1">
<deedy:WindowHeader ButtonBase.Click="WindowHeader_Click" MenuItem.Click="WindowHeader_Click_1">
<deedy:WindowHeader.Menu>
<MenuItem Header="CustomMenu">
<MenuItem Header="menu_1" Foreground="Red">
<MenuItem.Icon>
<Image Source="/Icons/Icon.png"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</deedy:WindowHeader.Menu>
<UniformGrid Rows="1" HorizontalAlignment="Center" MinWidth="300">
<Button Content="按钮"/>
<Button Content="按钮"/>
<Button Content="按钮"/>

View File

@@ -28,5 +28,10 @@ namespace Deedy.Testing
{
}
private void WindowHeader_Click_1(object sender, RoutedEventArgs e)
{
}
}
}

View File

@@ -4,6 +4,7 @@
xmlns:local="clr-namespace:Deedy">
<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"/>
@@ -12,7 +13,7 @@
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:WindowHeader}">
<ControlTemplate.Resources>
<Style x:Key="controlButtonStyle" TargetType="{x:Type Button}">
<Style x:Key="ControlButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
@@ -31,20 +32,19 @@
<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}}">
<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}}">
<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}}">
</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>
<Border/>
<Menu x:Name="MainMenu" Background="#01FFFFFF" Foreground="{TemplateBinding HoverBrush}"/>
</DockPanel>
<Decorator x:Name="Container" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</DockPanel>

View File

@@ -15,6 +15,7 @@ using System.Windows.Shell;
namespace Deedy
{
[ContentProperty("Child")]
[TemplatePart(Name = "MainMenu", Type = typeof(Menu))]
[TemplatePart(Name = "Minimize", Type = typeof(Button))]
[TemplatePart(Name = "Maximize", Type = typeof(Button))]
[TemplatePart(Name = "CloseWin", Type = typeof(Button))]
@@ -53,12 +54,40 @@ namespace Deedy
windowHeader.Container.Child = e.NewValue as UIElement;
}
}));
/// <summary>
/// 菜单
/// </summary>
public MenuItem Menu
{
get { return (MenuItem)GetValue(MenuProperty); }
set { SetValue(MenuProperty, value); }
}
public static readonly DependencyProperty MenuProperty =
DependencyProperty.Register("Menu", typeof(MenuItem), typeof(WindowHeader), new PropertyMetadata(null,
(d, e) => (d as WindowHeader)?.Menu_PropertyChangedCallback(e)));
/// <summary>
/// 处理「WindowHeader.Menu」属性变更
/// </summary>
protected virtual void Menu_PropertyChangedCallback(DependencyPropertyChangedEventArgs e)
{
if (this.MainMenu != null)
{
this.MainMenu.Items.Clear();
if (e.NewValue is MenuItem menu)
{
menu.Height = this.ActualHeight;
menu.Background = Brushes.Transparent;
this.MainMenu.Items.Add(menu);
}
}
}
private Panel? Controller;
private Decorator? Container;
private Button? Minimize;
private Button? Maximize;
private Button? CloseWin;
private Menu? MainMenu;
private Window? Target;
private WindowChrome? Chrome;
@@ -98,8 +127,19 @@ namespace Deedy
this.Minimize = GetTemplateChild("Minimize") as Button;
this.Maximize = GetTemplateChild("Maximize") as Button;
this.CloseWin = GetTemplateChild("CloseWin") as Button;
this.MainMenu = GetTemplateChild("MainMenu") as Menu;
if (this.Container != null) this.Container.Child = this.Child;
if (this.MainMenu != null)
{
this.MainMenu.Items.Clear();
if (this.Menu != null)
{
this.Menu.Height = this.Height;
this.Menu.Background = Brushes.Transparent;
this.MainMenu.Items.Add(this.Menu);
}
}
}
private void Target_Loaded(object sender, RoutedEventArgs e)
{
@@ -121,6 +161,7 @@ namespace Deedy
button?.AddHandler(Button.MouseLeaveEvent, new RoutedEventHandler((s, e) => ((Button)e.Source).Background = Brushes.Transparent));
}
}
if (this.Menu != null) this.Menu.Height = this.ActualHeight;
this.AdjustVisual();
this.AdjustMargin();
}