La ChildWindow è una finestra modale, ma non blocca. C'è un modo per bloccarlo? Fondamentalmente voglio un metodo ShowDialog() che chiamerà ChildWindow.Show() ma non restituirà fino a quando l'utente non avrà chiuso ChildWindow. Ho provato a utilizzare Monitor.Enter() per bloccare dopo ChildWindow.Show(), ma ChildWindow non ha mai eseguito il rendering e il browser è stato appena bloccato. Qualcuno ha qualche idea?Come rendere il blocco ChildWindow
risposta
Non credo che supporti questo comportamento. È possibile vote for it su CodePlex. A seconda di ciò che desideri, potresti utilizzare lo look at some of Tim Heuer's workarounds here o un altro controllo personalizzato, ad esempio Silverlight Modal Control (on CodePlex).
Non è possibile eseguire ciò che si sta tentando di fare in Silverlight. Qualsiasi modifica apportata all'interfaccia utente verrà eseguita sul thread dell'interfaccia utente. Se blocchi il thread dell'interfaccia utente, l'utente non può interagire con il browser, quindi non c'è alcuna azione da intraprendere per sbloccare il thread.
Se si desidera veramente creare una finestra di dialogo di blocco, l'unico modo per farlo è da un thread non dell'interfaccia utente. Per esempio. si potrebbe creare un metodo che sembra qualcosa di simile:
private void ShowModalDialog()
{
AutoResetEvent waitHandle = new AutoResetEvent(false);
Dispatcher.BeginInvoke(() =>
{
ChildWindow cw = new ChildWindow();
cw.Content = "Modal Dialog";
cw.Closed += (s, e) => waitHandle.Set();
cw.Show();
});
waitHandle.WaitOne();
}
Questo metodo mostrerà una finestra di dialogo e non tornerà fino a quando la finestra viene chiusa. Ma questo metodo può essere chiamato solo da una non-UI-thread. Chiamarlo dal thread dell'interfaccia utente causerà un deadlock (poiché il thread dell'interfaccia utente è in attesa di un evento che può essere attivato solo sul thread dell'interfaccia utente).
In alternativa, è consigliabile prendere in considerazione la logica asincrona piuttosto che forzarla in sincronia.
Mi piace questa soluzione e sembra che dovrebbe funzionare, ma dal momento che non può essere chiamata sul thread dell'interfaccia utente, non sono sicuro di poterlo usare (anche se in realtà non l'ho specificato nella mia domanda (dal Non ci ho nemmeno pensato allora)). Ad ogni modo, ottima soluzione. –
Ho eliminato la creazione di una finestra di dialogo modale "bloccante", avendo un controllo personalizzato che ha un allineamento verticale e orizzontale come tratto, e quindi lo aggiungo come figlio del layout del controllo corrente.
ad es.
<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle Fill="LightBlue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="0.3" />
</Grid>
e poi nel controllo personalizzato
Utilities.UITools.MessageBox x = new Utilities.UITools.MessageBox();
x.SetError(e.Result);
this.LayoutRoot.Children.Add(x);
A seconda di ciò che deve essere visualizzato nella modale, ho aggiungere dinamicamente controlli per il layout modale. Chiaramente, non è una soluzione elegante, ma almeno funziona.
Ciò lo renderebbe modale in un modo, ma non sembra che si bloccherebbe in quanto non vi è alcuna chiamata di funzione che bloccherebbe fino a quando l'utente non chiuderà la finestra del messaggio. –
L'ho bloccato bloccando un evento nella casella del messaggio. Quindi, blocca il resto del programma fino a quando l'evento si attiva – Johannes
Se si desidera eseguire un'azione sulla finestra secondaria, utilizzare il seguente codice. Nascondere i controlli indesiderati prima invocano e mostrano sulla chiusura della finestra secondaria, semplice :)
ChildWindow cw = new ChildWindow();
cw.Closed += new EventHandler(cw_Closed);
cw.Show();
Si potrebbe provare ad annullare sempre la chiusura dell'evento e impostare il DialogResult tardi.
void ConfigTemplatePopup_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (tmpDialogResult != null || DialogResult == true) return;
tmpDialogResult = DialogResult; //this is a field
e.Cancel = true;
var myMessageBox = new WspMessageBox("Are you sure you want to close?", true);
myMessageBox.Closed += (s, e2) =>
{
if (wspMessageBox.DialogResult == true)
{
DialogResult = tmpDialogResult;
}else
{
tmpDialogResult = null;
}
};
myMessageBox.Show();
}
Usando async and await in Silverlight 5 si può facilmente creare un metodo Show statica che può essere bloccando, come
public partial class MyDialog {
MyResultType result;
readonly AutoResetEvent waitHandle;
MyDialog() {
InitializeComponent();
waitHandle = new AutoResetEvent(false);
}
public static Task<MyResultType> Show() {
var dialog = new MyDialog();
dialog.Show();
dialog.Closed += (s, e) => dialog.waitHandle.Set();
return Task<MyResultType>.Factory.StartNew(() => {
dialog.waitHandle.WaitOne(); return dialog.result; });
}
void OkButton_Click(object sender, RoutedEventArgs e) {
result = new MyResultType();
// Initialize result...
Close();
}
}
e chiamare la finestra di dialogo come
public async void TestDialog() {
var result = await ConfirmBox.Show();
// This code will be performed after the Dialog is closed.
// use result...
}
-1 Ho paura, perché questo frammento non viene compilato. L'output di 'Task
Questo snippet proviene dal mio progetto di lavoro. Lo uso come soluzione comune per i dialoghi. Per compilarlo è necessario il "pacchetto di targeting asincrono", che puoi aggiungere al tuo progetto usando il nuget. Si prega di leggere l'articolo utilizzando il link nella mia risposta. –
- 1. Posso rendere libero il blocco di codice seguente/atomico?
- 2. Posso rendere un blocco visivo il termine di ricerca corrente?
- 3. Come rendere strictfp un blocco di inizializzazione (statico)?
- 4. Come rendere la nostra schermata di blocco in Android invece della schermata di blocco predefinita
- 5. Come rendere il numero non raggiungibile (simile al blocco delle chiamate)?
- 6. Come funziona il blocco dell'ambito?
- 7. Come rendere il gradiente trasparente?
- 8. Come rendere il wordwrap UILabel
- 9. Come rendere il testo "trasparente"?
- 10. Come rendere visibile il pulsante?
- 11. Come rendere il pulsante immagine
- 12. WPF: rendere l'intero "blocco" di un percorso selezionabile
- 13. Come creare un'area di testo per riempire il blocco div?
- 14. Come rendere Eclipse Formatter per non distruggere il codice commentato?
- 15. Come funziona Enumerator.new con il blocco passato?
- 16. vim: come selezionare il blocco incollato
- 17. Rails: come funziona il blocco respond_to?
- 18. Come funziona il blocco di RescueTimes?
- 19. Il blocco Console.WriteLine?
- 20. Il blocco sed è?
- 21. Come rendere invisibile il sottostante div?
- 22. Come rendere PrintWriter sovrascrivere il vecchio file
- 23. Come rendere meno dettagliato il webpack?
- 24. Come rendere Head il master in git?
- 25. Come rendere il menu di rotazione
- 26. Come rendere installabile il programma Java?
- 27. Come rendere il codice di eccezione DRY?
- 28. Materiale angolare: come rendere scorrevole il contenuto
- 29. Come rendere il sito Web disponibile offline
- 30. Come rendere rosso il testo in mediawiki?
Ci può spiegare che cosa stai cercando di raggiungere ? – Ray
Solo una semplice finestra di blocco modale simile a MessageBox.Show() o Form.ShowDialog() –
Ho provato tutto e non ho mai trovato una soluzione. Stavo cercando di creare il mio MessageBox.Ho anche provato asincrono ma è sempre stato bloccato. Ho rinunciato dopo aver letto che Tim Heuer diceva che non era possibile avere il vero Modal. – Paully