2009-04-29 39 views

Trả lời

14

Có một vài tùy chọn. Điều quan trọng là bạn bắt đầu thiết kế nó vào đầu trong dự án. Cố gắng thêm nó vào một dự án hiện có có thể là rất tốn kém nếu nó không được thiết kế với khả năng này trong tâm trí.

Có một vài mô hình cơ bản mà bạn sẽ muốn tận dụng:

  1. MVC hoặc Observer mẫu. Chìa khóa đầu tiên không phải là quá nhiều thực hiện tôn giáo hoặc mô hình-zealot của kiến ​​trúc cấp cao của bạn. Điều quan trọng là phần mềm của bạn nhận ra sự khác biệt giữa trạng thái hiện tại của nó và trạng thái được hiển thị và tách riêng một cách thích hợp. Cần phải có một khớp nối chung được xác định rõ ràng giữa trạng thái trực quan và trạng thái ứng dụng của bạn. Điều này cung cấp cho bạn kiến ​​trúc chung mà bạn cần để tạo một lệnh (xem # 2).

  2. Mẫu Command. Bạn nhận được rất nhiều chất lượng với mẫu lệnh (mặc dù nó có thể đi kèm với chi phí của một số mã trông giống như nó sẽ được tạo bởi trình thủ thuật). Cách tiếp cận cụ thể mà bạn thực hiện với mẫu lệnh có thể thay đổi (một lớp cho mỗi lệnh với việc thực hiện thông qua ghi đè so với một lớp trên nhiều lệnh bằng cách thực hiện thông qua trình xử lý sự kiện, vd), nhưng các lệnh là lớp "hành động" mà @Ralph đề xuất cấu trúc ngăn xếp xung quanh.

    Điều này có thể hơi phức tạp, nhưng cách tiếp cận chung sẽ là lắng nghe một sự kiện sẽ "chuyển" dữ liệu từ trạng thái trực quan sang trạng thái ứng dụng. Sự kiện Validated có thể là một móc tốt cho một số Textbox. Sự kiện Click sẽ có ý nghĩa hơn đối với một số Button. Khi cam kết đó xảy ra, bạn tạo lệnh kết hợp với điều khiển đó, bạn cố thực hiện lệnh, và bạn thêm lệnh vào ngăn xếp hoàn tác của bạn nếu lệnh hoàn tất thành công. Bây giờ bạn đang theo dõi chính xác những gì đang xảy ra và chính xác dữ liệu đang xảy ra.

  3. Mẫu Memento. @JP Kéo ra miếng cuối cùng của câu đố. Bạn có thể sử dụng một vật lưu niệm trên lệnh đã lưu để lưu trữ trạng thái của điều khiển bị ảnh hưởng trước khi lệnh được thực thi. Điều này, kết hợp với một thành viên UnExecute() trên giao diện lệnh của bạn, nên là phần cốt lõi cuối cùng của thiết kế mà bạn cần để thực hiện nhiệm vụ của bạn.

Điều tốt đẹp về cách tiếp cận có cấu trúc giống như bây giờ bạn có điểm mở rộng tự nhiên cho hành vi bổ sung cần thực hiện trên cơ sở lệnh. Ví dụ, các giao dịch là một sự phù hợp tự nhiên. Trong dự án hiện tại của tôi, tôi đang sử dụng giao diện WPF ICommand (trong dự án winforms của tôi) để cung cấp phản hồi về việc liệu một lệnh đã cho CanExecute() tại bất kỳ thời điểm nào đã cho. Điều này cho phép tôi bật và tắt tiện ích con của giao diện người dùng một cách thích hợp theo cách điều khiển hoàn toàn bằng lệnh. :)

Điều đáng tiếc là không có nhiều hỗ trợ cho cấu trúc này được xây dựng trong Winforms (theo như tôi biết), vì vậy bạn sẽ cần phải xây dựng hầu hết nó từ đầu. Không có phần nào đặc biệt phức tạp, nhưng bạn có thể thấy mình tạo ra một số tiền hợp lý của mã chủ yếu là soạn sẵn cho mỗi lệnh. Nó cũng là một kỹ thuật thiết kế phổ biến. Để nó có hiệu quả, nó phải được sử dụng nhất quán trong các phần thích hợp của ứng dụng. Điều này làm cho việc trang bị thêm các chức năng khá tốn kém, đặc biệt nếu mã ban đầu được kết hợp chặt chẽ và hăng hái.

+0

Tôi rõ ràng là chú ý đến một số chi tiết ở đây vì lợi ích của không gian, nhưng tôi nghĩ rằng tất cả các phần quan trọng đều ở đó. :) –

0

Phụ thuộc vào số lượng hoàn tác, bạn muốn có.

Bạn có thể lưu trữ các giá trị trước khi được "cam kết" theo một nghĩa nào đó trong bộ sưu tập Cấp biểu mẫu cho từng điều khiển, bạn có thể "Khôi phục" khi nhấp vào nút để người dùng quay lại.

3

Tôi không chắc liệu WinForms/.Net có một số tính năng Hoàn tác dựng sẵn mà bạn có thể tận dụng hay không. Nhưng những gì bạn đang thực sự tìm kiếm là một cơ sở hạ tầng Stack để giúp bạn quản lý một danh sách các hành động. Bạn cần phải tạo một số loại đối tượng "action" để biểu diễn các hành động mà người dùng có thể thực hiện và khi chúng tiến hành thông qua ứng dụng bạn sẽ cần phải đẩy các hành động này lên Stack. Khi họ nhấn nút hoàn tác hoặc Ctrl-Z hoặc bất kỳ phương thức nào để khởi động tác vụ hoàn tác, bạn sẽ bật ra hành động hiện tại và khôi phục trạng thái ứng dụng về hành động trước đó.

Đây là tổng quan cấp độ rất cơ bản và cao về cách thức này sẽ hoạt động nhưng tôi tưởng tượng rằng việc triển khai tính năng như vậy có thể khá phức tạp. Chỉ cần hình dung làm thế nào nó cần để làm việc cho một chương trình như Adobe Photoshop. : O

1

CTRL + Z hoạt động trên các điều khiển riêng lẻ.

Nếu bạn làm việc với dữ liệu và BindingSource, bạn có thể "hoàn tác" những thay đổi không được lưu giữ cho bản ghi bằng cách gọi hàm CancelEdit hoặc cách khác bạn có thể tải lại dữ liệu cho cơ sở dữ liệu.

2

Đây có thể không phải là cách tốt nhất để thực hiện tùy thuộc vào những gì bạn đang cố gắng hoàn thành, nhưng bạn có thể sử dụng richtextbox và gọi phương thức hoàn tác được tích hợp trong điều khiển đó.

Ví dụ:

1

Đề nghị của tôi là để xác định khôi phục trở lại cụ thể các yêu cầu và lợi ích thiết thực của nó trước khi bắt đầu thiết kế và thực hiện. Tôi thừa hưởng một ứng dụng WinForms sử dụng một hoạt động đa tuần tự hoàn tác thông qua một chồng các đối tượng "hành động" chung trong nội bộ. Tuy nhiên, hóa ra là không ai trong số những người dùng của ứng dụng tôi đã nói chuyện với việc sử dụng và cũng không yêu cầu tính năng này! Và cách ứng dụng cụ thể này hoạt động, nếu tôi là người dùng ứng dụng, tôi cũng sẽ không thấy bản thân mình sử dụng tính năng này.

Chức năng hoàn tác có thể hữu ích hơn trong trường hợp này nếu nó là 'hoàn tác' có chọn lọc; trong đó người dùng có thể chọn bất kỳ thao tác/chỉnh sửa nào của một số chỉnh sửa trước đó, trước khi dữ liệu cam kết và khôi phục bản chỉnh sửa đó về trạng thái ban đầu, thay vì chỉ có thể hoàn tác thao tác cuối cùng trước tiên. , vv đó là cách nó được thực hiện.

Trong mọi trường hợp, ứng dụng do đó gây ra sự phức tạp và không cần thiết, làm cho việc 'bừa bộn' trở nên khó khăn hơn và chậm hơn và thực hiện các thay đổi và cải tiến đối với chức năng hiện có, trong trường hợp này ít hoặc không có lợi ích thực tế. Kể từ khi tôi kế thừa dự án, tôi đã triển khai các tính năng mới mà không hoàn tác và không ai có bất kỳ khiếu nại nào.

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