Rozszerzenie Klasy Form

0

Witam. Mam następujące pytanie... może dla niektórych to proste :-) dla mnie nie ;/ niestety.

Mam pytanie następujące.

Jak tworzę aplikację w VS2008 projekt Windows Forms to dostaję coś co nazywa się Form1.cs
Na tyle na ile rozumiem Taki Form1 dziedziczy/jest pochodną obiektu Form

I teraz mam następujące pytanie ...

Kiedy tworzę klasę

public static void CosTam(this form formularz)
{
//tutaj cos sie dzieje na tym formularzu.
}

Nie jestem sie w stanie do niej odwolac dla defaultowego Form1

Jesli stworze sobie jego instancje
Form1 Formul1 = new Form1();

to potem moge zrobic Formul1.CosTam(); :/

Jednak chcialbym sie odwolac do tego nieszczesnego Form'a który jest defaultowy
a visual studio nie pozwala mi na wykonanie operacji Form1.CosTam();

I teraz tak czy ten defaultowy Form1 jest nie zainicjalizowany w zden sposob?

Moje pytanie bierze sie z tad ze chcialbym zautomatyzowac zmianę wygladu interfaceu... a nie jestem w stanie zawolac tego defaultowego forma... dlaczego?

0
Koteczek napisał(a)

Kiedy tworzę klasę

public static void CosTam(this form formularz)
{
//tutaj cos sie dzieje na tym formularzu.
}

Nie jestem sie w stanie do niej odwolac dla defaultowego Form1

Radzilbym poczytac wpierw o obiektowosci. Czyli czym sa obiekty i jak z nich korzystac :)
W powyzszej czesc nie widze bys tworzyl klase, tylko widze tam jakas statyczna metode, ktora jeszcze ma niepoprawne parametry. Jesli chcesz stworzyc klase dziedziczaca po Form1 to:

public class DrugaForma : Form1
{...

Jesli masz metode ktora jako parametr przyjmuje Form'e to nie musi to byc Form tylko Form1 i mozesz juz odwolywac sie do jego metod itp. Jesli rzutujesz Form1 na ogolnego Form'a (tak jest np poprzez uzywanie propertisa Parent) to zawsze mozesz zrzutowac to w druga strone np w kodzie Form1 mojForm = form as Form1;

0

Zdecydowanie dziedziczy, pochodne to całkiem inna branża.

Kiedy tworzę klasę

public static void CosTam(this form formularz)
{
//tutaj cos sie dzieje na tym formularzu.
}

To nie jest klasa, raczej metoda. Na dodatek masz bardzo dziwną listę argumentów, w zasadzie nie do skompilowania.

Jeśli chcesz mieć metodę w Form1, która zrobi coś z tym formularzem, to umieść ją w ciele klasy Form1, a potem wywołaj. Jeśli zrobisz ją jako static, to trzeba będzie wywoływać jako Form1.CosTam(). Lepiej zrobić ją jako zwykłą i wywoływać this.CosTam(). Ale to oczywiście zależy od tego, gdzie ją chcesz wywoływać i w odpowiedzi na co - możesz rozjaśnić?

Ponadto: stąd a nie "z tad", domyślny a nie defaultowy, interfejsu a nie interaceu.

0

Tia ... my Bad bylem troche zakręcony jak pisałem poprzedniego posta...
Tamto co pisałem to oczywiście metoda... -_-'' again my bad.
(i chyba przez to zakręciłem trochę to co chciałem powiedzieć więc jeszcze raz)

  • Jest Sobie Ten Form1
  • Jest Sobie Program z mainem gdzie siedzi wyswietlenie forma

i teraz

w Klasie Form1 jest Form1_on_Load (czy jakoś tak)
jeśli sobie stworzę klasę Form2 to tam tez mogę coś takiego umiesci (ale nie o to mi chodzi...)

Ta [again]metoda[/again] :] jest w Klasie którą tworzę (powiedzmy że nazywa się Rozszerz albo coś)
więc ta metoda :P o poprawnych parametrach (this Form Formularz)

Ma się później wywoływać
przez
Form1.Metoda
Form2.Metoda

  • etc
    FormXYZ.Metoda

... -_-
Z tym że do wywołania Form1 - XYZ nie potrzebuję instancji jego klasy żadnej.

Chodzi więc o to jak zmusić do tego żeby się pokazało to Form1.Metoda (w intellis sense i nie sypało błędami)

Bo na chwilę obecną nie ma instancji Form1...
stąd to public static void Metoda(this Form Formularz)

;] tak jak pisałem chodzi mi o to żeby nie pisać tego samego w każdym Form'ie który sobie tworzę tylko zawołać jakąś ogólną metodę z innej klasy....

Mam nadzieję że teraz było jaśniej xD
Dla większości obiektów(kolekcji?) C# to działa :P np.: dla guziczków, listboxów etc.

0

Nie trochę, tylko bardzo i nie byłeś, ale jesteś. Poza tym reszta się zgadza.
Wybacz, ale jak dla mnie, to piszesz całkowicie niezrozumiale i jakoś tak mało po programistycznemu...

Może Ty lepiej:

  1. pokaż jakiś kod;
  2. narysuj o co Ci chodzi;
  3. napisz - co tak naprawdę chcesz osiągnąć, ale z punktu widzenia funkcjonalności, nie kodu. Wtedy będzie można znaleźć rozwiązanie. Bo wydaje mi się, że za bardzo kombinujesz lub chcesz wynaleźć koło na nowo.

Z tego co udało mi się załapać - chcesz mieć taką samą metodę w kilku formularzach.
Możesz zatem zrobić jakąś klasę (np. statyczną), w której umieścisz tę metodę i będziesz ją wywoływał z formularzy.
Możesz też utworzyć klasę dziedziczącą z Form, np.
RozszerzonyFormularz : Form
i umieścić w niej tę metodę (niestatyczną). A następnie zamiast tworzyć i używać obiekty typu Form, tworzyć i używać obiekty typu RozszerzonyForm. Jeśli główny formularz aplikacji miałby też być typu RozszerzonyForm, to oczywiście będziesz musiał zmienić także kod w pliku Program.cs

0

Faktycznie ten watek przypomina bardziej zgaduj zgadula, co autor mial na mysli :) Dlatego tez, chyba lepiej by bylo gdyby jednak poczytal o klasach i calej obiektowosci, moze wtedy problem by sie sprecyzowal w konkretne pytanie :)

0

E tam po mojemu jemu chodzi o rozszerzenia (extension methods). Cytuję:

"Należy zdefiniować klasę niezagnieżdzoną w innej klasie (zdefiniowaną bezpośrednio w przestrzeni nazw) i umieścić w niej definicję statycznej metody, której argument jest takiego typu, jaki rozszerzamy, oraz jest poprzedzony słowem kluczowym this."

Nie wgłębiałem się w poprzednie wypowiedzi, zresztą całość mojej wiedzy dotyczącej C# sprowadza się do przeczytania na razie 1 książki, ale na pierwszy rzut oka ma być:

public static void CosTam(this Form formularz)

a nie

public static void CosTam(this form formularz)

Chodzi o wielkość liter. Jeśli dalej będzie nie halo to sprawdź czy twoja metoda spełnia inne podane w cytowanym zdaniu warunki.

Pozdrawiam

0

Dobra dzisiaj jestem trzeźwy [diabel]

Tak chodzi o Extension Method dla klasy Form.

W sprawie kodu wygląda to mniej więcej tak (pisząc na forum nie bardzo zwracam uwagę na wielkość liter)

static class Klasa
{
  public static void Rozszerz_UstawWygladNaOpcje(this Form formularz)
  {
    formularz.opcja1 = costam;
    itd;
    itd;
  }
}

poza tym wszystko jest mniej więcej jak w standardowym projekcie VS2008 -> dla windows Forms

a pozniej w Form1.cs lub jakims innym, On_Load chce wołać.

Form1.Rozszerz_UstawWygladNaOpcje;

albo w jakims innym miejscu.

Zaznaczam że nie tworzę wcześniej instancji tego Form1

czyli nie ma żadnego Form1 Forma1 = new Form1();

Formularze wywołuję poprzez Application.Run(new Form1());

/======
Co do ogólnych założeń jest klasa rozszerzenia w której są metody extension, i jedna z tych metod
ma obsługiwać ustawienia wyglądu formularza. Bez jakiegoś szczególnego tworzenia instancji tak aby możnabyło ją wywoływać na już naprzykład otwartym formularzu lub on load tegoż formularza.

0

Application.Run(new Form1()) juz tworzy intancje klasy Form1 wkoncu formularze to obiekty

public static void Rozszerz_UstawWygladNaOpcje(this Form formularz)
{... 

Nie ma czegos takiego jak powyzsze, jesli w zadaniu pisze o this, to jako formie przekazania z istniejacej klasy referencji na sama siebie. Metoda powinna byc zadeklarowana w sposob:

public static void Rozszerz_UstawWygladNaOpcje(Form formularz)
{... 

a nastepnie jesli chcesz ja wywolac w jakims zdarzeniu na Form1 OnLoad to wewnatrz tej metody musisz to zrobic tak:
Klasa.Rozszerz_UstawWygladNaOpcje(this);

this - wskazuje na aktualna klase. Czyli jezeli jestes akurat w metodzie OnLoad Form1 to this wskaze na instancje Form1. W metodach statycznych nie mozesz uzywac slowa kluczowego this, gdyz metody statyczne sa dzielone miedzy instancjami wszystkich klas, a zatem musisz przekazac konkretna klase jako argument metody.

0

Jak pisałem wcześniej moja wiedza jest czysto teoretyczna (właśnie mi się ściąga VS2008). Jakkkolwiek słowo kluczowe this (oprócz tego co napisał wasiu) służy właśnie do deklaracji rozszerzeń klas. Metoda rozszerzająca może mieć więcej argumentów ale tylko pierwszy może mieć słowo kluczowe this. Dlaczego to jednak nie działa ... cóż mogę tylko gdybać:

  • opis calss extension jest w rozdziale "Nowości w C# 3.0" - używasz tej wersji ?
  • ja bym jednak obstawiał, że to co napisałeś nie jest "widziane". W knidze którą zgłębiłem stało: "definicja klasy musi być umieszczona bezpośrednio w przestrzeni nazw" - ale co dokładnie to znaczy nie wiem : )

Pozdrawiam

0
wasiu napisał(a)

Application.Run(new Form1()) juz tworzy intancje klasy Form1 wkoncu formularze to obiekty

Ok tylko nie mam możliwości odwołania się do tego. bo to "new Form1()" jest tylko dla Application.Run i tu się bajka kończy ;)

public static void Rozszerz_UstawWygladNaOpcje(this Form formularz)
{...

> Nie ma czegos takiego jak powyzsze,

Oj jest i służy tak jak napisał Bobik do Tworzenia Metod rozszerzających istniejące już klasy ...


> jesli w zadaniu pisze o this, to jako formie przekazania z istniejacej klasy referencji na sama siebie. Metoda powinna byc zadeklarowana w sposob:
> <code>public static void Rozszerz_UstawWygladNaOpcje(Form formularz)
{... 

a nastepnie jesli chcesz ja wywolac w jakims zdarzeniu na Form1 OnLoad to wewnatrz tej metody musisz to zrobic tak:
Klasa.Rozszerz_UstawWygladNaOpcje(this);

this - wskazuje na aktualna klase. Czyli jezeli jestes akurat w metodzie OnLoad Form1 to this wskaze na instancje Form1. W metodach statycznych nie mozesz uzywac slowa kluczowego this, gdyz metody statyczne sa dzielone miedzy instancjami wszystkich klas, a zatem musisz przekazac konkretna klase jako argument metody.

Tia mógłbym to zrobic tak że mam jakąś klasę i sobie wołam
Klasa.Obsluga(Form1); i wtedy dowoli używać w ciele metody This
ale to już wtedy nie jest metoda typu extension. A niestety zależy mi na tym żeby to był extension.

@Bobik>
tia używam .NET 3.0

A co do przestrzeni nazw (namespace) to jakoś nie widzę co miałyby miec od rzeczy tutaj... :/
dlatego że wszystkie klasy są zdefiniowane w tym samym namespace dla przykładu nazwanego Projekt.

0

Ok rozwiązałem problem sugerując się postem Wasia... :) dzięki
Pod spodem wnętrza obu plików. Zwróćmy uwagę że to co nie działa dla Form1 działa bez problemu dla button1.

namespace Projekt
{
    public static class Rozszerzenia
    {
        public static void Rozszerzenie_Wyglad_Formularza(this Form Formularz)
        {
            Formularz.BackColor = SystemColors.ActiveBorder;
            Formularz.Cursor = Cursors.Hand;
        }

        public static void Rozszerzenie_Wyglad_Guzik(this Button Guzik)
        {
            Guzik.FlatStyle = FlatStyle.Flat;
        }
    }
}
namespace Projekt
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Rozszerzenie_Wyglad_Formularza();
            button1.Rozszerzenie_Wyglad_Guzik();   
        }
    }
}

... cały czas jednak nie rozumiem czemu
this.Rozszerzenie_Wyglad_Formularza(); działa
Form1.Rozszerzenie_Wyglad_Formularza(); nie działa
button1.Rozszerzenie_Wyglad_Guzik(); działa

pozdrawiam

0

Dzieki, a i ja sie czegos nauczylem, bo nie wiedzialem o tej nowince z .net'a 3.0 :)

Dla Form1 nie zadziala, gdyz Form1 nie jest instancja klasy, tak wiec pod tym nie kryje sie zaden formularz.

this i button1 sa instancjami klasy formy i button'a, wiec mozna na nich wykonac operacje zmiany stylu.
Tak z ciekawosci spytam... gdzie dostales takie zadanko?

0

@wasiu:

... bo nie wiedzialem o tej nowince z .net'a 3.0 :)

IMHO jeden z fajniejszych bajerów, które przekonały mnie żeby coś niecoś dowiedzieć się o .NET

... Dla Form1 nie zadziala, gdyz Form1 nie jest instancja klasy, tak wiec pod tym nie kryje sie zaden formularz.

Dokładnie masz rację. Form1 jest nazwą klasy. Metody rozszerzające pomimo że deklaruje się jako statyczne, wywołuje się na rzecz konkretnej instancji a tą w tym przypadku jest this. Szczerze powiedziawszy dobrze jest nazywać rzeczy po imieniu, może VS tego nie sugeruje, ale ja zawsze staram się trzymać wyuczonej konwencji:

TForm1, IJakisInterface ...

Pozdrawiam
b

0
wasiu napisał(a)

Dzieki, a i ja sie czegos nauczylem, bo nie wiedzialem o tej nowince z .net'a 3.0 :)

Dla Form1 nie zadziala, gdyz Form1 nie jest instancja klasy, tak wiec pod tym nie kryje sie zaden formularz.

this i button1 sa instancjami klasy formy i button'a, wiec mozna na nich wykonac operacje zmiany stylu.
Tak z ciekawosci spytam... gdzie dostales takie zadanko?

Przedmiot się Nazywa Programowanie Obiektowe ;) [nazwę uczelni celowo pominę]
I muszę właśnie wymyślić jakieś takie sztuka dla sztuki zastosowania obiektowości poprzez na przykład rozszerzanie już istniejących klas metodami typu extension. I jeszcze parę innych z którymi większych problemów nie mam (o dziwo :| )

Co do tego że Form1 nie ma instancji to ok. :-) tylko czemu skoro jestem wewnątrz kodu tej klasy i się do niej odwołuję xD to działa to nieszczęsne this tylko :-) (niby rozumiem że tak łatwiej) ale taki sam efekt można by uzyskiwać przez pisanie nazwy klasy wewnątrz tejże klasy, przynajmniej tak mi się wydaje... albo jestem nie konsekwentny :|

0

jesli zamiast
Application.Run(new Form1())

uzylbys:
Form1 forma = new Form1();

to pozniej moglbys korzystac z forma.Rozszerzenie_Wyglad_Formularza(); gdyz dzialasz bezposrednio na obiekcie :) (oczywiscie w zasiegu dzialaniu tego obiektu). Form1 nie jest obiektem ale typem obiektu jaki mozesz stworzyc, tak wiec rozszerzona metoda nie mialaby na czym dzialac :)

Wlasnie uczelnia i miasto mnie najbardziej ciekawi :) Sam sie chce wybrac na dalsze studia i miloby bylo wiedziec, gdzie czegos ciekawego ucza ;)

0
wasiu napisał(a)

Dzieki, a i ja sie czegos nauczylem, bo nie wiedzialem o tej nowince z .net'a 3.0 :)
Na pewno korzystałeś już z tego: http://msdn.microsoft.com/en-us/library/system.linq.enumerable_members.aspx ;)

0
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
   

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Rozszerz_UstawWygladNaOpcje();
        }
    }

    public static class dsa
    {
        public static void Rozszerz_UstawWygladNaOpcje(this Form formularz)
        {
            formularz.Text = "lalala";
        }
    }

U mnie działa. Intellisense też :)

0

No do tego tośmy doszli wczoraj że działa : )

0

No to żeby dodać choć coś wartościowego do tego wątku daję kawał:

  • Programista nie umiera, on oddaje zasoby.

;)

0

Grabarz kolektorowi

0

A ja dodam, że użyłem dzisiaj extension methods po raz pierwszy :). BinaryReader w metodzie ReadString oczekuje stringa z ilością znaków na początku, a ja miałem stringa z C zakończonego na /0. Dopisałem więc sobie odpowiednią metodę do BinaryReader i ładnie to działa ;).

0

Czy problem sam się rozwiązał - po prostu nie można rozszerzyć klasy o nowe metody statyczne! .. jedynie "zwykłe" metody obiektów można dodać.

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