如何获取 WPF 窗口的 ClientSize?

发布于 2024-07-24 05:24:40 字数 207 浏览 3 评论 0原文

在WinForms中,Form有一个ClientSize属性(继承自Control),它返回其客户区域的大小,即标题栏和窗口边框内的区域。

我在 WPF 中没有看到任何类似的内容:没有 ClientSize、ClientWidth、ClientHeight、GetClientSize() 或任何其他我能猜出其名称的内容。

如何获取 WPF 窗口的客户端大小?

In WinForms, Form had a ClientSize property (inherited from Control), which returns the size of its client area, i.e., the area inside the title bar and window borders.

I'm not seeing anything similar in WPF: there's no ClientSize, ClientWidth, ClientHeight, GetClientSize(), or anything else that I can think to guess the name of.

How do I go about getting the client size of a WPF Window?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

掩耳倾听 2024-07-31 05:24:40

一种方法是获取最上面的子元素,将 this.Content 转换为其类型,然后对其调用 .RenderSize,这将为您提供其大小。

<Window x:Class="XML_Reader.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="400" Width="600" WindowStyle="SingleBorderWindow">
    <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    </Grid>
</Window>

((Grid)this.Content).RenderSize.Height
((Grid)this.Content).RenderSize.Width

编辑:

正如特伦特所说,ActualWidth和ActualHeight也是可行的解决方案。 基本上是更简单的方法来获取我上面所说的内容。

One way you could do it is to take the top most child element, cast this.Content to its type, and call .RenderSize on it, which will give you its size.

<Window x:Class="XML_Reader.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="400" Width="600" WindowStyle="SingleBorderWindow">
    <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    </Grid>
</Window>

((Grid)this.Content).RenderSize.Height
((Grid)this.Content).RenderSize.Width

edit:

as Trent said, ActualWidth and ActualHeight are also viable solutions. Basically easier methods of getting what I put above.

愚人国度 2024-07-31 05:24:40
var h = ((Panel)Application.Current.MainWindow.Content).ActualHeight;
var w = ((Panel)Application.Current.MainWindow.Content).ActualWidth;
var h = ((Panel)Application.Current.MainWindow.Content).ActualHeight;
var w = ((Panel)Application.Current.MainWindow.Content).ActualWidth;
蓦然回首 2024-07-31 05:24:40

一种方法是使用下面的代码。 XAML:

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
    <Canvas>
    </Canvas>
</Window>

C#:

using System.Windows;

using System.IO;
using System.Xml;
using System.Windows.Controls;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            double dWidth = -1;
            double dHeight = -1;
            FrameworkElement pnlClient = this.Content as FrameworkElement;
            if (pnlClient != null)
            {
                dWidth = pnlClient.ActualWidth;
                dHeight = pnlClient.ActualHeight;
            }
        }
    }
}

One way to do it is with the code below. XAML:

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
    <Canvas>
    </Canvas>
</Window>

C#:

using System.Windows;

using System.IO;
using System.Xml;
using System.Windows.Controls;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            double dWidth = -1;
            double dHeight = -1;
            FrameworkElement pnlClient = this.Content as FrameworkElement;
            if (pnlClient != null)
            {
                dWidth = pnlClient.ActualWidth;
                dHeight = pnlClient.ActualHeight;
            }
        }
    }
}
醉梦枕江山 2024-07-31 05:24:40

我使用了 GridVerticalAlignment=Top。 结果,网格不幸地不再填充父窗口(这是它的默认行为,但 VerticalAligment 属性破坏了它)。

我通过在网格周围放置一个空的边框解决了这个问题。 该边框填充了窗口的完整内容,它的尺寸与 wpf 窗口的默认边框相同。

为了让网格填充主窗口,我使用了绑定:
<边框BorderThickness="0" x:Name=Main>
...

I used a Grid with VerticalAlignment=Top. As a result the Grid unfortunately didn't fill the parent Window anymore (which is its default behaviour, but the VerticalAligment property spoils it).

I solved it by putting an empty Border around the Grid. This border fills the complete content of the window, it has the same dimensions as the default border that a wpf window has anyways.

To get the Grid to fill the main window, I used the binding:
<Border BorderThickness="0" x:Name=Main>
<Grid VerticalAlignment="Top" Height="{Binding ElementName=Main, Path=ActualHeight}"> ...
</Grid>
</Border>

热情消退 2024-07-31 05:24:40

所有建议的解决方案都基于使用 Windows.Content 的大小来了解窗口内可用的实际大小的想法,如下所示:

var h = ((Panel)Application.Current.MainWindow.Content).ActualHeight;

这当然仅适用于 Window.Content 的情况。内容 不为空。 如果您想从代码中设置 Window.Content 并且您已经需要确切知道有多少可用空间,那么这就是一个问题。

另一个问题是,上述代码仅在第一个布局周期完成后(即在 Window_Loaded 事件中)提供可用空间。 但是,如果您需要知道第一个布局周期期间的可用空间(例如,因为您在 Windows.OnRender() 期间绘制到窗口),该怎么办?

任何Window 可视化树中的第一个控件始终是Border,即使Window.Content 为空。 有趣的是,Border.RenderSize 已经有一个值,即使 RenderSize.ActualSize 可能仍为零。 我猜原因是边框的大小不依赖于 Window.Content,而仅依赖于窗口的大小(当然,除非如果 Window.SizeToContent > 被使用)。

我建议将您的代码放入 Window.SizeChanged 事件中。 因为每次窗口大小改变时,您的内容也需要改变。 您不能使用事件参数中提供的大小,它为您提供了完整窗口的大小,但您可以像这样获取窗口内的可用大小:

var h = ((Border)GetVisualChild(0)).RenderSize.Height;

如果您覆盖 Windows,您也可以使用该行代码.OnRender()。

All the suggested solutions are based on the idea to use the size of Windows.Content to know what is the actual size available within the window, like this:

var h = ((Panel)Application.Current.MainWindow.Content).ActualHeight;

This of course only works if Window.Content is not null. Which is a problem if you want to set Window.Content from your code and you already then need to know exactly how much space is available.

The other problem is that the above code only provides the available space once a first layout cycle has completed (i.e. in the Window_Loaded event). But what do you do if you need to know the available space during the first layout cycle, for example because you draw to the window during Windows.OnRender() ?

The first control in the visual tree of any Window is always a Border, even if Window.Content is null. Interestingly, Border.RenderSize has already a value, even when RenderSize.ActualSize might still be zero. I guess the reason is that the size of the Border does not depend on Window.Content, but only on the size of the window (unless, of course, if Window.SizeToContent is used).

I recommend to place your code into the Window.SizeChanged event. Because each time the Window size changes, your content needs to change too. You cannot use the size provided in the event parameters, which gives you the size of the complete window, but you can get the the available size within the window like this:

var h = ((Border)GetVisualChild(0)).RenderSize.Height;

You can use that line of code also if you override Windows.OnRender().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文