Készíts egy MVVM alapú WPF alkalmazást, amely iskolai osztályokat jelenít meg, és lehetővé teszi, hogy a felhasználó törölhesse azokat az osztályokat, amelyek létszáma 0 fő.
A feladat célja az MVVM (Model--View--ViewModel) architektúra, a binding, valamint a parancskezelés (RelayCommand) és a CanExecute logika gyakorlása a CommunityToolkit.Mvvm csomag használatával.
A projekt mappaszerkezete:
SchoolClassManagment/
│
├── Models/
│ └── SchoolClass.cs
│
├── Repos/
│ └── SchoolClassRepo.cs
│
├── ViewModels/
│ └── MainViewModel.cs
│
└── Views/
└── MainWindow.xaml
flowchart TB
subgraph View["View (MainWindow.xaml)"]
V["ListView + Button<br>Bindings: Classes, SelectedClass, DeleteSelectedCommand"]
end
subgraph ViewModel["ViewModel (MainViewModel)"]
VM["ObservableCollection<SchoolClass><br>SelectedClass<br>DeleteSelectedCommand<br>DeleteSelected() / CanDeleteSelected()"]
end
subgraph Repo["Repo (SchoolClassRepo)"]
R["_items : List<SchoolClass><br>GetAll()<br>Remove()"]
end
subgraph Model["Model (SchoolClass)"]
M["Grade, Section, StudentCount, Name<br>ToString()"]
end
V -->|DataContext, Binding| VM
VM -->|Uses| R
VM -->|Contains| M
R -->|Stores and Returns| M
- Vegyen fel új tesztadatokat, közöttük legalább még két osztály 0 fővel és ellenőrizze, hogy azokat lehet-e törölni!
- Új property felvétele és törölhetőség
- Vegyen fel egy új property-t a SchoolClass osztályba (pl. AverageGrade).
- A repóban 1-2 „értelmetlen” értéket tartalmazó adatot (pl. AverageGrade = -5).
- A ViewModelben egészítse ki a törlési logikát: most ne csak StudentCount == 0 legyen törölhető, hanem pl. AverageGrade < 1 is (értelmetlen adat).
A View automatikusan engedélyezi a Törlés gombot ezekre az elemekre is, mert a CanDeleteSelected() bővül.
Összefoglaló táblázat feladat ötletekkel:
SchoolClass modellhez
| Property neve | Típus | Példa érték | Értelmetlen adat (törölhető) | Magyarázat / gyakorlati értelme |
|---|---|---|---|---|
RoomNumber |
string |
"B201" |
üres ("") vagy "???" |
Melyik tanteremben van az osztály; hibás, ha nincs megadva. |
ClassTeacher |
string |
"Kovács Ágnes" |
"Ismeretlen" vagy üres |
Az osztályfőnök neve; ha hiányzik, az adat hibás. |
AverageGrade |
double |
3.75 |
-1, 0, 99 |
Osztályátlag; negatív vagy irreálisan nagy érték hibás. |
StartYear |
int |
2023 |
0 vagy 9999 |
Tanév kezdete; irreális évszám hibás. |
Specialization |
string |
"informatika" |
"???", "nincs" |
Szakirány / tagozat; üres vagy „nincs” érték hibás. |
HasClassPresident |
bool |
true |
– | Nem „hibás” célra, de statisztikákhoz hasznos. |
BudgetPerStudent |
decimal |
12000.50m |
-500 |
Anyagi keret; negatív érték értelmetlen. |
WeeklyLessons |
int |
32 |
0 vagy >60 |
Heti óraszám; 0 vagy túl nagy hibás. |
Email |
string |
"9a@school.hu" |
nem e-mail formátum (pl. nincs @) |
Kapcsolattartás; formátum-ellenőrzés tanulható vele. |
IsValid |
bool |
true |
false |
Manuális jelölés, hogy az adat hibás-e (pl. későbbi tisztításhoz). |
Készíts egy SchoolClass nevű osztályt, amely az iskolai osztály adatait tárolja.
-
Az osztályban legyen három publikus property:
-
Grade -- az évfolyam száma (pl. 9, 10, 11, 12).
-
Section -- az osztály betűjele (pl. „a", „b", „c").
-
StudentCount -- a diákok száma az adott osztályban.
-
-
Készíts:
-
üres konstruktort (paraméter nélküli),
-
paraméteres konstruktort, amely beállítja az összes property-t.
-
-
Készíts egy ToString metódust, amely visszaadja az osztály szöveges formáját a következő módon:
„évfolyam.betűjel -- létszám fő" (pl. 9.a -- 26 fő).
Készíts egy SchoolClassRepo nevű osztályt, amely egy egyszerű memória alapú adattár.
-
Az osztályban legyen egy privát lista az iskolai osztályok tárolására.
A lista tartalmazzon legalább három előre feltöltött tesztosztályt, amelyek közül az egyik 0 fős. -
Készíts egy publikus metódust:
- GetAll() -- amely visszaadja az osztályok listáját (csak olvasható formában).
-
Készíts egy másik publikus metódust:
- Remove(SchoolClass schoolClass) -- amely törli a paraméterként kapott osztályt a listából.
classDiagram
class SchoolClass {
+int Grade
+string Section
+string Name
+int StudentCount
+SchoolClass()
+SchoolClass(int grade, string section, int studentCount)
+string ToString()
}
class SchoolClassRepo {
-List<SchoolClass> _items
+IReadOnlyList<SchoolClass> GetAll()
+void Remove(SchoolClass schoolClass)
}
class MainViewModel {
+ObservableCollection<SchoolClass> Classes
+SchoolClass? SelectedClass
+ICommand DeleteSelectedCommand
+MainViewModel()
-bool CanDeleteSelected()
-void DeleteSelected()
}
class MainWindow_xaml {
<<XAML View>>
+ListView ItemsSource=Classes
+SelectedItem -> SelectedClass
+Button Command=DeleteSelectedCommand
}
MainViewModel --> SchoolClassRepo : használja
MainViewModel "1" o-- "n" SchoolClass : listázza (Classes)
MainWindow_xaml --> MainViewModel : DataContext
Készíts egy MainViewModel nevű osztályt, amely felelős a View és az adatok közötti kapcsolattartásért.
-
Az osztály örököljön a ObservableObject osztályból, hogy automatikusan kezelje az értesítéseket a property-k változásáról.
-
Az osztályban legyen egy privát példány a SchoolClassRepo-ból, amelyen keresztül az adatok elérhetők.
-
Hozz létre egy publikus property-t:
- Classes, amely ObservableCollection<SchoolClass> típusú, és a repo adatait tartalmazza.
- Hozz létre egy választott elemhez tartozó property-t:
-
SelectedClass, amely a felhasználó által a ListView-ban kijelölt osztályt tárolja.
-
Az attribútumai között szerepeljen:
-
[ObservableProperty] -- automatikus getter/setter létrehozásához.
-
[NotifyCanExecuteChangedFor(nameof(DeleteSelectedCommand))] -- annak érdekében, hogy ha a kiválasztás megváltozik, a törlés gomb állapota automatikusan frissüljön.
-
- Készíts egy parancsot (RelayCommand):
-
Név: DeleteSelectedCommand
-
Célja: törölje a kijelölt osztályt a Classes gyűjteményből és a repóból.
-
Csak akkor legyen végrehajtható, ha a SelectedClass.StudentCount értéke 0.
(Ezt a feltételt egy külön CanDeleteSelected() metódus adja vissza.)
- A DeleteSelected metódus végén állítsd a SelectedClass értékét null-ra, hogy a kijelölés megszűnjön.
A felhasználói felület egy egyszerű WPF ablak legyen, amely az osztályokat listázza, és lehetőséget ad a törlésre.
-
Az ablak DataContext-je legyen a MainViewModel.
-
Készíts egy ListView-t, amely:
-
az ItemsSource tulajdonságon keresztül a Classes gyűjteményhez kötődik,
-
a SelectedItem a SelectedClass property-hez van bindelve,
-
két oszlopot tartalmaz:
-
az egyik az osztály nevét (Grade + Section),
-
a másik a létszámot (StudentCount).
-
-
-
Helyezz el egy Törlés gombot:
-
A gomb Command-ja a DeleteSelectedCommand legyen,
-
A gomb automatikusan letiltódjon, ha a parancs nem hajtható végre (nem 0 fős osztály van kijelölve).
-
sequenceDiagram
participant User as Felhasználó
participant View as MainWindow.xaml (View)
participant VM as MainViewModel
participant Repo as SchoolClassRepo
User->>View: 0 fős osztály kijelölése ListView-ban
View->>VM: SelectedClass beállítása
VM->>VM: CanDeleteSelected() == true
View->>User: "Törlés" gomb aktív
User->>View: Törlés gomb kattintás
View->>VM: Execute DeleteSelectedCommand
VM->>Repo: Remove(SelectedClass)
VM->>VM: Classes.Remove(SelectedClass), SelectedClass = null
View->>User: Lista frissül (elem eltűnik)