2010-02-26 10 views
5

przy użyciu C# WinForm VS2008Jak zatrzymać zdarzenie urlopu tekstowe wypalania na formularzu blisko

Mam pole tekstowe na formularzu z metodą jest wywoływana z imprezy textBox1_Leave. Metoda pobiera zawartość danego pola tekstowego i wypełnia inne pola tekstowe na podstawie zawartości. Mój problem polega na tym, że użytkownik skupił się na polu tekstowym, a następnie klika przycisk, aby zamknąć formularz (wywołanie this.close), a następnie formularz nie zamyka się, ponieważ wydarzenie zostanie wywołane. Jeśli pole tekstowe nie ma fokusu na formularzu, oznacza to, że formularz zamyka się prawidłowo.

Jeśli jednak użytkownik zamknie formularz, klikając małą ikonę zamknięcia X w górnym rogu, zamyka się dobrze cały czas bez wywoływania zdarzenia opuszczania pola tekstowego.

Jak mogę zduplikować funkcję zamykania X, aby zawsze można zamknąć formularz bez wywoływania zdarzenia textbox?

+0

Działa to dla mnie świetnie. http://stackoverflow.com/questions/2664639/cancel-leave-event-when-closing –

Odpowiedz

7

Najprostszym rozwiązaniem będzie sprawdzić, które kontrolują rzeczywiście koncentruje się przed robi swoje post-processing - ale nie można tego zrobić w programie obsługi Leave, ponieważ nacisk nadal będzie na polu tekstowym w tym momencie.

Zamiast tego należy przenieść logikę do zdarzenia LostFocus, którego nie ma w projektancie. musisz podłączyć go przy starcie:

public class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     textBox1.LostFocus += new EventHandler(textBox1_LostFocus); 
    } 

    private void textBox1_LostFocus(object sender, EventArgs e) 
    { 
     if (closeButton.Focused) 
      return; 
     // Update the other text boxes here 
    } 
} 

Impreza LostFocus dzieje na ogień po nowa sterująca otrzymuje się skupić.

Wyjaśnienie - ty może uważają, że działa poprzez umieszczenie tej logiki w przypadku Leave - jeśli ostrość jest zmieniana przez myszy. Jeśli zamiast tego użyjesz klawiatury, otrzymasz złe zachowanie. LostFocus jest niezawodny w przypadku obu przypadków - kontrola skupiona będzie zawsze zawsze być "nowy" kontroli. Jest to udokumentowane w witrynie MSDN: Order of Events in Windows Forms.

Nawiasem mówiąc, powodem, dla którego nie występuje ten problem z "czerwonym X" jest to, że X nie jest w rzeczywistości formantem, który może otrzymać fokus, jest częścią okna. Kiedy użytkownik kliknie, nie powoduje to utraty ostrości pola tekstowego i dlatego nie powoduje wywołania zdarzenia Leave.

+0

Nie zgadzam się z komentarzem na temat "Pozostawić", podając nieprawidłowe zachowanie, patrz - http://msdn.microsoft.com/en-us/library/system.windows.forms.control.leave.aspx (nawiasem mówiąc zmieniony parametr jest zmieniony zanim kontrola odbierająca wywoła "Enter", która jest pierwsza w kolejności zdarzeń). –

+0

W zależności od wymaganej funkcjonalności problem z tym podejściem może być również problemem. Jeśli przycisk zamykania jest następny w kolejności tabulacji po polu tekstowym, a użytkownik naciśnie klawisz TAB, aby opuścić pole tekstowe, spowoduje to, że aktualizacje będą zachowane, nawet jeśli powinny. –

+0

Zaryzykuję w ten sposób i zobacz, jak to jest dziękuję wszystkim za wejście – Spooky2010

0

możesz sprawdzić, która kontrola została właśnie ustawiona.

private void textBox1_Leave(object sender, EventArgs e) 
{ 
    if (btnClose.Focused) 
     return; 
    // go from here 
} 
+0

Jesteś blisko - ale fokus jeszcze się nie zmienił w wydarzeniu "Leave". – Aaronaught

2

Inne podejście: Użyj zdarzenia sprawdzania poprawności w polu tekstowym zamiast zdarzenia urlopu, a następnie zmień właściwość CausesValidation przycisku na wartość false. Musisz także ustawić pole tekstowe tak, aby nie powodowało walidacji w zdarzeniu kliknięcia przycisku, aby zdarzenie sprawdzania poprawności nie uruchomiło się po zamknięciu formularza (dzięki @Powerlord za wskazanie tego).

private void button1_Click(object sender, EventArgs e) 
{ 
    this.textBox1.CausesValidation = false; 
    this.Close(); 
} 
1

Można również obsługiwać zdarzenia FormClosing i upewnij się, że argumentem e.Cancel nie zostanie ustawiony na true potwierdzanie zdarzeń na innych formantów na formularzu. Myślę, że zostaną wystrzeleni przed wydarzeniem FormClosing.

private void MainForm_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      if (e.CloseReason == CloseReason.UserClosing) 
      { 
       e.Cancel = false; 
       return; 
      } 
     } 
+0

Czyste podejście, jak to^_ ^ – chad

0

Wystarczy sprawdzić, czy formularz będący właścicielem pola tekstowego jest przeznaczony? Jeśli się zamyka, to się pozbywa. Jeśli się pozbywasz, możesz po prostu zakończyć brzydkie wydarzenie "zostaw" bez robienia czegokolwiek. Nie sprawdziłem tego i nie wybacz, jestem zdławiony z własnego projektu, więc szukałem siebie, więc nie sądzę, że będę miał na to czas.

private void GuiltyTextBox_Leave(object sender, EventArgs e) { 
    Form formOwningTheTextBox=(Form)((Control)sender).TopLevelControl; 
    if (formOwningTheTextBox.Disposing || formOwningTheTextBox.IsDisposed) return; 
    ....... 
} 

Po prostu uważam, że to będzie działać przy minimalnym wysiłku i chciałem wysłać szybką odpowiedź, zanim przejdę do szukania własnej odpowiedzi.

0

zapis następujący wiersz kodu w przypadku tekstu należy pozostawić pole na górze

if me.closing then 
return 
end if 
Powiązane problemy