[C#] Dostęp z wątku do kontrolek


(Marcin Obala) #1

Witam

Ogólnie rzecz biorąc wiem jak zmodyfikować kontrolkę z wątku. Jednak jest pewien problem. Chciałbym dużo rzeczy robić a tym samym robię aktualnie kilka funkcji.

Osobna funkcja dla Items.Clear. Osobna dla items.Add, AddRange. A czy mogę w jakiś bardziej uniwersalny sposób zrobić funkcję np. jak ta

public void CheckBoxComboBox_Items_AddRange(CheckBoxComboBox c, object[] array)

{

    if (InvokeRequired)

        this.Invoke(new Action(CheckBoxComboBox_Items_AddRange), new object[] { c, array });

    else

        c.Items.AddRange(array);

}

Ale żebym przesyłał do funkcji że chcę zrobić AddRange i w kodzie będzie AddRange. Chcę Items.Clear to będzie Items.Clear bez osobnych funkcji lub bez switcha w jednej funkcji.


(mr-owl) #2

Witam,

A to nie jest tak że modyfikujesz kolekcje w programie i wykonujesz instrukcje która przeniesie zmiany na UI? Przechowywanie danych bezpośrednio w kontrolkach to chyba taki sobie pomysł.

Pozdrawiam,

mr-owl


(ptaku82) #3

użyj rozszerzeń (extensions method), dodaj do projektu:

public static class ControlExtensions

    {

        public static void InvokeIfRequired(this Control control, Action action)

        {

            if (control.InvokeRequired)

                control.Invoke(action);

            else

                action();

        }

        public static void InvokeIfRequired(this Control control, Action action, T parameter)

        {

            if (control.InvokeRequired)

                control.Invoke(action, parameter);

            else

                action(parameter);

        }

    }

dzięki czemu każda kontrolka będzie miała dostęp do metody InvokeIfRequired i nie będzie problemu z jej aktualizacją z innego wątku: przykład użycia:

this.InvokeIfRequired((value) => progressBar.Value = value, 10);

Więcej na: http://msdn.microsoft.com/pl-pl/library/dobre-i-zle-praktyki-w-c-sharp–czesc-2.aspx


(Marcin Obala) #4

Chodzi o inicjalizację. Używam kontrolki CheckBoxComboBox. I właśnie tworzę listę w programie a następnie dodaje tą listę do Itemsów i CheckBox Itemsów przez AddRange. Dodatkowo dodaję ręcznie przez Add kolejny element “Select All” który sam programuje że jeśli zaznaczony to ma się wyświetlić tylko on a nie lista wszystkich zaznaczonych, dodatkowo domyślnie zaznaczam ten element więc muszę wykonać CheckBoxItems[0].Checked = true;. Tylko że to do każdej operacji mam osobną funkcję. Osobna funkcja z Invoke dla AddRange, dla Add, dla Items.Clear(), dla CheckboxItems.Clear(), dla .Checked. I Pytam czy nie można zrobić tego jakoś z automatu.


(mr-owl) #5

Witam,

Pytanie jeszcze jest czy aplikacja jest w WPF czy w WinForms?

Pozdrawiam,

mr-owl


(Marcin Obala) #6

Winforms. Kolega wyżej podał już fajne rozwiązanie.