Parece que você caiu em algumas das armadilhas comuns, mas não se preocupe, elas podem ser corrigidas :)
Primeiro, você precisa olhar para seu aplicativo de maneira um pouco diferente e começar a dividi-lo em pedaços. Podemos dividir os pedaços em duas direções. Primeiro, podemos separar a lógica de controle (regras de negócios, código de acesso a dados, código de direitos do usuário, todo esse tipo de coisa) do código da interface do usuário. Segundo, podemos dividir o código da interface do usuário em partes.
Então, faremos a última parte primeiro, dividindo a interface do usuário em partes. A maneira mais fácil de fazer isso é ter um único formulário de host no qual você compõe sua interface do usuário com controles do usuário. Cada controle de usuário será responsável por uma região do formulário. Imagine que seu aplicativo tenha uma lista de usuários e, quando você clica em um usuário, uma caixa de texto abaixo é preenchida com os detalhes. Você pode ter um controle de usuário gerenciando a exibição da lista de usuários e um segundo gerenciando a exibição dos detalhes do usuário.
O verdadeiro truque aqui é como você gerencia a comunicação entre os controles. Você não deseja 30 controles de usuário no formulário, mantendo referências aleatórias entre si e chamando métodos sobre eles.
Então você cria uma interface para cada controle. A interface contém as operações que o controle aceitará e quaisquer eventos que ele gerar. Quando você pensa sobre este aplicativo, não se importa se a seleção da lista da caixa de listagem muda, você está interessado no fato de um novo usuário ter sido alterado.
Portanto, usando nosso aplicativo de exemplo, a primeira interface para o controle que hospeda a caixa de listagem de usuários incluiria um evento chamado UserChanged que distribui um objeto de usuário.
Isso é ótimo porque agora, se você se cansar da caixa de listagem e quiser um controle de olho mágico com zoom 3d, basta codificá-lo para a mesma interface e conectá-lo :)
Ok, então parte dois, separando a lógica da interface do usuário da lógica do domínio. Bem, este é um caminho bem usado e eu recomendo que você veja o padrão MVP aqui. É realmente simples.
Agora, cada controle é chamado de View (V no MVP) e já cobrimos a maior parte do necessário acima. Nesse caso, o controle e uma interface para ele.
Tudo o que estamos adicionando é o modelo e o apresentador.
O modelo contém a lógica que gerencia o estado do seu aplicativo. Você conhece o material, ele iria para o banco de dados para obter os usuários, escrever no banco de dados quando você adicionasse um usuário e assim por diante. A idéia é que você pode testar tudo isso em completo isolamento de todo o resto.
O apresentador é um pouco mais complicado de explicar. É uma classe que fica entre o modelo e a View. Ele é criado pela visualização e a visualização passa para o apresentador usando a interface que discutimos anteriormente.
O apresentador não precisa ter sua própria interface, mas eu gosto de criar uma de qualquer maneira. Torna explícito o que você deseja que o apresentador.
Portanto, o apresentador expôs métodos como ListOfAllUsers, que o View usaria para obter sua lista de usuários. Como alternativa, você pode colocar um método AddUser no View e chamar isso do apresentador. Eu prefiro o último. Dessa forma, o apresentador pode adicionar um usuário à caixa de listagem sempre que desejar.
O Presenter também teria propriedades como CanEditUser, que retornarão true se o usuário selecionado puder ser editado. O modo de exibição consultará isso sempre que precisar saber. Você pode querer editáveis em preto e somente leitura em cinza. Tecnicamente, é uma decisão para o modo de exibição, pois é focado na interface do usuário, se o usuário é editável em primeiro lugar, é para o apresentador. O apresentador sabe porque fala com o modelo.
Então, em resumo, use o MVP. A Microsoft fornece algo chamado SCSF (Smart Client Software Factory), que usa MVP da maneira que descrevi. Também faz muitas outras coisas. É bastante complexo e não gosto da maneira como eles fazem tudo, mas pode ajudar.