gpt4 book ai didi

c# - 使用 WindowChrome 复制标准系统菜单?

转载 作者:行者123 更新时间:2023-11-30 15:44:20 27 4
gpt4 key购买 nike

使用 WindowChrome 时( downloadable here ) 要自定义窗口的非客户区,一个自然的起点是制作一个外观和行为与标准标题栏相同的标题栏。这需要添加一个“假”应用程序图标和标题栏,因为显然 WindowChrome 禁用了这些功能(最小化、最大化和关闭按钮仍然有效。)

这是我目前所拥有的:

<Window x:Class="MyApp.MainWindow"
x:Name="MainWindowItself"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell"
xmlns:local="clr-namespace:MyApp"
Title="My Application" Icon="App.ico" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MainWindow}">
<Grid>
<Border Background="White" Margin="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=WindowNonClientFrameThickness}">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}"
VerticalAlignment="Top" HorizontalAlignment="Left"
Margin="32,8,0,0"/>
<Image x:Name="SystemMenuIcon" Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Icon}"
VerticalAlignment="Top" HorizontalAlignment="Left"
Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(shell:WindowChrome.WindowChrome).ResizeBorderThickness}"
Width="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=SmallIconSize.Width}"
shell:WindowChrome.IsHitTestVisibleInChrome="True" MouseDown="SystemMenuIcon_MouseDown">
</Image>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TextBlock Text="Client area content goes here"/>
</Grid>
</Window>

代码隐藏:

private void SystemMenuIcon_MouseDown(object sender, MouseButtonEventArgs e)
{
var offs = SystemParameters2.Current.WindowNonClientFrameThickness;
SystemCommands.ShowSystemMenu(this, new Point(Left + offs.Left, Top + offs.Top));
}

这非常接近工作。第一个问题是,在您单击应用程序图标并出现系统菜单后,如果您再次单击该菜单应该会消失——相反,该菜单只是重新绘制。此外,如果双击,则窗口应该关闭,但 Image 没有双击事件。您建议如何添加这些功能?

最佳答案

要禁用标准 Chrome 按钮的工作只需在 shell:WindowsChrome

的 XAML 代码中添加一个额外的属性 CaptionHeight="0"

就这样吧

<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome CaptionHeight="0" />
</Setter.Value>
</Setter>

做一个假的 Chrome。修改模板如下:

<ControlTemplate TargetType="Window">
<AdornerDecorator>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="PART_Chrome" shell:WindowChrome.IsHitTestVisibleInChrome="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="105" />
</Grid.ColumnDefinitions>

<Image Source="Application Favicon Path" />

<TextBlock Grid.Column="1" Text="{TemplateBinding Title}" VerticalAlignment="Center" />

<StackPanel Orientation="Horizontal" Grid.Column="3" >
<Button Command="{Binding Source={x:Static shell:SystemCommands.MinimizeWindowCommand}}" >
<Path Data="M0,6 L8,6 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center"
Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2" />
</Button>
<Button x:Name="MaximizeButton" Command="{Binding Source={x:Static shell:SystemCommands.MaximizeWindowCommand}}" >
<Path Data="M0,1 L9,1 L9,8 L0,8 Z" Width="9" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"
Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2" />
</Button>
<Button x:Name="RestoreButton" Command="{Binding Source={x:Static shell:SystemCommands.RestoreWindowCommand}}" >
<Path Data="M2,0 L8,0 L8,6 M0,3 L6,3 M0,2 L6,2 L6,8 L0,8 Z" Width="8" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"
Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1" />
</Button>
<Button Command="{Binding Source={x:Static shell:SystemCommands.CloseWindowCommand}}" >
<Path Data="M0,0 L8,7 M8,0 L0,7 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center"
Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1.5" />
</Button>
</StackPanel>
</Grid>
<ContentPresenter Grid.Row="1" Content="{TemplateBinding Content}" />
</Grid>
</AdornerDecorator>
<ControlTemplate.Triggers>
<Trigger Property="WindowState" Value="Normal">
<Setter Property="Visibility" Value="Collapsed" TargetName="RestoreButton" />
<Setter Property="Visibility" Value="Visible" TargetName="MaximizeButton" />
</Trigger>
<Trigger Property="WindowState" Value="Maximized">
<Setter Property="Visibility" Value="Visible" TargetName="RestoreButton" />
<Setter Property="Visibility" Value="Collapsed" TargetName="MaximizeButton" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

也为 Fake Chrome bar 的正常工作做命令绑定(bind)

public MainWindow()
{
this.CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, OnCloseWindow));
this.CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, OnMaximizeWindow, OnCanResizeWindow));
this.CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, OnMinimizeWindow, OnCanMinimizeWindow));
this.CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, OnRestoreWindow, OnCanResizeWindow));

}

private void OnCanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = this.ResizeMode != ResizeMode.NoResize;
}

private void OnCanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = this.ResizeMode == ResizeMode.CanResize || this.ResizeMode == ResizeMode.CanResizeWithGrip;
}

private void OnCloseWindow(object sender, ExecutedRoutedEventArgs e)
{
Microsoft.Windows.Shell.SystemCommands.CloseWindow(this);
}

private void OnMaximizeWindow(object sender, ExecutedRoutedEventArgs e)
{
Microsoft.Windows.Shell.SystemCommands.MaximizeWindow(this);
}

private void OnMinimizeWindow(object sender, ExecutedRoutedEventArgs e)
{
Microsoft.Windows.Shell.SystemCommands.MinimizeWindow(this);
}

private void OnRestoreWindow(object sender, ExecutedRoutedEventArgs e)
{
Microsoft.Windows.Shell.SystemCommands.RestoreWindow(this);
}

关于c# - 使用 WindowChrome 复制标准系统菜单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6131684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com