2010-08-12 3 views
5

면책 조항 :이 질문 탭의 페이지에서 대화 상자는 실제로 동일한 것을 의미합니다. 내 변명 : 나는 최종 제품이 어떻게 보일 것인가에 대해 확신하지 못한다.WinForms 및/또는 조언 재 설계로 구현 된 위저드 예제 찾기

WinForms로 구운 기존의 유지 관리하기 어려운 마법사를 개선하기 위해 노력하고 있습니다. 나는 모양과 느낌을 동일하게 유지하려고 노력해야하지만 내부 논리를 정리해야합니다. 총 5 개의 대화 상자가 있으며, 모두 하나의 거대한 방법으로 차례대로 표시됩니다 (다음 버튼을 클릭 한 후). 앞뒤로 이동하는 방법은 ... 5 또는 6 개의 레이블과 GOTO!

이제이 마법사는 트리가 아닌 선형입니다. 하나의 대화/페이지에서 최대 두 개의 다른 페이지로 이동할 수 있습니다. 여하튼 두 배로 연결된 목록이 떠오른다. 지금은 5 * 4 = 20 잠재적 인 상태 천이가 있으며 그 중 2*1 + 3*2 = 8 만 유효합니다. 나는 goto을 사용할 필요가 없습니다. 그들은 일반적으로 악마이며,이 경우 그들은 이미 이것을 유지하기가 어렵습니다 ... 또 다른 6 페이지를 추가 할 생각입니다. goto이있는 이유는 A) v. 1.0을 만들 때의 시간 압력, B) 5 년 전 이었기 때문에 당시 가능한 마법사에 대한 최고의 예제/자습서는 그리 좋지 않았을 수 있습니다.

이제 대부분의 마법사 페이지는 사용자의 입력을 요구합니다. 이후 페이지는 사용자가 입력 한 내용에 따라 렌더링됩니다. 사용자가 3 페이지에서 말하고 1로 뒤로 버튼을 놓고 아무 것도 변경하지 않고 다음 버튼을 두 번 누르면 상태가 변경되지 않아야합니다. 그러나 페이지 x의 내용을 변경하면 일반적으로 x + 1 페이지 이상의 내용이 무효화됩니다. 그러나 페이지 x의 일부 또는 모든 설정이 페이지 x-1, x-2 등에 의존 할 수 있지만 페이지 x + 1, x + 2 등은 그 x에 의존하지 않으므로 예외가 있습니다. 일부 x.

지금까지 상황이 분명하기를 바랍니다. 우리는 사용자를 위해 기본값을 설정하여 사용자를 도우려고합니다. 일들이 저장되는 방식도 훌륭하지 않습니다. 이 대화 상자는 실제 컨트롤과 /에서 실제 컨트롤로 복사되는 읽기/쓰기 속성을가집니다. 그런 다음 main 메소드에는 각 페이지의 저장 영역을 보유하는 "수퍼 스토리지"가 있습니다. 따라서 사용자가 페이지 x를 완료하고 다음에 히트하면 물건이 컨트롤에서 클래스에 로컬 인 저장소로 먼저 복사 된 다음 해당 항목이 수퍼 저장소의 해당 멤버에 저장됩니다.

배열 (대화 상자/저장 장치) 및 색인은 사용되지 않습니다. 각각의 goto 대상 (레이블)에 대해 별도의 유사한 "생성 & 채우기"논리가 있습니다. 페이지가 더 이상 표시되지 않을 때 대화 상자 객체가 버려집니다 (삭제되지는 않지만 표시 될 때마다 다시 만들어지고 다시 채워집니다.) 필요하다고 생각하지 않습니다. 단일 핸들이 필요하고, 표시되고 닫힌 후에 컨트롤을 다시 채울 필요없이 동일한 상태로 다시 표시 될 수 있다고 생각합니다. 메모리를 낭비하는 것이 유일한 문제라면, 그러나 것은 매우 유지 보수가 아니기 때문에 나뿐만 아니라 내가 생각하고

을 모두 고칠 수 있습니다.

  1. 저장 대화 상자를 모음에, 같은 배열로, 바람직 DLL 난 단지 수 있기 때문에 앞으로 1 또는 뒤로 1 또는 두 옵션 중 하나만 앞으로 이동하십시오. 나는 (첫번째와 마지막 대화를 위해) 열거했다.
  2. 실제로 "내", "뒤로", "종료"버튼과 그 동작은 모든 사용자에게 공통적이기 때문에 내 탭/페이지가 모두 공통 추상 클래스를 확장하도록하십시오.
  3. 각 탭/페이지/대화 상자 (이 질문의 목적을 위해 동일한 것, 혼란스러워서 죄송합니다)는 "지휘자"클래스에서 볼 수있는 읽기 전용 속성을 갖게됩니다.이러한 속성은 컨트롤 (실제 정보 소스)의 값에서 파생되며 속성은이 값을 약간 마사지합니다. "지휘자"가 그들을 붙잡아서 보관할 책임이 있습니다. 지휘자가 대화 상자에 단일 메서드 ("seed"라고 부름)를 채우려는 경우. 각 시드 메서드의 매개 변수가 달라 지므로 여기서 약간의 어려움이 있습니다. 저는 강력한 타이핑을 활용하고 일반적인 것을 유지할 수 있기를 원합니다. 나는 무언가가 주어져야한다고 생각한다. 나는 각 시드 메서드에 사전을 전달할 수 있지만 오리 타이핑과 같이 너무 파이썬 적이라고 느낍니다. 내가 망쳤다면 실행 시간까지 모르겠다. 또한 주어진 페이지에 대해 사전의 압축과 압축 해제가 항상 일치합니다. 이것은 당신이 올 곳입니다.
  4. 글로벌 스토리지는 하나의 거대한 사전이 될 수 있습니다. 나는 모든 키를 다른 것으로 유지할만큼 충분히 훈련받을 수 있으며, 페이지에 따라 "p1_"에서 "p5_"까지 이름 앞에 접두사를 붙일 수 있습니다. 나는 다른 계획도 존재한다고 확신합니다. 거대한 사전에 있으면 편리하게 끝낼 수 있습니다. 사용자 입력이 제대로 조합 된 순서는 문제가되지 않습니다. 나는 또한 상태 머신을 가질 수있다. 이것은 내가 디자인에서 길을 잃는 곳이기도하다. 만약 내가 사전에 물건을 가지고 있다면, 나는 많은 조건절 논리를 수행해야 할 것이다. 만약 내가 2 페이지에 있고 변경을하면 보통 (예외가있을 수있다) 오래된 기본값을 만들 필요가있다. 3,4,5 페이지는 유효하지 않습니다. 얼마나 추한 지에 따라 현재의 goto 기반 디자인보다 훨씬 좋을 수도 있습니다. 그러나 나는 여러 가지 대리자를 사용하여 내 상태 또는 상태 전환 관련 논리를 구현할 수 있기 때문에 더 잘할 수 있다고 생각합니다. 핸들은 두 개의 사전에 저장됩니다 (다음에 하나, 뒤에 하나). 현재 상태는 키.

아시다시피 몇 가지 문제점이 있습니다. 그러나 좋은 마법사 디자인을 통해 사고하는 것은 분명히 전에 발명 된 바퀴이기 때문에 나는 희망적입니다. 아마 당신은 오픈 소스 인 C#/mono 응용 프로그램을 추천 할 수 있습니다.이 응용 프로그램은 선형이지만, 사소한 마법사는 아니므로 구현을 들여다 볼 수 있습니다. 젠장, 어쩌면 자바/스윙조차 마법사가 자연에서 비슷한 한 아마 나를 적응할 것이다. WPF는 나에게 또 다른 도전이 될 것입니다. 나는 1 대신에 2 가지 문제를 가지고 싶지 않습니다.

당신이 생각할 수있는 것을 알려주세요. 내가 할 수있는 한 최대한 많은 부분을 정리해야 하나? 부담없이 질문하십시오. 감사합니다,

-HG

답변

0

하지 각 페이지에 대해 각 입력 필드에 대한 속성을 가진 클래스를 생성하고, 사용자가 마법사를 클릭 동안 다시 도약 할 수있을 것입니다 그런 식으로 그들을 추적 왜 사용자가 자신의 세션에서 추가 한 데이터를 유지할 수 있습니다. 사용자가 다음에 당신은 내가 문제의 일부를 이해하면 이것이

if(!page1model.IsValid) 
{ 
    List<RuleViolation> ruleViolations = page1model.GetRuleViolations(); 
} 

처럼 뭔가를 할 수 클릭 그렇게하면 당신도이 페이지 모델의 입력 유효성 검사를 가질 수있다.

나는 각 페이지에 전달되는 매개 변수로 상부 투표

0

을 (당신은 페이지 모델은 동일한 인터페이스를 구현하고 List<IPageModel> 또는 무언가를 작성하고 페이지 모델을 추가 할 수 페이지를 추적하는) 보여지고있는 그대로. 두 번째 매개 변수는 우리가 페이지를 방문한 방향 (Next 또는 Back)입니다. Back의 경우 이미 존재하는 데이터 만 표시합니다. 그것이 다음이면 이전 페이지의 데이터를 사용하여 현재 페이지에 적절한 데이터를 표시하십시오. 페이지가 처음으로 표시되는 경우에도 정보가 있어야합니다. 그런 경우 기본 데이터를 제공해야하며 그렇지 않은 경우 이전 페이지의 데이터와 모순되지 않는 한 해당 페이지의 기존 데이터를 재활용 할 수 있습니다. 상태는 숫자 일 뿐이며 각 페이지마다 증가 또는 감소합니다.주 코드는 현재 상태에 대한 페이지를 표시하고 사용자가 페이지를 완료 할 때 상태를 업데이트하는 하나의 작은 while 루프입니다. 사용자가 다음 페이지로 나가면 루프가 종료됩니다.

선택 페이지가있는 경우 다음 페이지 (그리고 이전 페이지 모두)를 결정할 논리가 필요하기 때문에 주 코드가 약간 복잡해 지지만 나머지는 여전히 동일합니다.

+0

흠 ... 그런 식으로 각 "페이지"는 다른 모든 것들을 알아야합니다. 나는 새로운 중요한 정보로 건설 된 후 "페이지"를 새로 고칠 수 있으며, 요청 된 중요한 정보가 페이지에 반환되도록 할 생각입니다. 그런 다음 외부에서 일종의 컨트롤러 ... –

+0

페이지는 사용자가 해당 페이지에서 볼 필요가있는 "알기"가장 좋은 위치에 있으며이를 달성하기 위해 필요한 정보를 알고 있습니다. 그리고 페이지에는 그것이 요구하는 모든 정보가 필요합니다 :-). 모든 것을 지나치게 모듈화 할 필요가 없기 때문에 페이지에서 정보 비트를 숨길 이유가 없습니다. 즉, 다른 프로젝트에서 "모듈"을 재사용하지 않으려는 경우입니다. 이 솔루션에서는 페이지를 새로 고칠 수 있으며 사실 페이지가 표시 될 때마다 새로 고쳐야합니다. 하지만 솔루션을 염두에 둔다면 그냥 사용해보십시오. – Dialecticus

0

인터페이스를 구현하는 사용자 정의 컨트롤을 호스팅하는 하나의 winform을 만듭니다. 이 인터페이스를 구현하는 모든 페이지를 사용자 컨트롤로 만들고 최상위 양식에서 흐름을 제어하십시오. 이 방법이 마음에 들면 좀 더 자세한 정보를 얻기 위해 오래된 코드를 파헤 칠 수 있습니다. 주요 마법사에

이 (baseWizardStep의) StepList으로 목록을 .. 마법사 기본 양식 인 경우 생성 가능한 모든 단계의 목록 :

+0

이것은 유망 해 보입니다. 그렇습니다. 내 마음을 결정하기 전에 코드가 필요합니다. 나는 그것이 효과가 없더라도 투표를하지 않겠습니다. 나는 다른 사람들도 도움을 시도하는 것을 처벌하지 않도록 권장합니다. –

1

나는이 일반적인 아키텍처 일부 윈폼 마법사 코드가 있습니다.

다음 뒤로 및 취소 버튼.

위의 Alex와 마찬가지로 현재 단계에 대한 사용자 정의 컨트롤을 호스팅하는 패널이있는 기본 클래스 (baseWizard) 기본 폼을가집니다. 각 마법사 단계 자체가 사용자 정의 컨트롤입니다 (UserControl에서 상속 한 baseWizardStep에서 상속 받음) baseWizardStep에는 ArriveAtStep, ValiateStep, LeaveStep 등의 이벤트가 내장되어 있습니다.또한 기본 마법사를 매개 변수로 사용하고 저장하는 InitliaseStep 하위 재산에있는 주요 마법사 모양에 참고. 모든 단계는 기본 마법사에 액세스하여 속성/개체/데이터 집합 등에 데이터를 저장합니다. (데이터 저장은 일반적으로 LeaveStep 이벤트에서 수행됩니다.) 단계는 ArriveAtStep 이벤트의 컨트롤에 데이터를로드합니다.

많은 마법사에서 마법사 단계를 공유해야하는 경우가 있습니다.이 경우 mainWizard는 인터페이스를 구현하고 마법사 단계에서는 기본 마법사 속성을 데이터 액세스/저장 인터페이스로 전송합니다.

마법사를 통해 제어 흐름이 2 개 있습니다.

이러한 2 가지 이벤트 중 하나라도 처리하지 않으면 마법사는 StepList의 첫 번째 항목에서 마지막 순서까지 한 번에 한 단계 씩 진행합니다.

이벤트 1 : ShoudlStepOccur를 처리하는 경우이 이벤트를 통해 개발자는 단계 목록에서 단계를 수행해야하는지 결정할 수 있습니다 (단계를 건너 뛸 수 있습니다). 이는 대부분의 마법사를 쉽게 이해할 수있는 비유에 대처하는 것처럼 보입니다. 이벤트는 단계와 이뇨를 제공합니다. (앞으로, 뒤로)

이벤트 2 : (고급 제어) 기본 형식 NavigateToStep에 다른 이벤트가 있습니다. 이벤트는 가고자하는 단계를 제공하지만 완전히 다른 단계로 이동하도록 변경할 수 있습니다. 이 방법을 사용하여 여러 번 루프를 반복합니다 (예 : 코스 마법사 등록에서 마법사의 몇 가지 단계를 한 번씩 여러 번 반복합니다)

또한 모든 단계를 나열하는 표가 있습니다 현재 단계가 강조 표시되고 사용자가 마법사를 클릭하여 점프 할 수 있습니다. StepShouldOccur 이벤트를 사용하여 언제든지 단계 목록에서 어떤 단계를 표시할지 알 수 있습니다.

가젯 1 개 : - 마법사를 닫을 때 패널에 호스트 된 경로가없고 단계 목록에있는 단계를 처리해야합니다. 그렇지 않으면 단계별로 다른 단계에서 처리해야합니다.

얼마나 많은 의미가 있는지 잘 모르겠습니다. 그래서 거기에두고 갈 것입니다.

어쩌면 요즘에는이 마법사 코드를 코드 프로젝트 등에 넣을 수 있습니다. 나는 그것이 어떻게 작동하는지에 대해 매우 만족합니다.

+0

감사합니다. 코드를 공유 할 수 있습니까? –