Сделайте так, чтобы пользовательский элемент управления отображался за пределами формы - PullRequest
13 голосов
/ 11 ноября 2008

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

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

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

альтернативный текст http://img50.imageshack.us/img50/9104/datetimepickervu6.jpg

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

Спасибо!

Ответы [ 5 ]

25 голосов
/ 12 ноября 2008

Элемент управления 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();
3 голосов
/ 11 ноября 2008

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

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

Показывать пустое текстовое поле до тех пор, пока оно не будет щелкнуто, а затем отобразить указатель даты и времени.

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

2 голосов
/ 11 ноября 2008

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

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

1 голос
/ 11 ноября 2008

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

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

Надеюсь, это поможет, Bruno Figueiredo

0 голосов
/ 11 ноября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...