2008-11-11 4 views
10

Postanowiłem ponownie wdrożyć selektor datetime, ponieważ standardowy selektor datetime nie jest zerowalny. Użytkownik chce rozpocząć od pustego pola i wpisać (nie wybrać) datę.Ustaw wyświetlanie kontrolki użytkownika poza granicę formularza

Stworzyłem kontrolę użytkownika, aby to zrobić, ale jeśli kontrola użytkownika znajduje się w pobliżu krawędzi formularza, zostanie odcięta na granicy formularza. Standardowy selektor datetime nie cierpi z powodu tego problemu.

Oto zdjęcie przedstawiające problem. Moja kontrola użytkownika jest po lewej stronie, a średnia DateTimePicker jest po prawej stronie:

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

Jak widać, standard sterowania zostanie wyświetlony nad formą i stosowania boundry. Jak uzyskać kontrolę nad miesiącem, aby zrobić to samo?

Dzięki!

+0

wygląd ekranu, które pracują w winform nie ASP.net jako tag powiedzieć? Normalna? –

+0

Tak, mój tag był nieprawidłowy. Potrzebuję kolejnej Coke, jak sądzę. :) –

+0

Och, więc ludzie * robią * używają IE :) – Dan

Odpowiedz

24

Kontrolka ToolStripDropDown ma tę funkcjonalność, więc dziedzicząc z niej możemy stworzyć proste okno 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); 
    } 
} 

Zastosowanie:

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

Holy crap, ten kod jest najbardziej niesamowitym kodem w historii. Integruję to z moją kontrolą użytkownika, dzięki. –

+2

Mam to działa. Czy mimo to można usunąć granicę? –

+2

Zaimplementowałem ten kod, ale wyskakujące okienko nadal kradnie fokus. Czy istnieje sposób, aby temu zapobiec? – jblaske

3

Zrzuty ekranu wyglądają jak aplikacje Windows Forms, więc moja odpowiedź dotyczy winform.

Domyślam się, że najlepszym rozwiązaniem byłoby stworzenie niestandardowego kontrolka, która sama używa próbnika datetime, który już ma zachowanie.

Pokaż puste pole tekstowe, aż zostanie kliknięte, a następnie wyświetl metrykę danych.

że można zaoszczędzić sporo kodu ..

+0

To jest dobra sugestia, dam to spróbować jutro. Wciąż chcę wiedzieć, czy istnieje sposób, aby odpowiedzieć na moje oryginalne pytanie! :) –

+0

Ta niestandardowa kontrola powinna załatwić sprawę: http://www.codeguru.com/csharp/csharp/cs_controls/custom/article.php/c9645 –

+0

Okazało się, że nie mogłem zejść tą drogą. Zacząłem od powyższej kontroli, ale nie ma sposobu na ustawienie kontroli, aby użytkownik mógł się do niej przyłączyć i zacząć pisać - ważną funkcję dla użytkownika, dla którego piszę. –

1

nie jestem w 100% pewien, ale szybkie spojrzenie na klasy DateTimePicker reflektorem zabiera mnie do klasy wewnętrznej SafeNativeMethods.SetWindowPos.

Można zastąpić SetBoundsCore z podstawowej klasy kontrolnej lub, jak podano w Tigraine, utworzyć niestandardowy formant oparty na narzędziu DateTimePicker.

Nadzieja pomaga, Bruno Figueiredo

2

wpadłem na to, próbując wdrożyć kontrolę niestandardowy i odkrył, że jest to niezwykle trudny problem. W modelu Windows.Forms nie ma wbudowanych funkcji obsługujących formanty, których obszar wyświetlania rozciąga się poza obszarem roboczym kontenera.

Zasadniczo musisz użyć interfejsu API systemu Windows lub narysować kontrolki wewnątrz formularza z zestawem AlwaysOnTop. Oba podejścia są trudniejsze, niż powinny być. Skończyło się na przeprojektowaniu kontrolki, więc zamiast wyświetlać jej rozwiniętą zawartość w rozwijanym menu, korzystałem z modalnego okna dialogowego. To było dość niesatysfakcjonujące rozwiązanie, ale spędziłem kilka tygodni próbując innych podejść i nigdy nie mogłem uzyskać niczego, co działałoby konsekwentnie we wszystkich przypadkach użycia (np. Znikanie, gdy aplikacja traci koncentrację).

0

Powodem, dla którego kontrola zostaje odcięta, jest kontrola podrzędna formularza, w którym przebywasz. Każda kontrola w formularzu musi być zawarta w formularzu, dlatego zostaje odcięta.

Nie zrobiłem tego w .Net, ale miałem podobny problem w VB6. Rozwiązaniem było ustawienie rodzica okna wyskakującego (kalendarza w twoim przypadku) na pulpit. Pozwoli to na przekroczenie granic twojego formularza. Będziesz musiał wykonać trochę magii P/Invoke, aby znaleźć hWnd wyskakującego okienka i kolejne P/Invoke, aby ustawić rodzica.