Схоже, ви потрапили в деякі загальні підводні камені, але не хвилюйтеся, їх можна виправити :)
Спочатку потрібно поглянути на свою програму трохи інакше і почати розбивати її на шматки. Ми можемо розділити шматки в двох напрямках. Спочатку ми можемо відокремити логіку управління (Правила бізнесу, код доступу до даних, код прав користувача, всі подібні речі) від коду інтерфейсу користувача. По-друге, ми можемо розбити код інтерфейсу на шматки.
Тому ми спочатку зробимо останню частину, розбивши інтерфейс користувача на шматки. Найпростіший спосіб зробити це - мати єдину форму хоста, на якій ви створюєте свій інтерфейс користувача з контролями користувача. Кожен елемент управління буде відповідати регіоном форми. Тож уявіть, що у вашій програмі був список користувачів, і коли ви натискаєте на користувача, текстове поле нижче воно заповнюється їх деталями. У вас може бути один елемент управління, який керує відображенням списку користувачів, а другий - керування відображенням даних про користувача.
Справжня хитрість тут полягає в тому, як ви керуєте зв’язком між елементами управління. Ви не хочете, щоб 30 користувальницьких елементів керували у формі, щоб усі випадковим чином містили посилання один на одного та методи виклику на них.
Таким чином, ви створюєте інтерфейс для кожного елемента управління. Інтерфейс містить операції, які контролю прийме і будь-які події, які він викликає. Коли ви думаєте про цю програму, вам не байдуже, чи зміниться список списку вікон, ви зацікавлені в тому, щоб новий користувач змінився.
Отже, використовуючи наш прикладний додаток, перший інтерфейс для управління, що розміщує список списків користувачів, буде включати в себе подію під назвою UserChanged, яка передає користувацький об’єкт.
Це чудово, тому що зараз, якщо вам нудно списку списку і ви хочете 3d-масштабування магічного контролю очей, ви просто кодуєте його до того ж інтерфейсу і підключаєте до нього :)
Гаразд, частина друга, що відокремлює логіку інтерфейсу користувача від логіки домену. Ну, це добре зношений шлях, і я б рекомендував вам переглянути MVP-шаблон тут. Це дійсно просто.
Кожен елемент управління називається View (V в MVP), і ми вже висвітлювали більшість того, що потрібно вище. У цьому випадку управління та інтерфейс для нього.
Все, що ми додаємо, - це модель та презентатор.
Модель містить логіку, яка керує станом вашої програми. Ви знаєте матеріал, він би перейшов до бази даних, щоб отримати користувачів, записати в базу даних, коли ви додасте користувача тощо. Ідея полягає в тому, що ви можете протестувати все це в повній ізоляції від усього іншого.
Ведучий трохи складніше пояснити. Це клас, який знаходиться між моделлю та View. Він створюється поданням, і подання переходить у презентатор за допомогою інтерфейсу, про який ми говорили раніше.
Ведучий не повинен мати власного інтерфейсу, але я все одно люблю його створювати. Робить те, що ви хочете, щоб презентатор мав ясний текст.
Таким чином, презентатор може викрити такі методи, як ListOfAllUsers, які перегляд буде використовувати для отримання списку користувачів, або ви можете поставити AddUser метод Перегляд і викликати його у презентатора. Я віддаю перевагу останньому. Таким чином презентатор може додавати користувача до списку, коли він захоче.
Презентатор також матиме такі властивості, як CanEditUser, які повернуть істину, якщо обраний користувач зможе редагувати. Тоді View буде запитувати, що кожного разу, коли це потрібно знати. Можливо, ви хочете редагувати їх у чорному кольорі та читати лише сірі. Технічно це рішення для View, оскільки він орієнтований на користувальницький інтерфейс, незалежно від того, чи користувач може редагувати в першу чергу саме для Presenter. Ведучий знає, бо спілкується з Модель.
Отже, підсумовуючи, використовуйте MVP. Microsoft надає щось, що називається SCSF (Smart Client Software Factory), яке використовує MVP так, як я описав. Це робить і багато іншого. Це досить складно, і мені не подобається, як вони все роблять, але це може допомогти.