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

时间:2008-11-11 13:38:50

标签: c# winforms

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

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

这是显示问题的图片。我的用户控件在左侧,标准的datetimepicker在右侧:

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

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

谢谢!

5 个答案:

答案 0 :(得分:25)

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);
    }
}

用法:

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

答案 1 :(得分:3)

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

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

在单击之前显示一个空文本框,然后显示datetimepicker。

这样可以省去一大堆代码..

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

我不是百分百肯定,但快速查看Reflector上的DateTimePicker类会将我带到SafeNativeMethods.SetWindowPos内部类。

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

希望它有所帮助, Bruno Figueiredo

答案 4 :(得分:0)

您的控件被切断的原因是因为它是您所驻留表单的子控件。表格上的任何控制都必须包含在表格中,因此它会被切断。

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