2010-01-21 39 views
6

Tôi đang cố gắng thực hiện hộp thoại xác nhận bằng cách sử dụng đối tượng ChildWindow của Silverlight.Hộp thoại xác nhận Silverlight để tạm dừng chủ đề

Lý tưởng nhất, tôi muốn nó hoạt động như MessageBox.Show(), trong đó toàn bộ ứng dụng tạm dừng cho đến khi nhận được dữ liệu nhập từ người dùng.

Ví dụ:

for (int i = 0; i < 5; i++) 
{ 
    if (i==3 && MessageBox.Show("Exit early?", 
     "Iterator", MessageBoxButton.OKCancel) == MessageBoxResult.OK) 
    { 
     break; 
    } 
} 

sẽ ngăn chặn sự lặp đi lặp lại ở 3 nếu người dùng chạm OK ...

Tuy nhiên, nếu tôi được làm một cái gì đó dọc theo dòng:

ChildWindow confirm = new ChildWindow(); 
confirm.Title = "Iterator"; 
confirm.HasCloseButton = false; 
Grid container = new Grid(); 

Button closeBtn = new Button(); 
closeBtn.Content = "Exit early"; 
closeBtn.Click += delegate { confirm.DialogResult = true; confirm.Close(); }; 
container.Children.Add(closeBtn); 

Button continueBtn = new Button(); 
continueBtn.Content = "Continue!"; 
continueBtn.Click += delegate { confirm.DialogResult = false; confirm.Close(); }; 
container.Children.Add(continueBtn); 

confirm.Content = container; 

for(int i=0;i<5;i++) { 
    if (i==3) { 
    confirm.Show(); 
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) { 
     break; 
    } 
    } 
} 

Điều này rõ ràng sẽ không hoạt động vì luồng không bị dừng lại ... confirm.DialogResult.HasResult sẽ là sai và vòng lặp sẽ tiếp tục qua 3.

Tôi chỉ tự hỏi, làm thế nào tôi có thể đi về việc này đúng cách. Silverlight là đơn luồng, vì vậy tôi không thể chỉ đưa thread vào giấc ngủ và sau đó đánh thức nó khi tôi đã sẵn sàng, vì vậy tôi chỉ tự hỏi nếu có bất cứ điều gì khác mà mọi người có thể giới thiệu?

Tôi đã xem xét đảo ngược logic - tức là, chuyển các hành động tôi muốn xảy ra cho các sự kiện Có/Không, nhưng trong trường hợp cụ thể của tôi, điều này sẽ không hoạt động.

Cảm ơn trước!

Trả lời

11

Tôi không nghĩ rằng bạn sẽ có thể chặn mã của mình trong vòng lặp thư theo cách bạn có thể với WinForms 'ShowDialog.

Tuy nhiên, bạn có thể lạm dụng vòng lặp để đạt được hiệu quả tương tự:

interface IAction { void Execute(Action callback); } 

public static void ExecAction(IEnumerator<IAction> enumerator) { 
    if (enumerator.MoveNext()) 
     enumerator.Current.Execute(() => ExecAction(enumerator)); 
} 

class DialogAction : ChildWindow, IAction { 
    void IAction.Execute(Action callback) { 
     //Show the window, then call callback when it's closed 
    } 
} 

IEnumerator<IAction> YourMethod() { 
    ... 
    var confirm = new DialogAction(); 
    yield return confirm; 
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) 
     yield break; 
    ... 
} 

Để sử dụng hệ thống này, bạn sẽ viết ExecAction(YourMethod());. Lưu ý rằng đây sẽ là cuộc gọi bán chặn và tôi chưa thử nghiệm điều này.

Tính năng mới async của C# 5 hoạt động giống hệt nhau (trên thực tế, các phiên bản đầu tiên của mã biên dịch async được dựa trên việc thực hiện trình lặp hiện tại), nhưng với sự hỗ trợ cú pháp đẹp hơn.

+1

Đó là một thiên tài tuyệt vời! Tôi sẽ cung cấp cho một shot và xem nó hoạt động tốt như thế nào ... – AlishahNovin

+0

Nó có thể dễ dàng được áp dụng để thực thi điều tra trong một chủ đề nền, làm cho một luồng công việc UI đa luồng rất đơn giản. – SLaks

+0

+1. Điểm nhỏ: bạn không có nghĩa là 'trả về lợi nhuận' trong' YourMethod'? –

1

Bạn có thể đạt được yên tĩnh này một cách dễ dàng với RX Framework:

var continued = Observable.FromEvent<RoutedEventArgs>(continueBtn, "Click"); 

var iter = new Subject<int>(); 

var ask = iter.Where(i => i == 3).Do(_ => confirm.Show()); 

iter.Where(i => i != 3 && i < 10) 
    .Merge(ask.Zip(continued, (i, _) => i)) 
    .Do(i => Debug.WriteLine("Do something for iteration {0}", i)) 
    .Select(i => i + 1) 
    .Subscribe(iter); 

iter.OnNext(0); 

Giải pháp dễ dàng quy mô đối với bất kỳ quy tắc xác định thời gian hiển thị một hộp thoại. Ví dụ. giả sử chúng tôi muốn chặn lặp lại và yêu cầu xác nhận người dùng cứ 3 lần lặp lại. Tất cả những gì bạn phải làm là thay thế điều kiện i == 3 bằng i % 3 == 0 (và i != 3 với i % 3 != 0).

0

Kiểm tra dự án này http://silverlightmsgbox.codeplex.com/. Nó trình bày cách triển khai đơn giản nhưng có thể trình bày của một số hộp thư hữu ích, tức là xác nhận, lỗi, thông tin, đầu vào của người dùng, v.v. và có thể hữu ích cho bạn. Chúc may mắn.

+0

Điều đó không liên quan gì đến câu hỏi - anh ấy yêu cầu một cuộc gọi chặn. – SLaks

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