C# 使用户控件显示在表单边界之外

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/280891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 21:26:35  来源:igfitidea点击:

Make user control display outside of form boundry

c#winforms

提问by Danny Frencham

I've decided to reimplement the datetime picker, as a standard datetime picker isn't nullable. The user wants to start with a blank field and type (not select) the date.

我决定重新实现日期时间选择器,因为标准日期时间选择器不可为空。用户想要从一个空白字段开始并键入(而不是选择)日期。

I've created a user control to do just that, but if the user control is near the edge of the form, it will be cut off on the form boundry. The standard datetime picker doesn't suffer from this problem.

我已经创建了一个用户控件来做到这一点,但是如果用户控件靠近窗体的边缘,它将在窗体边界上被切断。标准的日期时间选择器不会遇到这个问题。

Here is a picture showing the problem. My user control is on the left, the standard datetimepicker is on the right:

这是显示问题的图片。我的用户控件在左侧,标准日期时间选择器在右侧:

alt text http://img50.imageshack.us/img50/9104/datetimepickervu6.jpg

替代文字 http://img50.imageshack.us/img50/9104/datetimepickervu6.jpg

As you can see, the standard control will display over the form AND application boundry. How do I get the month picker in my control to do the same thing?

如您所见,标准控件将显示在表单和应用程序边界上。如何让我控制的月份选择器做同样的事情?

Thanks!

谢谢!

采纳答案by Jesper Palm

The ToolStripDropDown control has this functionallity so by inheriting from it we can make a simple PopupWindow.

ToolStripDropDown 控件具有此功能,因此通过继承它,我们可以制作一个简单的 PopupWindow。

/// <summary>
/// A simple popup window that can host any System.Windows.Forms.Control
/// </summary>
public class PopupWindow : System.Windows.Forms.ToolStripDropDown
{
    private System.Windows.Forms.Control _content;
    private System.Windows.Forms.ToolStripControlHost _host;

    public PopupWindow(System.Windows.Forms.Control content)
    {
        //Basic setup...
        this.AutoSize = false;
        this.DoubleBuffered = true;
        this.ResizeRedraw = true;

        this._content = content;
        this._host = new System.Windows.Forms.ToolStripControlHost(content);

        //Positioning and Sizing
        this.MinimumSize = content.MinimumSize;
        this.MaximumSize = content.Size;
        this.Size = content.Size;
        content.Location = Point.Empty;

        //Add the host to the list
        this.Items.Add(this._host);
    }
}

Usage:

用法:

PopupWindow popup = new PopupWindow(MyControlToHost);
popup.Show(new Point(100,100));
...
popup.Close();

回答by Tigraine

The screenshots looks like a Windows Forms applications, so my answer is for winforms.

屏幕截图看起来像 Windows 窗体应用程序,所以我的答案是针对 winforms。

I guess the best solution would be to create a customcontrol that itself uses the datetime picker that already has the behavior.

我想最好的解决方案是创建一个自定义控件,它本身使用已经具有该行为的日期时间选择器。

Show a empty textbox until it gets clicked, then display the datetimepicker.

显示一个空文本框,直到它被点击,然后显示日期时间选择器。

That would save you a bunch of code..

这将为您节省一堆代码..

回答by Bruno Shine

I'm not 100% sure, but a quick look at the DateTimePicker class on Reflector takes me to the SafeNativeMethods.SetWindowPosinternal class.

我不是 100% 确定,但快速浏览 Reflector 上的 DateTimePicker 类会将我带到SafeNativeMethods.SetWindowPos内部类。

You can override the SetBoundsCorefrom the base Control class or, like Tigraine stated, create a custom control based on the DateTimePicker.

您可以覆盖SetBoundsCore基本 Control 类中的 ,或者像 Tigraine 所说的那样,基于 DateTimePicker 创建自定义控件。

Hope it helps, Bruno Figueiredo

希望它有所帮助,布鲁诺·菲格雷多

回答by Robert Rossney

I ran into this when trying to implement a custom control and discovered that it's a remarkably hard problem. There's no built-in functionality within the Windows.Formsmodel to support controls whose display area extends outside the client area of their container.

我在尝试实现自定义控件时遇到了这个问题,并发现这是一个非常困难的问题。Windows.Forms模型中没有内置功能来支持其显示区域扩展到其容器客户区之外的控件。

You basically have to either use the Windows API or draw your controls inside a Form with AlwaysOnTop set. Both approaches are harder than they should be. I ended up redesigning my control so that instead of displaying its expanded contents in a dropdown it used a modal dialog. This was a pretty unsatisfying solution, but I spent a couple of weeks trying other approaches and could never get anything that worked consistently across all use cases (like disappearing when the application loses focus).

您基本上必须使用 Windows API 或在设置了 AlwaysOnTop 的 Form 中绘制控件。这两种方法都比应有的困难。我最终重新设计了我的控件,以便它使用模式对话框而不是在下拉列表中显示其展开的内容。这是一个非常不令人满意的解决方案,但我花了几个星期尝试其他方法,但永远无法获得在所有用例中都能一致工作的任何东西(例如在应用程序失去焦点时消失)。

回答by Dan R

The reason that your control gets chopped off is because it is a child control of the form that you reside on. Any control on the form must be contained by the form, hence it gets chopped off.

您的控件被切断的原因是因为它是您所在窗体的子控件。窗体上的任何控件都必须包含在窗体中,因此它会被砍掉。

I haven't done this in .Net, but had a similar problem in VB6. The solution then was to set the parent of the popup window (the calendar in your case) to be the desktop. This will allow it to extend beyond the boundaries of your form. You'll have to do some P/Invoke magic to find the hWnd of the popup, and another P/Invoke to set the parent.

我没有在 .Net 中做过这个,但在 VB6 中也有类似的问题。然后解决方案是将弹出窗口的父级(在您的情况下为日历)设置为桌面。这将允许它超出表单的边界。您必须执行一些 P/Invoke 魔术才能找到弹出窗口的 hWnd,并使用另一个 P/Invoke 来设置父级。