Odwoływanie się do obiektu w zdarzeniu - pytanie.

0

Mam wyświetlonego PictureBox-a z pętli (tworzone dynamicznie) i do niego zdarzenie onclick .
Do kazdego PictureBoxa jest podpiete zdarzenie onclick.
Jak teraz w tym zdarzeniu odwolac sie do pictureboxa ktory to zdarzenei wywolal? Wiem ze to bedzie cos z obiektem seder.

Johny pomóż :-)

0

No właśnie obiekt sender to jest ten PictureBox! Tylko najpierw przeprowadź rzutowanie:

PictureBox pb = (PictureBox)sender;

0

Dzieki, a jescze trakie pytanie, mam 2 zdarzenia:

obrazki[j].MouseLeave += new EventHandler(Odznaczenie);
obrazki[j].MouseEnter+= new EventHandler(Zaznaczenie);

i obsługa:

void Zaznaczenie(object sender, EventArgs args)
        {
            PictureBox objekt =(PictureBox)sender;
            objekt.BorderStyle = BorderStyle.Fixed3D;
        }

        void Odznaczenie(object sender, EventArgs args)
        {
            PictureBox objekt = (PictureBox)sender;
            objekt.BorderStyle = BorderStyle.None;           
        }

Ale nie zawsze po opuszczeniu foty ramka znika , czy faktycznie tu trzeba uzyc MouseEEnter i MouseLeave ?

0

Czasem jest tak, ze jak szybko ruszysz myszka, to jedno zdarzenie zostanie zauwazone, a drugie juz nie. Zreszta sprawdz to u siebie - jak najezdzasz i zjezdzasz powoli to zazwyczaj wszystko jest ok, a jak szybko to sie chrzani. W takim wypadku musialbys lekko usprawnic takie zdarzenie, np. poprzez wlasna implementacje tego zdarzenia (watek sprawdzajacy czy myszka jest na pictureboxie + flaga, czy sprawdzanie ma sens, itp) - nie jest to takie trudne.

0

Znowu mam ten sam problem, jak to poprawić ?
Mogę prosić o więcej szczegółów?

Wstawilem sobie int-y do srodka i z tego wynika ze raz nie dziala Leave a nieraz Enter.
Wiadomo ze nikt nie bedzie specjalnie szybko smigał myszka ale nawet jak normalnie sie wybiera zdjecia nie zawsze zaskakuje.

0

Ja zrobilbym to raczej tak:

  • watek, ktory raz na jakis czas sprawdza czy myszka jest na danym picturebox'ie (i np. przelatuje liste wszystkich)
  • kazdy picturebox ma flage MouseOver
  • sprawdzanie polega na takiej metodzie:
    • jezeli myszka jest na pictureBox i MouseOver == true lub myszka poza i MouseOver == false, to koncze dzialanie sprawdzania (bo nie ma co robic)
    • jezeli myszka jest na pictureBox i mouseOver == false, to zmieniam flage i wywoluje odpowiednia reakcje (czyli np. zapalenie ramki)
    • jezeli myszka poza pictureBox i mouseOver == true, to zmieniam flage i wywoluje odpowiednia reakcje (czyli np. zgaszenie ramki).

Tak naprawde to wlasna implementacja zdarzen - implementacja wlasciwa wyglada bardzo podobnie, ale w tym wypadku najwyrazniej jest troche gorsza. Ta implementacja ma ta zalete, ze nie meczy tak bardzo kompa, bo w wiekszosci wypadkow wychodzi z metody zaraz na poczatku. Do tego ZAWSZE zauwazy, ze myszka opuscila/weszla na dany region.

0

z mouse enter/mouse leave nie trzeba robic wlasnych flag. to sa pochodne zdarzenia mouse move i eventy te powinny byc generowanie dla odwiedzanych/opuszczanych kontrolek przy kazdym poruszeniu myszka, tzn. nawet jak w danej chwili mouseleave nie zostanie zauwazony i mysz bardzo szybkim ruchem wyjedzie poza kontrolke, to zostanie to nadrobione w momencie gdy kursor przesunie sie o nastepny pixele, a ju zna pewno gdy najezdie na inna kontrolke - bo wtedy ona musi dostac mouse enter i system sprawdzi czy nie trzeba wykonac mouse leave na poprzedniej.. tak to przynajmniej z moich obserwacji w .NET2.0 wygladalo. kilkanascie razy rzeczywiscie widzialem ze event byl permanentnie opuszczany, ale za kazdym razem to byl jakis moj blad gdzies w kodzie zajmujacym sie dynamicznym podpinaniem/odpinaniem handlerow

0

bo wtedy ona musi dostac mouse enter i system sprawdzi czy nie trzeba wykonac mouse leave na poprzedniej..

A jak sie odwolac do kontrolki poprzedniej?
Poprzedniej w rozumieniu najechania myszką na nią, czyli mam np 2 wiersze obrazkow i najezdzam z gory na nr 3 i dalej w dol na nr 7 jak sie dostac do kontrolki nr 3 z kontrolki nr 7 ?

0

niestety, to system sobie sam trzyma i chyba Ci nie podaje w zaden sposob.. ale glowy nie dam, nie pamietam.

jesli rzeczywiscie jest jak teraz napisalem, to najprawdopodobniej musialbys sobie zapamietywac w obsludze zdarzenia mouseenter aktualna kontrolke i wtedy az do kolejnego mouseenter i wpisania nowej mialbys tam stara..

0
johny_bravo napisał(a)

Ja zrobilbym to raczej tak:

  • watek, ktory raz na jakis czas sprawdza czy myszka jest na danym picturebox'ie (i np. przelatuje liste wszystkich)
  • kazdy picturebox ma flage MouseOver
  • sprawdzanie polega na takiej metodzie:
    ...

Jezeli za kazdym razem bede przelatywal wszystkie komponenty to bede mial efekt mrugania, ale tak sobie mysle teraz , mam chyba prostrzy pomysl, nie potrzeba obslugiwac dwoch zdarzeń w sumie , jezeli bysmy w jakis sposob potrafili sie odwolac do poprzedniego kompoinentu to moznaby uzyc tylko zdarzenie MouseEnter i w nim zapalc obramowanie i gasic z poprzedniego komponentu. I po sprawie tylko wlasnie jak uchwycic ktory komponent byl wczesniej przelatywany przez myszke :-)

0

Mozesz tez gasic po prostu wszystkie pozostale. Jezeli 95% jest zgaszonych, to komp sie nie zmeczy za wiele, bo w 95% nic robil nie bedzie. Albo zapamietuj tak jak napisal quetzalcoatl.

0

Sytuacja wyglada tak ze w petli mozna przeleciec wszystkie komponenty, a nie da sie odwolac do komponentow w jakis wyrywkowy sposob ? Ze np jadac myszka nad nimi ustawiam jakikes tam id kolejne, np przesuwam kursor nad pierwszym id ustawiam na 1 , pozniej wchodze na komponent drugi ustawiam na 2 i autoamtycznie komponent[1] = obramowanie brak ?

0

No mozesz przeciez zrobic sobie skladowa, ktora zapamieta ostatni z zapalona ramka i podmieniac przy kolejnym zdarzeniu tego typu.

0
johny_bravo napisał(a)

No mozesz przeciez zrobic sobie skladowa, ktora zapamieta ostatni z zapalona ramka i podmieniac przy kolejnym zdarzeniu tego typu.

Co rozumiesz przez slowo zapamieta, jak wrzucic do tablicy indeks kontrolki ? Bo normalnie jezeli np na panelu mam 15 kontrolek to odwolujesz sie do nich przez kontrolka[indeks] i teraz jak wylowic ten indeks i zapisac do tablicy ?

Dobra zrobilem takie zdarzenie Mouse_Enter:

ArrayList lista = new ArrayList();
        private void Najechanie(object sender, EventArgs e)
        {
            int indeks;
           PictureBox o = (PictureBox)sender;

     
            lista.Add(splitContainer1.Panel2.Controls.IndexOf(o));
            o.BorderStyle = BorderStyle.FixedSingle;
            if (lista.Count > 1)
            {
                indeks = (int)lista[lista.Count - 2];
                           
                PictureBox o1 = (PictureBox)splitContainer1.Panel2.Controls[indeks];
                o1.BorderStyle = BorderStyle.None;
            }
           
        }

Zapisuje sobie id kontrolki do tablicy, zaznaczam aktualna kontrolke i jezeli tablica ma wiecej niz 1 element(bo dla pierwszego elementu nie ma sensu gasic poprzedniego bo go nie ma) wtedy gasze kontrolke poprzednia, indeksy mam w tablicy i pozniej sie tylko do kontrolek odwoluje.
Jedyny minus tej metody jest taki ze zaznaczenie nigdy nie zniknie tzn zawsze bedzie jakas kontrolka z borderem ale mi to nie przeszkadza.
Takze dziala
Dzieki za pomoc.

0

Zapamietaj referencje do obiektu, niekoniecznie indeks, np. tak:

private void zdarzenie(object sender, EventArgs eventArgs) { ((MyPictureBox)last).turnOff(); last = sender; ((MyPictureBox)last).turnOn(); } ```

Jezeli koniecznei chcesz indeks, to przechowuj go we wlasciwosci Tag picturebox'a.

0
johny_bravo napisał(a)

Zapamietaj referencje do obiektu, niekoniecznie indeks, np. tak:

private void zdarzenie(object sender, EventArgs eventArgs)
{
((MyPictureBox)last).turnOff();
last = sender;
((MyPictureBox)last).turnOn();
}

> 
> Jezeli koniecznei chcesz indeks, to przechowuj go we wlasciwosci Tag picturebox'a.


Moje kontroli tworza sie tak PictureBox - > Label ->PictureBox -> label czyli nie moge gasic poprzedniej bo wtedy zgasnie mi label , zrobilem to tak jak napisalem przed Twoim postem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1