2010-08-12 27 views
5

Tuyên bố từ chối trách nhiệm: Trong tab câu hỏi này, một trang, một hộp thoại thực sự có cùng ý nghĩa, xin lỗi. Lý do của tôi: Tôi không chắc sản phẩm cuối cùng sẽ trông như thế nào - một loạt các cửa sổ riêng biệt hoặc tất cả trong một.Tìm kiếm một ví dụ Wizard tuyệt vời được triển khai với WinForms và/hoặc thiết kế lời khuyên regrding

Tôi đang tìm cách cải thiện Trình hướng dẫn hiện có, khó duy trì được nướng bằng WinForms. Tôi cần phải cố gắng để giữ cho cái nhìn và cảm nhận về giống nhau, nhưng tôi cần phải làm sạch logic nội bộ. Có 5 hộp thoại trong tổng số, tất cả đều được hiển thị cái khác (sau khi nút Tiếp theo được nhấp vào khóa học) bên trong một phương pháp khổng lồ. Cách nhảy qua lại là ... 5 hoặc 6 nhãn và GOTO!

Bây giờ, thuật sĩ này là tuyến tính, không phải là một cây. Từ bất kỳ hộp thoại/trang nào, bạn sẽ có thể truy cập tối đa hai trang khác. Bằng cách nào đó danh sách doubly0linked đến với tâm trí. Hiện tại, có 5 * 4 = 20 chuyển tiếp trạng thái tiềm năng, trong khi chỉ 2*1 + 3*2 = 8 trong số đó là hợp lệ. Tôi không phải sử dụng goto s. Chúng thường là ác, và trong trường hợp này chúng là - rất khó để duy trì điều này rồi ... và tôi đang nghĩ đến việc thêm một trang thứ 6 khác. Lý do tại sao goto s có nhiều khả năng là do A) áp lực thời gian khi phiên bản 1.0 đã được thực hiện, B) Đó là 5 năm trước, vì vậy các ví dụ/hướng dẫn tốt nhất về Wizards có sẵn tại thời điểm đó có thể không tuyệt vời.

Hiện tại, hầu hết các trang của Trình hướng dẫn đều yêu cầu đầu vào của người dùng. Các trang tiếp theo được hiển thị tùy thuộc vào những gì người dùng đã nhập. Nếu người dùng nói trên trang 3 và quyết định ht một nút quay lại tất cả các cách để 1, và đã không thay đổi bất cứ điều gì, và nhấn Next hai lần, sau đó nhà nước không nên thay đổi. Tuy nhiên, việc thay đổi mọi thứ trên trang x nói chung sẽ làm mất hiệu lực nội dung trên các trang x + 1 và hơn nữa. Tuy nhiên, có một số ngoại lệ, vì một số hoặc tất cả các cài đặt trên trang x có thể phụ thuộc vào trang x-1, x-2, v.v. nhưng các trang x + 1, x + 2, v.v. không phụ thuộc vào x đó cho một số x.

Tôi hy vọng mọi thứ rõ ràng cho đến nay. Chúng tôi cố gắng giúp người dùng bằng cách mặc định một số nội dung cho họ. Cách mọi thứ được lưu trữ cũng không tuyệt vời. Hộp thoại có các thuộc tính đọc/ghi, từ/đến công cụ nào được sao chép vào/từ các điều khiển thực tế. Sau đó, trong phương pháp chính, có một "siêu lưu trữ" chứa kho lưu trữ cho mỗi trang. Vì vậy, khi người dùng được thực hiện với trang x và lần truy cập tiếp theo, công cụ đầu tiên được sao chép từ các điều khiển vào bộ nhớ cục bộ cho lớp và sau đó nội dung đó được lưu vào thành viên thích hợp của siêu lưu trữ.

Mảng (của hộp thoại/kho lưu trữ) và chỉ mục không được sử dụng. Có một cách riêng biệt nhưng tương tự "tạo ra & điền" logic cho mọi đích đến (nhãn). Các đối tượng hộp thoại bị vứt bỏ khi trang không còn hiển thị nữa (chúng không được xử lý, nhưng mỗi khi chúng được hiển thị, chúng sẽ được tạo lại và tái tạo lại một lần nữa. Tôi không tin điều này là cần thiết, vì chỉ cần xử lý đơn, và sau khi nó đã được hiển thị, và đóng lại, tôi tin rằng nó có thể được hiển thị một lần nữa trong cùng một trạng thái, mà không cần phải nhập lại các điều khiển. nhưng điều này là không phải là rất dễ bảo trì, vì vậy tôi cũng có thể sửa chữa nó tất cả lên

tôi đang nghĩ đến:.

  1. hộp thoại Store trong một bộ sưu tập, chẳng hạn như một mảng, nhưng tốt nhất là DLL vì tôi chỉ có thể di chuyển tiến lên 1 hoặc lùi 1 hoặc chỉ một trong hai tùy chọn Tôi đã liệt kê (cho hộp thoại đầu tiên và cuối cùng).
  2. Thực tế các tab/trang của tôi mở rộng một lớp trừu tượng chung (vì các nút "tiếp theo", "quay lại", "thoát" và hành vi của chúng là phổ biến cho tất cả).
  3. Mỗi tab/trang/hộp thoại (cùng một mục đích cho câu hỏi này, xin lỗi vì nhầm lẫn) sẽ có thuộc tính chỉ đọc hiển thị cho lớp "dây dẫn".Các thuộc tính này sẽ lấy được từ các giá trị trong các điều khiển (nguồn thông tin thực sự), đôi khi các thuộc tính sẽ xoa bóp các giá trị này một chút. Nó sẽ là trách nhiệm của các "dây dẫn" để lấy những người và đưa chúng vào lưu trữ. Khi dây dẫn muốn điền vào hộp thoại bằng một phương thức duy nhất (hãy gọi nó là "hạt giống"). Tôi có một chút khó khăn ở đây, vì các tham số cho mỗi phương thức hạt giống sẽ khác nhau. Tôi muốn có thể tận dụng lợi thế của việc gõ mạnh mẽ, cũng như giữ những thứ chung chung. Tôi nghi ngờ rằng một cái gì đó nên cung cấp cho. Tôi có thể chuyển từ điển vào từng phương pháp hạt giống, nhưng cảm giác quá Pythonic, giống như gõ vịt. Tôi sẽ không biết cho đến khi thời gian chạy nếu tôi hơi say. Ngoài ra, việc đóng gói và giải nén từ điển tốt hơn luôn phù hợp với bất kỳ trang cụ thể nào. Đây là nơi bạn sẽ đến.
  4. Bộ nhớ toàn cầu có thể là một từ điển khổng lồ. Tôi có thể được xử lý kỷ luật đủ để giữ cho tất cả các phím khác nhau, hoặc tiền tố tên của họ với "p1_" thông qua "p5_" tùy thuộc vào một trang, chỉ để chắc chắn. Tôi chắc chắn rằng các chương trình khác cũng tồn tại. Có trên từ điển khổng lồ có thể được thuận tiện ở cuối cùng - có thứ tự mà người dùng nhập vào được lắp ráp sẽ không quan trọng, miễn là nó được thực hiện một cách chính xác. Tôi cũng có thể có một máy nhà nước ... loại. Đây là nơi tôi cũng bị lạc trong thiết kế. Nếu tôi giữ mọi thứ trong từ điển, tôi sẽ phải thực hiện rất nhiều logic có điều kiện, chẳng hạn như: nếu tôi ở trang 2 và tôi thực hiện thay đổi, thì tôi thường (có thể có ngoại lệ) cần thực hiện các giá trị mặc định cũ nếu bất kỳ trang nào 3,4,5 không hợp lệ. Tùy thuộc vào mức độ xấu xí của nó, nó có thể không tốt hơn nhiều so với thiết kế dựa trên goto hiện tại. Tuy nhiên, tôi nghĩ rằng tôi có thể làm tốt hơn, vì tôi có thể thực hiện logic của tiểu bang hoặc trạng thái chuyển tiếp cụ thể của mình với một nhóm đại biểu, tay cầm được lưu trữ trong hai từ điển (một cho từ kế tiếp, một cho lưng), trạng thái hiện tại là Chìa khóa.

Như bạn có thể thấy, có một vài thách thức. Tôi hy vọng, tuy nhiên, bởi vì suy nghĩ thông qua một thiết kế Wizard tốt là một bánh xe chắc chắn đã được [phát minh lại] trước đây. Có lẽ bạn có thể đề xuất một ứng dụng C#/mono nguồn mở đi kèm với một thuật sĩ tuyến tính, nhưng không tầm thường, để tôi có thể xem qua việc triển khai. Heck, thậm chí có thể Java/Swing có lẽ sẽ phù hợp với tôi miễn là Wizard là tương tự trong tự nhiên. WPF sẽ là một thách thức đối với tôi, tôi không muốn có 2 vấn đề thay vì 1.

Hãy cho tôi biết những gì bạn có thể nghĩ đến. Tôi có nên giữ gotos nhưng dọn dẹp các bộ phận khác nhiều nhất có thể không? Hãy đặt câu hỏi. Cảm ơn,

-HG

Trả lời

0

tại sao không tạo ra một lớp có các thuộc tính cho từng lĩnh vực đầu vào cho từng trang và theo dõi chúng trong khi người dùng nhấp chuột thông qua các wizard, như vậy bạn sẽ có thể nhảy trở lại và giữa một số trang và vẫn giữ dữ liệu đã được người dùng thêm vào trong phiên của anh ấy. thậm chí bạn có thể có xác thực đầu vào trong các mô hình trang này để khi người dùng nhấp vào tiếp theo, bạn có thể làm điều gì đó như

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

điều này là nếu tôi hiểu một số vấn đề của bạn.

(đối với việc theo dõi những trang mà bạn có thể có các mô hình trang thực hiện cùng một giao diện và tạo ra một cái gì đó List<IPageModel> hay và thêm các mô hình trang để nó)

0

Tôi bỏ phiếu cho kiến ​​trúc thượng tầng như một tham số truyền cho từng trang vì nó đang được hiển thị. Tham số thứ hai sẽ là hướng mà chúng tôi đến trang (Tiếp theo hoặc Quay lại). Nếu đó là Quay lại thì chỉ hiển thị dữ liệu đã tồn tại. Nếu đó là Tiếp theo, sau đó sử dụng dữ liệu từ các trang trước (được tìm thấy trong cấu trúc thượng tầng) để hiển thị dữ liệu thích hợp trong trang hiện tại. Trang cũng sẽ có thông tin nếu nó được hiển thị lần đầu tiên. Nếu đó là sau đó nó sẽ cung cấp dữ liệu mặc định, và nếu nó không thì nó có thể tái chế dữ liệu hiện có quy cho trang đó (miễn là chúng không mâu thuẫn với dữ liệu từ các trang trước). Nhà nước chỉ là một số, được tăng lên hoặc giảm dần sau mỗi trang.Mã chính là một vòng lặp trong khi chỉ hiển thị một trang cho trạng thái hiện tại và cập nhật trạng thái khi người dùng kết thúc với trang. Khi người dùng rời khỏi trang cuối cùng với Tiếp theo sau đó thoát khỏi vòng lặp.

Nếu có các trang tùy chọn thì mã chính sẽ phức tạp một chút, vì sau đó bạn cần một logic để quyết định trang tiếp theo là gì và tất cả mọi thứ khác vẫn như cũ.

+0

Hm ... theo cách đó, mỗi "trang" phải biết tất cả những gì khác là. Tôi đang nghĩ đến việc có thể làm mới một "trang" sau khi nó được xây dựng với bất kỳ thông tin quan trọng mới nào và có trang trả về bất kỳ thông tin quan trọng nào được yêu cầu. Sau đó, một số loại điều khiển từ bên ngoài ... –

+0

Trang ở vị trí tốt nhất để "biết" người dùng cần xem gì trong trang đó và biết thông tin nào cần để đạt được điều đó. Và trang yêu cầu tất cả các thông tin mà nó requiers :-). Không có lý do gì để che giấu các thông tin từ trang, vì không cần phải làm cho toàn bộ mô hình quá mô-đun. Tức là, trừ khi bạn muốn sử dụng lại "mô-đun" trong một dự án khác. Trong giải pháp này, bạn vẫn có thể làm mới trang và trên thực tế, bạn nên làm mới mỗi khi trang được hiển thị. Nhưng, nếu bạn có một giải pháp trong tâm trí, sau đó chỉ cần đi cho nó. – Dialecticus

0

Tạo một biểu tượng thắng sẽ lưu trữ điều khiển người dùng triển khai giao diện. làm cho tất cả các trang điều khiển người dùng thực hiện giao diện này và kiểm soát luồng từ biểu mẫu cấp cao nhất của bạn. nếu bạn thích cách tiếp cận này, tôi có thể khai thác một số mã cũ để cung cấp thêm chi tiết.

+0

điều này có vẻ hứa hẹn, và có, tôi cần mã trước khi tôi có thể quyết định. Tôi sẽ không bỏ phiếu ngay cả khi nó không hoạt động. Tôi khuyến khích những người khác không trừng phạt những nỗ lực giúp đỡ. –

1

Tôi có một số WinForms wizard mã này là kiến ​​trúc chung:

Mở thuật sĩ chính có StepList Như Danh sách (Tất baseWizardStep) .. danh sách tất cả các bước có thể được tạo ra khi các hình thức chính là phù thủy.

Ngoài ra nút Quay lại và Hủy tiếp theo.

Như với Alex ở trên, có biểu mẫu chính cơ sở (baseWizard) với bảng điều khiển lưu trữ điều khiển người dùng cho bước hiện tại. Mỗi bước của trình hướng dẫn chính nó là điều khiển người dùng (Inherits từ baseWizardStep kế thừa từ UserControl) baseWizardStep có một số sự kiện được xây dựng (ArrivAtStep, ValiateStep, LeaveStep, v.v.) Cũng trong một phụ InitliaseStep có trình hướng dẫn chính làm tham số và cửa hàng một ref để hình thức thuật sĩ chính trong tài sản. Tất cả các bước truy cập trình hướng dẫn chính để lưu trữ dữ liệu của chúng trong thuộc tính/đối tượng/tập dữ liệu vv .. (Lưu trữ dữ liệu thường được thực hiện trên sự kiện LeaveStep) Các bước tải dữ liệu vào các điều khiển của chúng trên sự kiện ArriveAtStep. Đôi khi tôi cần chia sẻ các bước thủ thuật giữa nhiều trình thuật sĩ, trong trường hợp đó, mainWizard thực hiện một giao diện và các bước của trình thủ thuật sẽ đưa thuộc tính thuật sĩ chính của chúng đến giao diện để truy cập/lưu trữ dữ liệu.

Tôi có 2 sự kiện điều khiển luồng hàng đầu thông qua trình hướng dẫn.

Nếu bạn không xử lý bất kỳ sự kiện nào trong số 2 sự kiện này, trình hướng dẫn sẽ chuyển từ 1st trong StepList sang bước cuối cùng theo thứ tự từng bước một.

Sự kiện 1: Nếu bạn xử lý ShoudlStepOccur sự kiện này cho phép nhà phát triển quyết định một bước xảy ra trong danh sách các bước (để bạn có thể bỏ qua bước) Điều này dường như đối phó với hầu hết các trình thuật sĩ trong một ẩn dụ dễ hiểu. Sự kiện cung cấp cho bạn bước và lợi thế (Chuyển tiếp, quay lại)

Sự kiện 2: (kiểm soát nâng cao) Có sự kiện khác trên biểu mẫu chính NavigateToStep, sự kiện cung cấp cho bạn bước mà nó dự định truy cập, nhưng bạn có thể thay đổi nó để điều hướng đến một bước hoàn toàn khác. Chúng tôi sử dụng điều này để đi vòng trong một vòng lặp nhiều lần (Ví dụ: Trong Enroll trên một thuật sĩ khóa học, chúng tôi đi throurgh một số bước của thuật sĩ nhiều lần cho mỗi khóa học)

Tôi cũng có một lưới liệt kê tất cả các bước với bước hiện tại được đánh dấu và người dùng có thể nhấp vào để nhảy thourgh trình hướng dẫn. Tôi sử dụng sự kiện StepShouldOccur để biết các bước nào sẽ không hiển thị trong danh sách bước bất kỳ lúc nào.

Một gatchas: -Khi đóng trình hướng dẫn, bạn phải vứt bỏ các bước không được lưu trữ trong bảng điều khiển và chỉ nằm xung quanh trong StepList vì chúng sẽ không releae cửa sổ của họ xử lý khác.

Không chắc chắn bao nhiêu ý nghĩa đó là làm như vậy tôi sẽ để nó ở đó.

Có lẽ một trong những ngày này tôi sẽ đặt mã trình hướng dẫn này lên trên dự án mã hoặc một cái gì đó, tôi khá hài lòng với cách nó hoạt động cho chúng tôi.

+0

Cảm ơn, bạn có thể chia sẻ mã không? –

Các vấn đề liên quan