2011-12-16 17 views
7

Cóż, piszę plik rozszerzeń/metody użyteczny dla łańcuchów, etykiet, linków, klas itp.jak korzystać z metody Invoke w pliku rozszerzeń/metod?

ale mam problem. Mam metodę showMessage(), która zmienia tekst etykiety, działa poprawnie. Ale ja decyduję zrobić współpracuje z wykonania gwintu, a następnie zrobić to:

namespace LabelExtensions 
{ 
    public static class LabelExtensionsClass 
    {   
     private delegate void UpdateState(); 

     public static void ShowMessage(this Label label, string text) 
     { 
      if (label.InvokeRequired) 
      { 
       label.Invoke((UpdateState)delegate 
       { 
        label.Text = text; 
       }); 
      } 
      else 
      { 
        label.Text = text; 
      } 
     } 
} 
} 

przykro, to była literówka. Napisałem ten kod na forum. błąd jest kontynuowany.

zgodnie z documentation, aby użyć metody konieczność importu Invoke:

Przestrzeń nazw: System.Windows.Forms

Montaż: System.Windows.Forms (w System.Windows.Forms .dll)

następnie zrobiłem:

using System.Windows.Forms; 

, ale to zwraca ten sam błąd:

The name 'Invoke' does not exist in the current context 

jak to naprawić?

Z góry dziękuję.

+0

Możesz użyć istniejącego delegata "Działanie"; nie musisz tworzyć własnego. – SLaks

+0

Może, '(label.TopLevelControl as Form) .Invoke' – Joe

+0

@SLaks: Thanks :) –

Odpowiedz

8

Dlaczego nie po prostu to zrobić:

label.BeginInvoke((Action) (() => label.Text = text)); 

Nie ma potrzeby, aby stworzyć swój własny delegata. Po prostu użyj wbudowanego delegata Action. Prawdopodobnie powinieneś utworzyć metodę rozszerzenia dla klasy podstawowej Control zamiast klasy Label. Będzie bardziej nadaje się do ponownego użycia.

1

Zapomniałeś określić etykietę w kodzie (po wywołaniu metody Invoke):

public static void ShowMessage(this Label label, string text) 
     { 
      if (label.InvokeRequired) 
      { 
       lablel.Invoke((UpdateState)delegate 
       { 
        label.Text = text; 
       }); 
      } 
      else 
      { 
        label.Text = text; 
      } 
     } 

również rozważyć użycie BeginInvoke zamiast więc nie będzie blokować wywołującego wątku (jeśli dotyczy)

3

Zmień

Invoke((UpdateState)delegate … 

do

label.Invoke((UpdateState)delegate … 
+0

Dokładnie. Wymagana metoda "Invoke" jest członkiem klasy System.Windows.Forms.Control, z której wywodzi się Label. Twoja statyczna klasa LabelExtensions nie ma metody "Invoke". – KeithS

+0

Przepraszam, to był błąd. :( –

1

Invoke to metoda instancji z Control.
Potrzebujesz numeru Control, aby go wywołać, na przykład label.

+0

Przepraszam, to był literówka. :( –

+0

@ TheMask: Czy to działa? – SLaks

1

Nie musisz zadeklarować nowego typu delegata ani skonstruować nowego lambda lub anonimowego delegata. Masz już metodę, która działa w wątku UI - tym, który piszesz. Po prostu spraw, aby w razie potrzeby wywoływał się w wątku UI, tak jak to.

public static void ShowMessage(this Label label, string text) { 

    if(label.InvokeRequired) { 
     label.Invoke(new Action<Label, string>(ShowMessage), label, text); 
     return; 
    } 

    label.Text = text; 
} 

Zaletą tego podejścia jest to, że można niemal skopiować i wkleić blok kodu przekierowanie z tej metody do jakiejkolwiek innej metody, które chcesz zmodyfikować w taki sam sposób.