2017-01-04 13 views
7

Tôi đã trải qua quá nhiều nỗi đau khi cố gắng chuyển đổi giữa quản lý trạng thái VM cho các chế độ xem khác nhau trong cửa sổ trình bao, cùng với trạng thái VM cho nhiều cuộc đối thoại chỉnh sửa, phương thức hoặc không phương thức và trạng thái cho chính cửa sổ.Cửa sổ thoại chung cho WPF và Prism

Bây giờ tôi muốn làm lại với một cửa sổ vỏ, và hy vọng chỉ có một cửa sổ đối thoại, sau đó cửa sổ và VMS của tôi có ít khớp nối hơn và tôi có thể mượn các mẫu quản lý VM của trình quản lý đối thoại.

Tôi thấy khá nhiều hướng dẫn để quản lý trực tiếp cửa sổ bật lên và ít chế độ tổng quát hơn, nhưng có bất kỳ mẫu hoặc hướng dẫn được thiết lập nào để chỉ sử dụng một cuộc hội thoại để lưu trữ các máy ảo khác nhau không? Thậm chí tốt hơn, có bất kỳ chức năng nào có sẵn trong Prism không?

Tôi muốn thực sự gắn nguyên tắc DRY, và thừa kế trong cả hai quan điểm và máy ảo là thêm phức tạp tôi không thể đủ khả năng trên một nguyên mẫu nhanh chóng lặp lại đầu tiên.

Trả lời

1

Điều này thực sự khá đơn giản, nhưng có một số phức tạp. Trước hết, bạn sẽ muốn tạo một dịch vụ thoại tùy chỉnh. Dịch vụ này có thể đơn giản hoặc phức tạp như bạn muốn. Điều chính mà dịch vụ này sẽ làm là hiển thị một hộp thoại được coi là vỏ của chính nó. Có nghĩa là hộp thoại sẽ giống nhau, nhưng nội dung trong hộp thoại sẽ khác nhau dựa trên thông tin bạn chuyển vào hộp thoại khi bạn gọi. SO này có nghĩa là một hộp thoại tùy chỉnh với các vùng riêng của nó. Để xử lý bằng cách sử dụng các khung nhìn khác nhau trong hộp thoại, tôi sẽ sử dụng dịch vụ điều hướng.

thoại của bạn có thể trông giống như thế này:

public interface IDialogService 
{ 
    void ShowDialog(string uri); 
} 

public class DialogService : IDialogService 
{ 
    private readonly IUnityContainer _container; 
    private readonly IRegionManager _regionManager; 

    public DialogService(IUnityContainer container, IRegionManager regionManager) 
    { 
     _container = container; 
     _regionManager = regionManager; 
    } 

    public void ShowDialog(string uri) 
    { 
     var dialog = _container.Resolve<DialogShell>(); 
     //use a scoped region just in case you can have multiple instances 
     var scopedRegion = _regionManager.CreateRegionManager(); 
     //set the region manager of the dialog to the scoped region 
     RegionManager.SetRegionManager(dialog, scopedRegion); 
     //navigate to show the desired view in the dialog 
     scopedRegion.RequestNavigate(KnownRegionNames.ContentRegion, uri); 
     //show the dialog 
     dialog.Show(); 
    } 
} 

Bạn có thể thay đổi cách tiếp cận này để phù hợp với nhu cầu của bạn một cách chính xác, nhưng bạn sẽ có được ý tưởng.

EDIT: Tôi cũng muốn đề cập đến rằng bạn thậm chí có thể bị điên với điều này bằng cách cho phép hộp thoại của bạn có điều hướng riêng biệt trong đó và duy nhất cho mỗi trường hợp được hiển thị. Tôi có một khóa học Pluralsight cho thấy làm thế nào để làm điều này nếu bạn quan tâm. https://www.pluralsight.com/courses/prism-showing-multiple-shells

+0

Điều này có thể sử dụng được, với một số thích ứng.Tôi không sử dụng điều hướng, chỉ cần đơn giản và các lệnh nút, nhưng đó chỉ là nói chuyện nhỏ trong kịch bản này. Trễ hơn. Cảm ơn bạn. – ProfK

+0

Vì đây là một giải pháp khả thi cho vấn đề của bạn, làm thế nào để đánh dấu nó là câu trả lời? –

4

Tôi không biết về bất kỳ giải pháp nào trong số các giải pháp, nhưng việc tạo triển khai hộp thoại có thể tái sử dụng lại không khó như vậy. Trên thực tế, tôi đã thực hiện một cái gì đó như thế này một vài năm trước đây. Vâng nó đã được trong một công việc khác, vì vậy tôi không có quyền truy cập vào mã nữa. Ngoài ra, tôi không thể nhớ tất cả các chi tiết, nhưng tôi có thể cố gắng cung cấp cho bạn ý tưởng cơ bản về việc triển khai như vậy.

Bạn có thể tạo DialogVm, tính năng này cung cấp chức năng hộp thoại chung.

Trước hết, điều gì cần thiết cho một hộp thoại trong lớp trình bày? Thông thường, ba nút, giống như ...

  • Áp dụng, HủyĐóng (thoại Modification)
  • OkHủy hoặc Không (Câu hỏi hộp thoại)
  • Ok (trong trường hợp có hộp thư)

Như bạn có thể thấy, bạn cần ba lệnh (ICommanddoc). Trên thực tế, tôi đã tạo triển khai DelegateCommand (dựa trên this). ICommand.CanExecute xác định, cho dù một nút giới hạn bị tắt hay bật. Nếu một lệnh là null, nút sẽ bị ẩn.

(Nếu bạn sử dụng điều khiển bố trí đúng, vị trí của các nút được điều chỉnh đúng cách, nếu một nút không được hiển thị.)

Để cung cấp hỗ trợ cho hơn bốn kịch bản trên, tôi đã thêm một tài sản CommandTitle vào DelegateCommand, để nội dung của nút đến từ đó.

Điều tiếp theo bạn sẽ cần thuộc tính Title cho tiêu đề của hộp thoại. Vì vậy, hãy thêm số này vào số DialogVm.

Nếu bạn muốn có thể đóng hộp thoại (chỉ cần thiết, nếu đó là con của Window) bằng cách thực hiện lệnh, bạn có thể theo dõi this approach. Tất nhiên tôi đã sử dụng phiên bản mà tôi đã mô tả ở đó. Nhưng những người khác cũng đang tìm kiếm đầy hứa hẹn.

Điểm mở cuối cùng là thuộc tính đại diện cho các nội dung hộp thoại khác nhau. Nếu tôi nhớ lại chính xác, tôi đã sử dụng một nhóm nhỏ các kiểu xem và tương ứng DataTemplates (và dĩ nhiên là TemplateSelector, cung cấp mẫu phù hợp dựa trên loại máy ảo). Tất nhiên, bạn cũng sẽ cần một điều khiển ContentPresenter trong hộp thoại của mình, hiển thị số DataTemplate do TemplateSelector cung cấp.

Đây là downsite chỉ, nó chỉ là một cách tiếp cận tốt, nếu bạn chỉ có một vài loại hộp thoại khác nhau (ví dụ hộp Câu hỏi, hộp tin nhắn ...)

Việc sử dụng là khá dễ dàng. Đơn giản chỉ cần, khởi tạo một trường hợp DialogVm với mong muốn ICommand logic, các DialogContentVm (tuy nhiên bạn muốn gọi nó), vượt qua nó để DialogWindow (có lẽ, bạn muốn sử dụng sth. Khác nhau ví dụ như một flyout) và trình bày cho người dùng.

Tôi hy vọng điều đó sẽ hữu ích. Nếu bạn cần thêm thông tin hoặc bất kỳ trợ giúp nào, hãy cho tôi biết.

+0

Cảm ơn. Những gì bạn đề nghị là khá gần với những gì tôi đã có trong tâm trí, ngoại trừ việc sử dụng 'DataTemplate'. Web dev là dòng chính của tôi nhiều năm trước 2 đến 3 năm gần đây trên WPF, vì vậy tôi chỉ sử dụng một 'UserControl' đơn giản như khung nhìn, được gắn với một' ContentControl' trong cửa sổ. Sau đó thay vì chọn mẫu, tôi muốn sử dụng dây tự động vm của Prism, vì vậy lệnh 'ShowView' của tôi chỉ sử dụng Untiy để giải quyết một thể hiện khung nhìn, và vm đã bị ràng buộc. – ProfK

+0

@ProfK: Ah, đó dường như là lựa chọn tốt hơn so với phương pháp 'DataTemplate'. Cảm ơn gợi ý. :) – DHN

+0

Xin đừng bị xúc phạm bởi tiền thưởng. Tôi không có nghi ngờ lời khuyên của bạn là đáng tin cậy, nhưng nó là tinh khiết WPF và không Prism dựa, và tôi đã muốn một vài câu trả lời nhiều hơn từ "chính quyền" trên khuôn khổ đó. Không may cho SO từ ngữ của nút tùy chọn đó. – ProfK

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