Сделать отображение пользовательского контроля вне рамки рамки

Я решил переопределить сборщик datetime, поскольку стандартный сборщик datetime не имеет значения NULL. Пользователь хочет начать с пустого поля и ввести (не выбирать) дату.

Я создал пользовательский элемент управления, чтобы сделать это, но если пользовательский элемент управления находится рядом с краем формы, он будет обрезаться на границе формы. Стандартная сборщик данных и времени не страдает от этой проблемы.

Вот изображение, показывающее проблему. Мой пользовательский элемент управления находится слева, стандартный datetimepicker находится справа:

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

Как вы можете видеть, стандартный элемент управления будет отображаться над границей формы AND. Как я могу сделать сборщик месяцев в моем контроле, чтобы сделать то же самое?

Спасибо!

Ответ 1

Элемент управления 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();

Ответ 2

Скриншоты выглядят как приложения Windows Forms, поэтому я отвечаю за winforms.

Я думаю, лучшим решением было бы создать настраиваемый элемент управления, который сам использует сборщик datetime, который уже имеет поведение.

Показывать пустое текстовое поле до щелчка, а затем отображать datetimepicker.

Это сэкономит вам кучу кода.

Ответ 3

Я столкнулся с этим при попытке реализовать пользовательский элемент управления и обнаружил, что это очень сложная проблема. Внутри модели Windows.Forms нет встроенных функций для поддержки элементов управления, область отображения которых выходит за пределы клиентской области своего контейнера.

В основном вам нужно либо использовать Windows API, либо использовать элементы управления внутри формы с AlwaysOnTop. Оба подхода сложнее, чем они должны быть. Я закончил переориентировать мой контроль, чтобы вместо отображения его расширенного содержимого в выпадающем меню использовался модальный диалог. Это было довольно неудовлетворительное решение, но я потратил пару недель на проработку других подходов и никогда не мог получить ничего, что бы последовательно работало во всех случаях использования (например, исчезновение, когда приложение теряет фокус).

Ответ 4

Я не уверен на 100%, но быстрый взгляд на класс DateTimePicker на Reflector приводит меня к внутреннему классу SafeNativeMethods.SetWindowPos.

Вы можете переопределить SetBoundsCore из базового класса Control или, как указано в Tigraine, создать настраиваемый элемент управления на основе DateTimePicker.

Надеюсь, что это поможет, Бруно Фигейредо [/p >

Ответ 5

Причина, по которой ваш контроль прерывается, заключается в том, что он является дочерним элементом формы, в которой вы находитесь. Любое управление формой должно содержаться в форме, поэтому оно отрубается.

Я не делал этого в .Net, но имел аналогичную проблему в VB6. Затем решение заключалось в том, чтобы установить родительский элемент всплывающего окна (календарь в вашем случае) на рабочий стол. Это позволит выйти за пределы вашей формы. Вам нужно будет сделать магию P/Invoke, чтобы найти hWnd всплывающего окна, а другой P/Invoke - установить родительский элемент.