VS - statyczne kontrolki

0

Mam VS 2008 Professional i chciałem, aby w formularzu głównym aplikacji kontrolka DataGridView była statyczna. Próbowałem w Form1.Designer.cs dopisać słowo kluczowe "static" ale przy każdej możliwej okazji zamieniane jest przez VS z powrotem na non-static i musze za każdym razem przed kompilacją zmieniać. Jak to ustawić?

0

Zadeklaruj sobie zmienną w pliku Form1.cs. Konfiguracja może zostać w plikuForm1.Designer.cs. Osobiście nie radzę tworzyć statycznych kontrolek - może to przysporzyć sporo kłopotu w przyszłości.

0

Jesli bardzo chcesz to stworz sobie statyczny property ktory odwolowuje sie do tej kontrolki... kontrolka sama w sobie nie moze byc statyczna, bo musi byc przypisana do konkretnej instancji okna (a ich mozesz miec wiele jednoczesnie). Aby moc uzyc statycznego property bys potrzebowac stworzyc klase formularza jako singletona i dodatkowo przechowywac statyczna instancje klasy formularza w jakiejs zmiennej, z ktorego w statycznym Property bys odczytywal instancje danej kontrolki.

0

Proponuję, żebyś uzasadnił w jakim celu chcesz kontrolkę uczynić statyczną. Bo tworzenie statycznych kontrolek jest złą praktyką programistyczną. Przeważnie jest wiele sposobów na zrobienie tego samego i należy wybrać sposób, który będzie generował jak najmniej problemów i nie pozbawi aplikacji elastyczności.
Podejrzewam, że po prostu chcesz mieć dostęp do kontrolki z obiektu innego niż forma na której jest dana kontrolka (popraw mnie jeśli się mylę). W przypadku DataGridView najlepszym sposobem jest utworzenie specjalnej klasy, której obiekt będzie przechowywać wartości dla DataGrid-a i skorzystać z bindingu danych (google: DataGridView data binding).

Można również przekazywać instancję danej kontrolki klasom podrzędnym, np. w konstruktorze.
Najmniej ładnym sposobem jest przechowywanie instancji kontrolki w obiektach statycznych. Ale nie na zasadzie tworzenia danej kontrolki w statycznym obiekcie, ale przechowywanie kopii (referencji) danego obiektu niestatycznego w obiekcie statycznym. Np. do klasy głównej formy dodajesz:

public static DataGridView staticDGV = null;

A potem w konstruktorze formy dodajesz:public MainForm()
{
InitializeComponent();
staticDGV = myNonStaticDataGridView;
}

Dodatkowo w "Program.cs" musisz zapisać instancję formy również w statycznym obiekcie, w tym celu kod:
```cpp
static void Main()
{
	Application.EnableVisualStyles();
	Application.SetCompatibleTextRenderingDefault(false);
	Application.Run(new MainForm());
}

Zamieniasz na:

public static MainForm mainForm;
static void Main()
{
	Application.EnableVisualStyles();
	Application.SetCompatibleTextRenderingDefault(false);
	mainForm = new MainForm();
	Application.Run(mainForm);
}

I od teraz w każdym miejscu kodu możesz odwołać się do kontrolki poprzez Program.mainForm.staticDGV.

Chociaż w tym ostatnim przypadku chyba lepiej będzie utworzyć oddzielną statyczną klasę i w niej przechowywać statyczną instancję DataGridView. Ale jak już pisałem, nie jest to najlepsza metoda i należy jej unikać jeśli jest to możliwe.

0

Dokladnie, chodzi mi o to, żeby mieć dostęp do niej z zewnątrz, zarówno z okien podrzędnych jak i innych wątków. Wiem, że do innych wątków moge przekazać referencję, ale myślałem, że w ten sposób będzie wygodniej a nie byłem pewny czy coś takiego nie jest zalecane.
A jeśli chodzi o inne okna, to jak to zrobić? Ustawić tworzyc zmienna "owner" za pomoca ktorej bede mogl sie do okna wywołującego, tak?

cos w stylu:

class Form1:Form
{
public Form1
{
Form2 f2 = new Form2;
f2.owner = this;
}
}

class Form2:Form
{
public Form1 owner;
}

W przypadku DataGridView najlepszym sposobem jest utworzenie specjalnej klasy, której obiekt będzie przechowywać wartości dla DataGrid-a i skorzystać z bindingu danych (google: DataGridView data binding).

Czyli po prostu, powinienem stworzyć inny statyczny obiekt własnej klasy, albo np obiekt typu DataSet, tak?
Jeśli macie inne propozycje jeszcze, to pomóżcie.

0

Źle kombinujesz. Po pierwsze, obiektów statycznych w większości wypadków należy się wystrzegać. Obiekt statyczny może być np. używany do pozyskania i przechowania ustawień komputera, bo wiadomo, że program może być uruchomiony tylko na jednym komputerze i nie ma sensu tworzyć kilku takich obiektów. Ale w przypadku kontrolek nie jest to dobra praktyka.

Najlepiej w takim wypadku jest zastosować eventy. Obiekty, które będą wykonywały operacje na elementach wyświetlanych przez DataGrid-a będą zgłaszały odpowiednie eventy i będą do niech przesyłały odpowiednie dane.
Druga metoda, którą można połączyć z poprzednią, to tak jak już pisałem, stworzenie klasy, która będzie przechowywała elementy wyświetlane przez DataGrid-a, utworzyć kolekcję obiektów tej klasy i przekazywać tą kolekcję jako argument do obiektów lub samych metod, które będą wykonywały jakieś operacje na tych danych. Do tego, żeby zautomatyzować wyświetlanie danych proponuję skorzystać z data bindingu.

Co do wątków, to musisz uważać na wykonywanie operacji na obiektach interfejsu użytkownika, gdyż operacje na tych obiektach mogą być wykonywane tylko w wątku w którym działa GUI. Do wywoływania z innego wątku pewnych funkcji operujących na obiektach interfejsu użytkownika, każda klasa dziedzicząca po System.Windows.Forms.Control ma zaimplementowane metody Invoke/BeginInvoke/EndInvoke.

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