WinForms에서 MVP로 약간을 썼는데 해결해야 할 문제가 많이 있습니다. 대부분의 문제는 VS에 있다는 사실에서 비롯되며 디자이너 인 양식을 사용하여 양식을 쉽게 디자인 할 수 있다는 것이 좋습니다.
널리 사용되는 WebForms MVP 프로젝트에서 개발 한 WinForms MVP API를 사용해 보았습니다.하지만 Generics (예 : public class TheForm : UserControl)의 파일이면에 코드가 있기 때문에 양식을 디자인 할 능력이 없어졌습니다. 디자이너는 Generics를 처리하는 방법을 알고 있습니다.
IPresenter, IView, IViewModel과 같은 핵심 인터페이스가 끝났습니다. 추가 속성을 추가하지 않아도 특정 구현을위한 중간 인터페이스를 만들었습니다. 주로 나중에 추가 작업을 할 때 변경 사항을 수용하기가 더 쉽기 때문입니다. IPresenter는 유형 IView의 공동 변형 generice 형식을 사용합니다. 그래서 상속 체인 아래에서 특정 하위 뷰 유형의 발표자를 만들 수 있습니다. 대화를 만들어 결국 쇼 발표자를 인스턴스화하고 호출하여 수행됩니다
ISomePresenter<ISomeView> somePresenter = new SomeFactory.GetSomePresenter();
somePresenter.Show();
내보기는 IViewModel의 사본 보유 : 없음 다시 원래의 질문에
public void Show()
{
ISomeView theView = new V();
theView.ViewModel = new SomePresenterViewModel();
.
.
.
}
을 ... 을 SampleView는 ISampleViewModel에 대해 알 수 없기 때문에 어딘가에 캐스트를 넣지 않고 ViewModel에 표준 데이터 바인딩을 수행하는 것은 불가능합니다. 이 모든 것들을 개발 한 프로젝트에서 손을 떼었고 사람들은 BindingSource 마법사뿐만 아니라 이벤트 핸들러에서 온통 캐스팅되었습니다. MVP 전체가 사라졌습니다.
이제는 이벤트 처리 방법과 속성 (및 함께 제공되는 ISampleView 속성)을 공개 컨트롤로 설정하여 발표자가 볼 수있게하거나 단순히 중복 이벤트를 만들어서 다시 발생시키는 방법에 대해 엄격하게 다루었습니다. 발표자가 가져올 이벤트 전체 데이터 바인딩 수수께끼에 대해 생각해 보았습니다. 실제로 디자이너가 지원하지 않고 디자이너가 코드에서 수행하는 모든 작업을 Presenter 내부에서 수행하는 유일한 방법이 있습니다. Designer를 사용하여 .designer.cs 파일에서 자동 생성 된 코드를 가져오고 모든 코드를 Presenter로 잘라낼 수 있습니다. 어쩌면 문법 등을 얻고, 보일러 플레이트 코드를 배제하거나, 생성 된 내용을 기반으로 발췌 문장을 만들 수 있습니다. 바인딩을 지정하려면 뷰의 실제 컨트롤에 대한 액세스가 필요하므로 컨트롤 인스턴스를 반환하는 ISampleView에 속성을 추가하십시오. 또한 Presenter에 BindingSource 인스턴스를 배치하거나 Presenter가 인스턴스를 보유하는 다른 클래스에 배치하는 것이 좋습니다.
저는 가능한 한 디자이너를 사용하고 싶지만 때로는 휴식을 취할 필요가 있습니다. 내가 말했듯이 CodePlex의 WinForms MVP 프로젝트는 훌륭하지만 모든 폼 디자인은 코드로 수행됩니다. 내 시나리오에서는 코드에서 수행해야하는 데이터 바인딩 일뿐입니다. 어쨌든 실제로 시각적 인 것이 아니기 때문에 다루기가 더 쉽습니다.
또한 메모로 전체 데이터 바인딩을 지원하는 NotifyPropertyWeaver (IL 제직) 사용자. 보기 모델에서 자동 속성을 만들어서 각 속성에 NotifyPropertyChanging 등을 호출 할 필요없이 코드를 간결하고 읽기 쉽게 유지할 수 있다는 점에서 훌륭합니다. IL Weaving with Fody는 최종 빌드 출력 단계 전에 컴파일 된 모든 작업을 수행합니다. 매우 편리합니다.
어쨌든이 두뇌 문제에 대한 개념을 두뇌가 누군가에게 가치 있기를 바랍니다. 나는 긴 시간을 그것을 밖으로 분류하는 데 썼다. 그러나 그것은 나를 위해 꽤 잘 돌아 간다.
스티브
편집 2014년 4월 23일
당신은 .NET 데이터 바인딩이 엉덩이에 엄청난 고통이 무엇인지 알고있다. 최근에 프로젝트에서 우리는 특정 컨트롤에 대한 자체 데이터 바인딩 코드를 롤업하는 결과를 낳았습니다.
더 많은 최근 경험을 다시 회고 해보면 핵심 모델이 완전히 분리되어 있어야합니다. 필자는 데이터베이스와 대화하고 DataBindable이며 View에서 볼 수있는 ViewModel을 작성하는 경향이 있습니다. 데이터 바인딩을 사용하면 특히 DateTimePicker의 ValueChanged와 같은 컨트롤 이벤트를 처리 할 때 많은 불만이 생깁니다. 한 시나리오에서 시작 날짜와 종료 날짜 선택기 및 시작 날짜 이후의 종료 날짜와 다른 범위 규칙을 고려해야 할 체크 상자가 있습니다. 일부 규칙을 기반으로 값을 변경할 때 VM에 구성된 데이터 바인딩을 사용하면 이벤트가 다시 실행되고 내가 선택한 것보다 우선합니다. 이벤트 처리기가 계속 진행되어야하는지, 아니면 잠재적 경쟁 조건이 있는지 또는 다른 스레드의 이벤트 처리기가 기다려야하는지 여부를 알지 못하게하는 데 도움이되는 bool 값을 넣어야합니다. 정말 지저분 해집니다.
내 접근법은 데이터베이스에 접근하는 큰 MODEL을 생성하고 캡처 된 데이터를 기반으로 유효성 검사 규칙을 확인할 수 있지만 데이터 바인딩을위한 속성 만 보유하고있는 작고 가벼운 버전을 만들 것입니다. 실제 모델과의 분리는 여전히 진행 중이며 Presenter/Controller가 응답하는 모든 이벤트는 양식 데이터 유효성 검사/데이터 지속 시간에 VM에서 주 모델로 복사 할 수 있습니다. 이벤트에 응답하는 경우 다음에 바인딩되는 VM 값을 설정하면 더 가벼운 VM을 만들 수 있습니다. 새 VM 인스턴스를 만들고 유효성 검사 결과를 다시 할당 한 다음이 새 VM 인스턴스를 .DataSource로 설정할 수 있습니다. 보기에있는 BindingSource는 준비가되면 이벤트 처리기가 엉망이되는 것을 방지합니다.
주 모델이 NotifyPropertyChanged 이벤트에 응답하여 변경 사항을 업데이트하거나 적절한시기에 발표자에게 알릴 수 있습니다.
그런데 Visual Studio 2012 및 2013에서는 디자이너의 일반 컨트롤이 매우 멋지게 처리되는 것 같습니다.
사이드 노트로서 저는 최근에 iOS 개발에 관심을 기울이고 있습니다. 한 가지 내가 감동했습니다. 프로세스의 일부로 MVC에서 구운 방법입니다. .NET과 달리 모든 방식의 해킹 방법을 생각해 낼 수 있습니다. 나는 이것으로부터 몇 가지 교훈을 얻었고 그것들을 .NET에 적용했다. 그리고 나의 두뇌가 너무 많이 깨지는 것을 발견했다. 특히 내가 좋아하는 한 가지는리스트 컨트롤이 작동하는 방식입니다. Qt (C++ 프레임 워크) MVC 컨트롤과 매우 비슷합니다. 객체의 모 놀리 식 백엔드 목록을 가질 수있는 능력은 보이는 영역에서만 필요한 것만 보유하고 있기 때문에 .NET이 기본 동작을 제어하는 것보다 훨씬 더 좋습니다.
어쨌든 .NET 데이터 바인딩과 함께 행운을 빈다. 저는 개인적으로 새로운 사람들에게 권하고 싶습니다 ... 그것을 사용하지 말고 적절한 시간에 모든 값을 명시 적으로 할당하는 컨트롤러를 얻으십시오. 그러나 편안하고 짜증나는 뉘앙스를 이해한다면, 나는 누군가에게 도달했다고 말한 바가 있습니다.
왜 모델을 뷰로 언급하는 것이 좋지 않은가요? 나는 모델을 IView에 바인딩하기 위해 표현 자에게 메서드를 추가하기 만하면됩니다. –
@WiktorZychla : 프리젠터 내에서 뷰와 모델을 캡슐화합니다. 의도는 발표자 바깥에있는 어떤 물체도 모델을 포함하여보기가 어지럽 혀서는 안된다는 것입니다. 그렇지 않으면 다른 오브젝트가 뷰의 제어를 대신하는 함수 크립이 발생할 수 있습니다. – IAbstract
그런 다음 발표자를보기 모델로 만듭니다. 즉, 발표자에서 모델을 흡수하고보기 모델과 마찬가지로보기의 발표자에 바인딩합니다. 이는 권장되는 접근 방법입니다. –