Можно сделать это через через ShowDialog, но мне кажется более чистым метод с async/await.
Вот простой вариант:
public Task<int> ShowMessage()
{
var tcs = new TaskCompletionSource<int>();
var w = new YourWindow();
w.Closed += (o, args) => tcs.TrySetResult(w.ClickedButtonIndex)
w.Show();
return tcs.Task;
}
Для этого, понятно, YourWindow должно в публичном свойстве PressedButtonIndex запоминать, какая кнопка была нажата. И закрываться по нажатию любой из кнопок. Это делается так:
<Button Click="OnButtonClicked" Name="Button1">1</Button>
<Button Click="OnButtonClicked" Name="Button2">2</Button>
и в code-behind окна YourWindow
void OnButtonClicked(object sender, RoutedEventArgs e)
{
if (sender == Button1)
ClickedButtonIndex = 1;
else
ClickedButtonIndex = 2;
Close();
}
public int ClickedButtonIndex { get; private set; }
Давайте попробуем более изощрённый вариант Для начала, научимся дожидаться нажатия на кнопку:
async Task<Button> ClickOnButton(Button b, CancellationToken ct)
{
var tcs = new TaskCompletionSource<Button>();
RoutedEventHandler handler = (sender, args) => tcs.TrySetResult(b);
b.Click += handler;
try
{
using (ct.Register(() => tcs.TrySetCanceled()))
return await tcs.Task;
}
finally
{
b.Click -= handler;
}
}
async Task<Button> ClickOnAny(IEnumerable<Button> buttons, CancellationToken ct)
{
using (var innerCts = CancellationTokenSource.CreateLinkedTokenSource(ct))
{
var tasks = buttons.Select(el => ClickOnButton(el, innerCts.Token)).ToList();
var winningTask = await Task.WhenAny(tasks);
var clickedControl = await winningTask;
innerCts.Cancel();
return clickedControl;
}
}
Теперь можно навешивать ожидание на любое окно:
public async Task<int> ShowMessage()
{
var w = new YourWindow();
w.Show();
var clickedButton = await ClickOnAny(
new[] { w.Button1, w.Button2 }, CancellationToken.None);
w.Close();
return clickedButton == w.Button1 ? 1 : 2;
}
При таком подходе окно не обязано «сотрудничать».
И в заключение стандартный (на мой вкус, устаревший) вариант с ShowDialog:
int ShowMessage()
{
var dw = new YourWindow();
var result = dw.ShowDialog();
if (result == true)
return dw.ClickedButtonIndex;
else
return -1;
}
Для этого в YourWindow должен быть такой code-behind:
void OnButtonClicked(object sender, RoutedEventArgs e)
{
if (sender == Button1)
ClickedButtonIndex = 1;
else
ClickedButtonIndex = 2;
DialogResult = true;
}
public int ClickedButtonIndex { get; private set; }
static WpfDialogSample.Result? – Alex D. Sep 12 '15 at 12:37enum Resultиз блока кода выше, что позволяет писатьCancelвместоResult.Cancel. – Kyubey Sep 12 '15 at 18:38WpfDialogSample- это, как я понимаю, пространство имен? – Alex D. Sep 12 '15 at 19:00using staticи замените\b(?<!")(Yes|No|Cancel)(?!,)\b=>Result.$1. – Kyubey Sep 12 '15 at 19:42