Silverlight Подтвердите диалог, чтобы приостановить поток - PullRequest
6 голосов
/ 22 января 2010

Я пытаюсь сделать диалог подтверждения, используя объект ChildWindow Silverlight.

В идеале, я бы хотел, чтобы он работал как MessageBox.Show(), когда все приложение останавливается до тех пор, пока не будет получен ввод от пользователя.

Например:

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

Остановит итерацию на 3, если пользователь нажмет OK ...

Однако, если бы я сделал что-то вроде:

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;
    }
  }
}

Это явно не будет работать, так как поток не останавливается ... confirm.DialogResult.HasResult будет ложным, и цикл будет продолжаться после 3.

Мне просто интересно, как я мог бы сделать это правильно. Silverlight является однопоточным, поэтому я не могу просто уложить нить в спящий режим, а затем разбудить его, когда я буду готов, поэтому мне просто интересно, есть ли что-нибудь, что люди могли бы порекомендовать?

Я подумал о том, чтобы поменять логику - то есть передать действия, которые я хочу совершить, событиям Да / Нет, но в моем конкретном случае это не совсем сработало бы.

Заранее спасибо!

Ответы [ 3 ]

11 голосов
/ 22 января 2010

Я не думаю, что вы сможете блокировать свой код в цикле сообщений так, как вы можете с помощью WinForms 'ShowDialog.

Однако вы можете неправильно использовать итераторы для достижения того же эффекта:

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;
    ...
}

Чтобы использовать эту систему, вы должны написать ExecAction(YourMethod());.Обратите внимание, что это будет полублокирующий вызов, и я его вообще не тестировал.

Новые функции async в C # 5 работают точно так же (фактически, начальные версииasync код компилятора в значительной степени основывался на существующей реализации итератора), но с более приятной синтаксической поддержкой.

1 голос
/ 23 января 2010

Вы можете легко достичь этого спокойствия с 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);

Решение легко масштабируется для любого правила, определяющего, когда показывать диалог. Например. Предположим, мы хотим заблокировать итерацию и запрашивать подтверждение пользователя каждые 3 итерации. Все, что вам нужно сделать, это заменить условие i == 3 на i % 3 == 0i != 3 на i % 3 != 0).

0 голосов
/ 18 января 2011

Проверьте этот проект http://silverlightmsgbox.codeplex.com/. Он представляет собой простую, но презентабельную реализацию нескольких полезных окон сообщений, таких как подтверждение, ошибка, информация, ввод пользователя и т. Д., И может быть полезен для вас.Удачи.

...