[C#] Dostęp do kontrolki z metody w klasie abstrakcyjnej


(Gkuczmik89) #1

Witam !

Piszę aplikację implementującą algorytmy wyszukiwania. Aplikacja pisana jest w C# w technologii WPF, mam problem z hierarchią klas, którą sobie wymyśliłem. Ogólnie wygląda to tak, że stworzyłem abstrakcyjną klasę wyszukującą wzorzec (nie będę więcej się rozpisywał bo to nie istotne). Dziedziczę po tej klasie, a klasy potomne są poprostu kolejnym algorytmami wyszukiwania wzorca. W tej klasie abstrakcyjnej mam generalnie 2 funkcje : wyszukiwanie i wczytywanie tekstu z pliku tekstowego. Problem pojawia się, gdy piszę kod związany z wczytywaniem z pliku. Moja aplikacja jest oparta na 2 oknach, jedno w których user wybiera algorytm, a drugie jest tym w którym można wyszukać zadany wzorzec. Jak z poziomu klasy abstrakcyjnej odwołać się do kontrolek w oknie ?? Dokładnie do openDialog. To tak w skrócie, proszę o pomoc i radę z góry dziękuję za jakąkolwiek pomoc :wink:


(Tomek Matz) #2

Utwórz sobie statyczną klasę Factory, która będzie miała tylko jedną statyczną metodę zwracającą instancję tej Twojej abstrakcyjnej klasy (a konkretnie mówiąc - instancję klasy potomnej rzutowaną na instancję klasy abstrakcyjnej). Metoda ta będzie przyjmować parametry: ścieżka pliku, kodowanie (?), rodzaj wzorca itp. i na podstawie tego będzie decydować instancję jakiej klasy potomnej ma utworzyć, np. (pseudokod):

public static class SearchAlgorithmFactory

{

    public static SearchAlgorithm GetSearchAlgorithm(string searchAlgorithmName, string filePath, Encoding fileEncoding)

    {

        switch (searchAlgorithmName)

        { 

            case "":

                return new SearchAlgorithm(filePath, fileEncoding);

                break;

            case "":

                return new SearchAlgorithm(filePath, fileEncoding);

                break;

        }

    }

}

(Gkuczmik89) #3

tak tylko że jak narazie mój problem wygląda tak

abstract class WyszukiwanieWzorca

{ 

   public abstract void wyszukaj(); // bedzie przysłaniana w potomnych klasach

   public void wczytajTxt() // wspólna dla wszystkich klas potomnych

   {

     // tutaj chce odowłać się do OpenDialoga z okna wykonania algorytmu tylko jak ??

   }

}

(Tomek Matz) #4

Pozwolisz, że będę trzymał się nazewnictwa, które użyłem w moim poprzednim poście (żeby to było spójne):

public abstract class SearchAlgorithm

{

    private string fileName;

    private Encoding fileEncoding;


    protected SearchAlgorithm(string fileName, Encoding fileEncoding)

    {

        this.fileName = fileName;

        this.fileEncoding = fileEncoding;

    }


    public abstract void Search();


    protected void ReadFile()

    {

    }

}

To, że klasa jest abstrakcyjna nie oznacza, że nie może mieć konstruktora. Teraz w klasach potomnych będziesz robił coś takiego:

public class SearchAlgorithm : SearchAlgorithm

{

    public SearchAlgorithm(string fileName, Encoding fileEncoding)

        : base(fileName, fileEncoding)

    { }


    public override void Search()

    {

        throw new NotImplementedException();

    }

}

Parametry fileName i fileEncoding możesz też przekazywać poprzez metodę Search. W końcu to pewno z poziomu metody Search będziesz wywoływał metodę ReadFile. W efekcie tworzyłbyś jedną instancję klasy potomnej i mógłbyś ją wykorzystywać do wyszukiwania wzorców w wielu różnych plikach.


(Gkuczmik89) #5

Dobra jestem już naprawdę blisko rozwiązania problemu jeszcze jedno, mam w klasie abstrakcyjnej tak zdefiniowaną funkcję:

public void wczytajPlikTxt()

   {

       OpenFileDialog ofd = new OpenFileDialog();

       ofd.Filter = "(*.txt)|*.txt"; // dopuszcza tylko pliki tekstowe


       string nazwa_pliku;

       StreamReader reader = null;


       ofd.RestoreDirectory = true;

       if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)

       {

           nazwa_pliku = ofd.FileName;

           try

           {

               reader = new StreamReader(nazwa_pliku);

               textBox1.Text = reader.ReadToEnd(); // wczytuje zawartość pliku do textboxa

           }

           catch (Exception ex)

           {

               System.Windows.MessageBox.Show("Błąd:Nie można odczytać pliku z dysku. Error: " + ex.Message);

           }

           finally

           {

               reader.Close();

           }

       }

Podkreśla mi textboxa (służy mi on do wczytania zawartości pliku txt i wykonaniu na tej zawartości wyszukania)


(Tomek Matz) #6

Chciałbym zauważyć, że miksujesz kod GUI z kodem odpowiedzialnym za logikę aplikacji. Tak się nie powinno robić. A to, że podkreśla Ci textBox1 nie powinno być dla Ciebie zaskoczeniem. Przecież nie masz tej zmiennej zadeklarowanej w obrębie swojej klasy abstrakcyjnej.


(Gkuczmik89) #7

wiem ale potrzebuję mieć dostęp do textboxa z poziomu kodu funkcji, jak to naprawić ?


(Tomek Matz) #8

Nie potrzebujesz, Ty sobie (z jakiegoś powodu?) przyjąłeś, że potrzebujesz. Jeśli w GUI chcesz wyświetlić zawartość pliku txt, to przygotuj sobie publiczną właściwość w klasie odpowiedzialnej za jego wczytywanie, która będzie udostępniać zawartość tego pliku. Możesz też zwrócić zawartość pliku jako rezultat wywołania publicznej metody tej klasy. Możliwości masz wiele, na pewno nie musisz mixować kodu GUI z kodem odpowiedzialnym za logikę aplikacji.