Silverlight подтверждает диалоговое окно для приостановки потока

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

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

Например:

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

Остановил бы повторение в 3, если пользователь совершает нападки хорошо...

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

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 является однопоточной, таким образом, я не могу только поместить поток, чтобы спать и затем разбудить ее, когда я готов, таким образом, я просто задаюсь вопросом, существует ли что-либо еще, что могли рекомендовать люди?

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

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

6
задан Groo 6 May 2011 в 16:31
поделиться

2 ответа

Я не думаю, что вы сможете заблокировать свой код в цикле сообщений, как вы можете с 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;
    ...
}

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

C # 5 New Async Особенности Async работают точно так же (на самом деле, начальные версии Commiler Compiler ASYNC были в значительной степени основаны на существующей реализации итерации), но с Приятная синтаксическая поддержка.

12
ответ дан 8 December 2019 в 18:36
поделиться

Вы можете легко достичь этой тишины с помощью 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 == 0 I! = 3 с I% 3! = 0 ).

1
ответ дан 8 December 2019 в 18:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: