.NET表单-设置位置改变大小
我正在开发一个应用程序,该应用程序将其表单显示为一系列彼此堆叠的模式窗口。所有表格都放置在屏幕中央。当用户在屏幕上移动表单时,只有最上面的表单会移动,其他表单则保留在中间,无法移动,因为它们被最上面的对话框挡住了。
我正在尝试编写一个表单移动代码,将所有表单移动到新位置,以及在当前非居中位置打开新表单的代码。
但在执行后者时会发生一些奇怪的事情 - 使用其他表单(最底部表单)的位置在非居中位置打开一个新表单。如果我以编程方式设置窗体的 Location 属性,其大小会发生变化 - 窗体会变小。其 Size 属性从 Designer GUI 中设置的 (240, 320) 更改为 Designer 生成的代码中存在的较小的 ClientSize (234, 294)。我只在网上找到一篇引用此问题的帖子,但没有答案。 如果我保留 Location 属性,则表单将以原始大小正确显示。
窗体的StartPosition设置为Manual,FormBorderStyle为FixedSingle,AutoScaleMode为DPI或Font(我不知道如何设置这个)。
有什么想法吗?谢谢。
I'm working on an app that shows its forms as a series of modal windows stacked on eachother. All forms are placed to the center of the screen. When the user moves the form around the screen, only the topmost one moves, others remain at the center and cannot be moved as they are blocked by the topmost dialog.
I'm trying to code a form-moving code that would move all the forms to the new location and also code that would open new forms at the current, non-centered location.
But something wierd happens when doing the latter - opening a new form in a non-centered position using Location of some other form (the bottom-most form). If I set the Location property of the form programatically, its size changes - the form gets smaller. Its Size property is changed from (240, 320), as set in the Designer GUI, to the smaller ClientSize (234, 294), which is present in the Designer-generated code. I've only found one post on the net referencing this problem, but no answers to it.
If I leave the Location property alone, the Form is displayed correctly with the original size.
The StartPosition of the form is set to Manual, FormBorderStyle is FixedSingle, AutoScaleMode is either DPI or Font (I don't know gow to set this one).
Any ideas? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我会回答我自己的问题。该行为似乎源于在操作系统尚未形成表单时设置 Location 属性,也就是说,它尚未创建句柄且其 IsHandleCreated 为 False。我已经调试了 .NET 代码本身,并且有一个 Debug.Assert 调用,其中包含“在 CreateHandle 之前不要使用它”或类似的内容,作为有问题的代码周围的调用堆栈上某处的断言参数。这给了我第一个提示。
将代码放入 Form.Load 事件的事件处理程序中解决了该问题。当 Load 触发时,句柄已经创建,并且一切似乎都正常工作。
现在我知道了原因,我在网上搜索了一些“构造函数与加载事件处理程序初始化”,相关讨论意味着您需要将控件的处理推迟到加载。这有点有意义,因为 .NET 控件是操作系统外部实体的包装器(并且需要创建这些实体才能使用),但同时没有意义,因为设计器代码似乎能够在句柄创建得很好。如果这有意义的话..
TLDR:推迟控件访问和使用,直到 Form.Load 事件触发。
I'll answer my own question. It seems that the behaviour stems from setting the Location property while the form is not yet formed by the OS, that is, it doesn't have a handle created yet and its IsHandleCreated is False. I've debugged into .NET code itself and there was a Debug.Assert call with "Do not use this before CreateHandle" or something like that as the assert parameter somewhere on the call stack around the code that was problematic. This gave me the first hint.
Putting the code into an event handler for the Form.Load event fixed the problem. At the time that Load fires, the handle is already created and everything seems to function.
Now that I know the cause, I've searched the net a bit for "Constructor vs. Load event handler initialization" and the relevant discussions imply that you need to defer handling of controls until Load. Which kinda makes sense because .NET controls are wrappers around entities outside in the OS (and those need to be created to be usable) but at the same time doesn't make sense because the Designer code seems to be able to access controls before the handle is created just fine. If that makes any sense..
TLDR: defer control access and use until Form.Load event fires.