funcionalidade emulating ShowDialog
-
11-09-2019 - |
Pergunta
Eu estou escrevendo um aplicativo (c # + WPF), onde todos os diálogos estilo modais são implementados como um UserControl
em cima de uma grade translúcido que cobre o Window
principal. Isto significa que há apenas um Window
e mantém a aparência de todas as aplicações empresas.
Para mostrar uma MessageBox
, a sintaxe é a seguinte:
CustomMessageBox b = new CustomMessageBox("hello world");
c.DialogClosed += ()=>
{
// the rest of the function
}
// this raises an event listened for by the main window view model,
// displaying the message box and greying out the rest of the program.
base.ShowMessageBox(b);
Como você pode ver, não é apenas o fluxo de execução realmente invertido, mas a sua terrivelmente detalhado em comparação com a versão clássica NET:
MessageBox.Show("hello world");
// the rest of the function
O que eu realmente estou procurando é uma maneira de não retornar de base.ShowMessageBox
até o evento fechado de diálogo tem sido levantada por ele, mas eu não posso ver como é possível esperar por este sem desligar o fio GUI e, assim, impedindo que o usuário nunca clicar em OK. Estou ciente de que posso fazer uma função de delegado como um parâmetro para a função ShowMessageBox
que tipo de impede a inversão de execução, mas ainda causa alguma sintaxe louco / recuar.
Am I faltando alguma coisa óbvia ou se existe uma maneira padrão de fazer isso?
Solução
Você pode querer dar uma olhada este artigo em CodeProject e < a href = "http://msdn.microsoft.com/en-us/library/aa969773.aspx#Creating_a_Modal_Custom_Dialog_Box" rel = "noreferrer"> este artigo no MSDN. O primeiro artigo percorre manualmente criar um diálogo modal de bloqueio, eo segundo artigo ilustra como criar diálogos personalizados.
Outras dicas
A maneira de fazer isso é usando um DispatcherFrame objeto .
var frame = new DispatcherFrame();
CustomMessageBox b = new CustomMessageBox("hello world");
c.DialogClosed += ()=>
{
frame.Continue = false; // stops the frame
}
// this raises an event listened for by the main window view model,
// displaying the message box and greying out the rest of the program.
base.ShowMessageBox(b);
// This will "block" execution of the current dispatcher frame
// and run our frame until the dialog is closed.
Dispatcher.PushFrame(frame);
Você pode fazer a sua função em um iterador que retorna um IEnumerator<CustomMessageBox>
, em seguida, escrevê-lo como este:
//some code
yield return new CustomMessageBox("hello world");
//some more code
Você, então, escrever uma função wrapper que leva o enumerador e chamadas MoveNext
(que irá executar todas as funções até a próxima yield return
) nos manipuladores DialogClosed
.
Note que a função de invólucro não seria um bloqueio de chamadas.
Configurar outro loop de mensagem na classe caixa de mensagem. Algo como:
public DialogResult ShowModal()
{
this.Show();
while (!this.isDisposed)
{
Application.DoEvents();
}
return dialogResult;
}
Se você olhar para Windows.Form no refletor você vai ver que ele faz algo como isso ..