Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用WindowChrome复制标准系统菜单?_C#_.net_Wpf_Window Chrome - Fatal编程技术网

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

C# 使用WindowChrome复制标准系统菜单?,c#,.net,wpf,window-chrome,C#,.net,Wpf,Window Chrome,使用()自定义窗口的非客户端区域时,一个自然的起点是使标题栏的外观和行为与标准标题栏相同。这需要添加一个“假”应用程序图标和标题栏,因为WindowChrome显然禁用了这些功能(最小化、最大化和关闭按钮仍然有效) 以下是我目前掌握的情况: <Window x:Class="MyApp.MainWindow" x:Name="MainWindowItself" xmlns="http://schemas.microsoft.com/winfx/2006/xa

使用()自定义窗口的非客户端区域时,一个自然的起点是使标题栏的外观和行为与标准标题栏相同。这需要添加一个“假”应用程序图标和标题栏,因为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>

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

我的xaml并不完全相同(我不使用WindowChrome,但我自己使用,我有一个标题栏模板),但我遇到了完全相同的问题,解决方案也应该对您有用

首先是简单的一个:要使双击有效,只需使用ClickCount

然后,让菜单消失需要保持一些状态,告诉它当前是否处于活动状态:诀窍是在第二次单击时触发不同的事件(如使用所示)。第一次单击只是一次鼠标向下,第二次单击是MouseDown,然后是MouseUp(我的猜测是,从第一次单击开始的向上移动由sysmenu处理)


要禁用标准Chrome按钮,只需在shell:WindowsChrome的XAML代码中添加一个额外属性
CaptionHeight=“0”

就是这样

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

要使它成为完美的解决方案,只缺少一件事:在
堆栈面板中设置
WindowChrome.IshittesVisibleinChrome=“True”
将使窗口可以双击和拖动。(由@pushpraj在回答问题时提供。)
private bool inSysMenu = false;

void SystemMenuIcon_MouseDown( object sender, MouseButtonEventArgs e )
{
  if( e.ClickCount == 1 && !inSysMenu )
  {
    inSysMenu = true;
    ShowSystemMenu(); //replace with your code
  }
  else if( e.ClickCount == 2 && e.ChangedButton == MouseButton.Left )
  {
    window.Close();
  }
}

void SystemMenuIcon_MouseLeave( object sender, MouseButtonEventArgs e )
{
  inSysMenu = false;
}

void SystemMenuIcon_MouseUp( object sender, MouseButtonEventArgs e )
{
  inSysMenu = false;
}
<Setter Property="shell:WindowChrome.WindowChrome">
    <Setter.Value>
        <shell:WindowChrome CaptionHeight="0" />
    </Setter.Value>
</Setter>
<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>
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);
}