2012-04-10 30 views
19

Tôi có ViewModel1 và View1 được liên kết với nó. Tôi bắt đầu cửa sổ hộp thoại từ ViewModel2 (một số chế độ xem khác) bằng cách sử dụng đối tượng IWindowManager. Mã từ ViewModel2 lớp học:Cách đóng cửa sổ hộp thoại từ chế độ xem mô-đun (Caliburn + WPF)?

windowManager.ShowDialog(new ViewModel()); 

Vì vậy, tôi có cửa sổ hộp thoại có quyền kiểm soát người dùng View1. Câu trả lời của tôi là tiếp theo - Tôi có thể đóng cửa sổ hộp thoại bằng nút đóng màu đỏ, nhưng cách đóng bằng nút cụ thể của tôi (chứa trong điều khiển người dùng View1), như nút "Hủy" với lệnh đóng (Command={Binding CancelCommand}), CancelCommand tất nhiên được chứa trong lớp ViewModel1.

Trả lời

36

Nó thậm chí còn dễ dàng hơn nếu mô hình điểm của bạn kéo dài Caliburn.Micro.Screen:

TryClose(); 
+0

TryClose cố gắng để đóng toàn bộ ứng dụng ... – Tim

+16

Vâng, nó đóng toàn bộ ứng dụng chỉ khi bạn đang cố gắng đóng cửa sổ ứng dụng chính. –

+0

bạn vừa lưu ngày của tôi :-) – juFo

10

Bạn có thể xem chế độ xem hiện tại (trong trường hợp của bạn là cửa sổ hộp thoại) bằng cách triển khai giao diện IViewAware trên ViewModel của bạn. Sau đó, bạn có thể gọi Close trên chế độ xem (số Window được tạo làm hộp thoại) khi lệnh của bạn được thực thi.

Các đơn giản nhất tại sao để lấy được từ ViewAware:

public class DialogViewModel : ViewAware 
{ 
    public void ExecuteCancelCommand() 
    { 
     (GetView() as Window).Close(); 
    } 
} 

Nếu bạn không được phép để lấy được bạn có thể thực hiện nó cho mình:

public class DialogViewModel : IViewAware 
{ 
    public void ExecuteCancelCommand() 
    { 
     dialogWindow.Close(); 
    } 

    private Window dialogWindow; 
    public void AttachView(object view, object context = null) 
    { 
     dialogWindow = view as Window; 
     if (ViewAttached != null) 
      ViewAttached(this, 
       new ViewAttachedEventArgs(){Context = context, View = view}); 
    } 

    public object GetView(object context = null) 
    { 
     return dialogWindow; 
    } 

    public event EventHandler<ViewAttachedEventArgs> ViewAttached; 
} 

Lưu ý: Tôi đã sử dụng 1,3 Caliburn.Micro .1 cho mẫu của tôi.

+0

Đúng vậy! Cảm ơn bạn rất nhiều !!!)))) –

5

Một cách sạch hơn (Chủ đề của sở thích cá nhân) mà tôi sử dụng rất nhiều là sử dụng mô hình IResult, bằng cách này bạn trừu tượng Window implemenation

ViewModel

public IEnumerable<IResult> CloseMe() 
{ 
    yield return new CloseResult(); 
} 

mã kết quả

public class CloseResult : Result 
{ 
    public override void Execute(ActionExecutionContext context) 
    { 
     var window = Window.GetWindow(context.View); 
     window.Close();    

     base.Execute(context); 
    } 
} 

public abstract class Result : IResult 
{ 
    public virtual void Execute(ActionExecutionContext context) 
    { 
     OnCompleted(this, new ResultCompletionEventArgs()); 
    } 

    protected virtual void OnCompleted(object sender, ResultCompletionEventArgs e) 
    { 
     if (Completed != null) 
      Completed(sender, e); 
    } 

    public event EventHandler<ResultCompletionEventArgs> Completed; 
} 

chỉnh sửa (Chỉ cần thiết cho IoC): Nếu bạn muốn tiến thêm một bước nữa, bạn thực hiện một lớp cơ sở cho tất cả các màn hình

public abstract class ShellPresentationModel : Screen 
{ 
    public ShellPresentationModel(IResultFactory resultFactory) 
    { 
     Result = resultFactory; 
    } 

    public IResultFactory Result { get; private set; } 
} 

Bằng cách này bạn có thể tiêm phụ thuộc với một IoC dễ dàng hơn nhiều, sau đó ViewModel của bạn phương pháp chặt chẽ sẽ trông như thế này

public IEnumerable<IResult> CloseMe() 
{ 
    yield return Result.Close(); 
} 

Một ví dụ về một IResult có sử dụng phụ thuộc có thể

public class ShowDialogResult<TModel> : Result 
{ 
    private readonly IWindowManager windowManager; 
    private readonly TModel model; 
    private Action<TModel> configure; 

    public ShowDialogResult(IWindowManager windowManager, TModel model) 
    { 
     this.windowManager = windowManager; 
     this.model = model; 
    } 

    public IResult Configure(Action<TModel> configure) 
    { 
     this.configure = configure; 
     return this; 
    } 

    public override void Execute(ActionExecutionContext context) 
    { 
     if(configure != null) 
      configure(model); 

     windowManager.ShowDialog(model); 

     base.Execute(context); 
    } 
} 

chỉnh sửa Chỉ cần lưu ý rằng tôi quên thêm một ví dụ về sơ đồ IoC ở trên, ở đây đi Với một IoC con chứa er mẫu nó sẽ trông như thế này

public IEnumerable<IResult> ShowDialog() 
{ 
    yield return Result.ShowDialog<MyViewModel>(); 
} 

Nếu không có một mẫu chứa con bạn sẽ cần phải tiêm dependeync mẹ vào đứa trẻ bằng tay

yield return Result.ShowDialog<MyViewModel>().Configure(m => m.SomeData = this.SomeData); 
Các vấn đề liên quan