WPF最大化窗口大于屏幕

lrpiutwd  于 2023-04-22  发布在  其他
关注(0)|答案(5)|浏览(308)

当用AllowsTransparency="True" WindowStyle="None"创建一个WPF窗口并通过this.WindowState = WindowState.Maximized;最大化它时,窗口变得比我的屏幕更大。
当设置AllowTransparency="False"时,我的窗口周围有一个边框,但窗口不会比屏幕大。
在我的例子中,我有一个1920x1080的屏幕,窗口变成了1934x1094。
在我的1280x1024屏幕上,窗口将变为1294x1038。
无论是否启用了AllowTransparency,窗口都会变得像这样大,但禁用了它,它可以正常工作。
在最大化之前设置AllowTransparency不起作用,并引发InvalidOperationException。
如何获得一个没有Windows风格边框的WPF窗口,但还没有正确地最大化?

piok6c0g

piok6c0g1#

几年后的聚会,但只是增加您的this.borderthickness的SizeChanged事件,如下所示:

<Window x:Class="MyApp.MainWindow"
    ResizeMode="CanResize" 
    WindowStyle="SingleBorderWindow"
    SizeChanged="Window_SizeChanged">
....
Code
....
</Window>

public void Window_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (this.WindowState == WindowState.Maximized)
        {
            this.BorderThickness = new System.Windows.Thickness(8);
        }
        else
        {
            this.BorderThickness = new System.Windows.Thickness(0);
        }
    }
2ledvvac

2ledvvac2#

如果您只关心窗口的正确尺寸,并且对外观没有任何问题,则可以将窗口的内容 Package 在System.Windows.Controls.Canvas中,如下所示:

<Canvas Name="MyCanvas" Width="auto" Height="auto">
...
</Canvas>

然后,您可以使用MyCanvas.ActualWidthMyCanvas.ActualHeight来获取当前屏幕的分辨率,并考虑DPI设置和设备独立单位。它不会像最大化窗口本身那样添加任何边距。它也应该适用于多个显示器。
(Canvas接受UIElement s作为子项,因此您应该能够将其用于任何内容。

c90pui9n

c90pui9n3#

不幸的是,除了创建一个不调整大小的WindowStyle="None"窗口之外,没有很好的解决方案。你可以自己处理一切。这意味着你自己的最大化/最小化/恢复按钮,用于设置窗口尺寸以适应屏幕。你自己的实时字幕区域用于拖动。你自己的边框与适当的光标。你自己的双击处理程序用于最大化/恢复。你自己的例行检查鼠标位置对屏幕的高度拖放到码头。等等。你得到的想法。这是一个痛苦的脖子,但如果你这样做一次,至少你会有它为所有未来的项目。不幸的是,你会失去“航空”动画,但唉。
我还想指出这个问题非常重要的一个原因,至少在某些情况下,当窗口跨越两个显示器时,WPF不能充分利用加速图形(就像他们通常在窗口最大化时所做的那样)。这意味着当窗口最大化时,D3DImage以及任何Effect的性能都会受到影响。这发生在我身上,我的许多用户,这也是我关注这个问题的原因

u7up0aaq

u7up0aaq4#

通常一个窗口总是有一个调整大小的边框。现在,当你最大化窗口时,Windows会根据调整大小的边框的厚度来扩大窗口的大小。这样,边框就会被推到屏幕外,也就是说,调整大小的边框会被隐藏起来,从而使窗口具有干净的全屏外观。重要的一点是,Windows * 期望 * 这个调整大小的边框,而WPF允许从Window模板中删除它。
如果你覆盖了窗口边框或者将Window.WindowStyle设置为WindowStyle.None,你将丢失窗口周围的调整边框。Windows不会识别这一点,并继续膨胀Window以隐藏调整边框。因为在我们的例子中(WindowStyle.None),边框从模板中删除了,Windows有效地裁剪了窗口本身。
解决方案是自己补偿预期的调整大小边框厚度。
您可以通过在Window模板中添加一个额外的resize Border并定义一个Trigger来处理WindowState.Maximized的情况(参见 * 解决方案1*)。
或者,简单地对当前Window.BorderThickness进行充气和放气(参见 * 解决方案2*)。
而不是像其他答案建议的那样使用随机猜测的厚度值,如8,您应该使用SystemParameters.WindowResizeBorderThickness常数。

方案一

将窗口调整边框添加回模板。当将Window.WindowStyle设置为WindowStyle.None时,它会被删除。

<Style TargetType="Window">
  <Setter Property="WindowStyle"
          Value="None" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Window}">
        <Border x:Name="ResizeBorder">
          <Border Background="{TemplateBinding Background}"
                  BorderBrush="{TemplateBinding BorderBrush}"
                  BorderThickness="{TemplateBinding BorderThickness}">
            <Grid Background="Transparent">
              <Grid.RowDefinitions>
                <RowDefinition Height="Auto" /> <!-- Title bar row -->
                <RowDefinition /> <!-- Window.Content row -->
                <RowDefinition Height="Auto" /> <!-- Resize gripper row -->
              </Grid.RowDefinitions>

              <AdornerDecorator Grid.Row="1">
                <Border Background="Transparent"
                        Margin="{x:Static SystemParameters.WindowNonClientFrameThickness}">
                  <ContentPresenter />
                </Border>
              </AdornerDecorator>
            </Grid>
          </Border>
        </Border>

        <ControlTemplate.Triggers>
          <Trigger Property="WindowState"
                   Value="Maximized">
            <Setter TargetName="ResizeBorder"
                    Property="BorderThickness"
                    Value="{x:Static SystemParameters.WindowResizeBorderThickness}" />
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

方案二

Window.WindowState属性更改时,膨胀Window.BorderThickness

MainWindow.xaml.cs

partial class MainWindow : Window
{
  private WindowState OldWindowState { get; set; }

  public MainWindow()
  {
    InitializeComponent();
  }

  protected override void OnStateChanged(EventArgs e)
  {
    base.OnStateChanged(e);

    this.BorderThickness = this.WindowState switch
    {
      WindowState.Maximized => InflateBorder(SystemParameters.WindowResizeBorderThickness),
      WindowState.Normal or WindowState.Minimized when this.OldWindowState == WindowState.Maximized => DeflateBorder(SystemParameters.WindowResizeBorderThickness),
      _ => this.BorderThickness
    };

    this.OldWindowState = this.WindowState;
  }

  private Thickness InflateBorder(Thickness thickness)
  {
    double left = this.BorderThickness.Left + thickness.Left;
    double top = this.BorderThickness.Top + thickness.Top;
    double right = this.BorderThickness.Right + thickness.Right;
    double bottom = this.BorderThickness.Bottom + thickness.Bottom;
    return new Thickness(left, top, right, bottom);
  }

  private Thickness DeflateBorder(Thickness thickness)
  {
    double left = this.BorderThickness.Left - thickness.Left;
    double top = this.BorderThickness.Top - thickness.Top;
    double right = this.BorderThickness.Right - thickness.Right;
    double bottom = this.BorderThickness.Bottom - thickness.Bottom;
    return new Thickness(left, top, right, bottom);
  }
lxkprmvk

lxkprmvk5#

设置你窗口的这个属性。

MinHeight="100"
  MinWidth="100"
  Height="auto"
  Width="auto"

希望这能起作用

相关问题