窗口上的 SizeToContent:加载缓慢会导致窗口显示较小,然后正确调整大小

发布于 2024-10-22 01:25:59 字数 856 浏览 3 评论 0原文

好的,我有一个根据用户请求弹出的窗口(在程序正常运行期间),以显示一些特定于上下文的信息。该窗口中恰好有很多元素,因此加载需要 0.5 - 1 秒。但是,由于我期望此窗口根据上下文包含几种不同类型的信息,因此其内容的宽度和高度可能会有所不同。因此,我将 SizeToContent 值设置为“WidthAndHeight”,以允许窗口根据绑定到它的任何内容来调整大小。

但是,由于窗口需要一些时间来加载,因此用户首先会看到一个小的方形窗口,然后在渲染完所有内容后看到全尺寸的窗口。我想避免让用户在完全加载之前看到小窗口。

有没有办法让窗口仅在完全渲染后显示?

我尝试过的事情:

  • 将窗口的可见性设置为“隐藏”,然后将其设置为“可见” " 在 ContentRendered 事件处理程序中:窗口从未显示。

  • 将窗口的不透明度设置为 0,然后在 ContentRendered 事件处理程序中将其设置为 1:窗口本身内容的不透明度设置为 0,然后设置为 1。

更新:

我也尝试将 Window.WindowState 设置为“最小化”在 XAML 中,然后在 ContentRendered 事件处理程序中将其设置为“正常”。尽管窗口本身的宽度大于应有的宽度,但这似乎部分有效。更糟糕的是,窗口中的内容似乎是根据窗口的正确大小呈现的,然后窗口在不重新呈现内容的情况下使自身变大。因此,内容不在窗口的中心,并且内容的右侧有一个令人讨厌的黑色矩形,它表示窗口的正确大小和当前(较大)大小之间的差异。当我通过抓住窗口边缘手动调整窗口大小时,内容会正确重新呈现,并且一切看起来都很好。但是如何在代码中强制进行这样的重新渲染呢? Window.UpdateLayout() 不起作用。

Ok, so I have a window that pops up (during normal operation of the program) at the user's request to display some context-specific information. This window happens to have a lot of elements in it, so it takes 0.5 - 1 sec to load. However, since I'm expecting this window to contain several different types of information depending on the context, it's content's width and height may vary. Thus I set the SizeToContent value to "WidthAndHeight" to allow the window to resize based on whatever content is bound to it.

However, since the window takes some time to load, the user first sees a small, square window and then the full-size window after everything renders. I would like to avoid having the user see the small window before it fully loads.

Is there any way to cause the window to only display AFTER it has rendered completely?

Things I've tried:

  • set the visibility of the window to "Hidden" and then set it to "Visible" in a ContentRendered event handler : the window never displayed.

  • set the opacity of the window to 0 and then set it to 1 in a ContentRendered event handler: the opacity of the content in the window itself is set to 0, then to 1.

Update : Another attempt

I have also tried to set Window.WindowState to "Minimized" in XAML and then set it to "Normal" in the ContentRendered event handler. This seems to work partially, though the width of the window itself is larger than it should be. Worse, it appears that the content in the window rendered according to the correct size for the window, and then the window made itself larger without re-rending the content. Thus, the content is not centered in the window and we have a nasty black rectangle to the right of the content that represents the difference between the correct size of the window and the current (larger) size. When I resize the window manually by grabbing the edge of the window, the content re-renders properly and everything looks fine. But how do I force such a re-rendering in code? Window.UpdateLayout() doesn't work.

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

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

发布评论

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

评论(3

格子衫的從容 2024-10-29 01:25:59

好的,我找到了一个有效的解决方案。不理想,但它有效。

首先,我在 XAML 中将 Window.WindowState 设置为“最小化”。这可以防止窗口在渲染时出现在屏幕上。然后,我订阅了窗口的 ContentRendered 事件,并在处理程序中添加了以下代码:

this.WindowState = System.Windows.WindowState.Normal;
this.MaxWidth = MainContentPresenter.ActualWidth;
this.Height = MainContentPresenter.ActualHeight;

this.InvalidateVisual();

其中 MainContentPresenter 是窗口的 ContentPresenter。 ViewModel 绑定到此元素,因此内容显示在那里。

Ok, I found a solution that works. Not ideal, but it works.

First I set Window.WindowState to "Minimized" in XAML. This prevents the window from appearing on the screen as it is rendering. Then I subscribed to the ContentRendered event for the window, and added the following code in the handler:

this.WindowState = System.Windows.WindowState.Normal;
this.MaxWidth = MainContentPresenter.ActualWidth;
this.Height = MainContentPresenter.ActualHeight;

this.InvalidateVisual();

where MainContentPresenter is the ContentPresenter for the window. The ViewModel is bound to this element, so the content appears there.

眼泪淡了忧伤 2024-10-29 01:25:59

请注意,您可以知道窗口需要什么大小的事件,而无需显示它。

如果您有一个控件想要知道它想要的大小,您可以执行以下操作

// I'm picking Button here, but any control could be put here, be it
// Window or whatever:

Button b = new Button();

// I'm putting some content to see that it actually measures it children. If you'll put more text here
// you'll see bigger size
b.Content = "Hello";

// I'm manually measuring the control, passing in double.PositiveInfinity so that the control
// would give me the size it wants, regardless of any constraints (you can put constraints here
// if you like)
b.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

// After Measure is called, the Property DesiredSize become relevant, and contains the size that the
// Control needs to show all of its contents.
MessageBox.Show(b.DesiredSize.ToString());

Note that you can know what size the window needs event without showing it at all.

if you have a control that you want to know the size that it wants, you can do the following

// I'm picking Button here, but any control could be put here, be it
// Window or whatever:

Button b = new Button();

// I'm putting some content to see that it actually measures it children. If you'll put more text here
// you'll see bigger size
b.Content = "Hello";

// I'm manually measuring the control, passing in double.PositiveInfinity so that the control
// would give me the size it wants, regardless of any constraints (you can put constraints here
// if you like)
b.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

// After Measure is called, the Property DesiredSize become relevant, and contains the size that the
// Control needs to show all of its contents.
MessageBox.Show(b.DesiredSize.ToString());
四叶草在未来唯美盛开 2024-10-29 01:25:59

好吧,我发现了我的错误。只要新窗口的 DataContext 在显示窗口之前设置为 WidthAndHeight,SizeToContent 设置为 WidthAndHeight 就可以正常工作。就像:

secondaryWindow.DataContext = viewModel;  

secondaryWindow.Show();

而不是:

secondaryWindow.Show();

secondaryWindow.DataContext = viewModel;  

像我一样。

因此,发生的情况是,在 DataContext 为 null 的情况下,窗口会适当调整大小,然后在设置 DataContext 时重新调整大小。

感谢 Elad Katz 添加了间接导致我发现此错误的解决方案。

Ok, I found my mistake. SizeToContent set to WidthAndHeight works just fine as long as the DataContext for the new window was set BEFORE you show the window. As in:

secondaryWindow.DataContext = viewModel;  

secondaryWindow.Show();

rather than:

secondaryWindow.Show();

secondaryWindow.DataContext = viewModel;  

like I had.

So what was happening was that the window was sizing appropriately in the case that the DataContext was null, and then re-sizing when the DataContext was set.

Kudos to Elad Katz for adding a solution that indirectly caused me to find this bug.

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