WPF s'il vous Plaît Attendre boîte de Dialogue
Je suis le développement d'une application de bureau WPF en c# 4.0, qui a à gérer une grande quantité d'opérations de longue durée (le chargement de données à partir de la DB, le calcul de simulations, l'optimisation des itinéraires, etc.).
Lors de ces opérations de longue durée exécuter en arrière-plan, je veux montrer un Veuillez-Attendre boîte de dialogue. Lorsque l'Veuillez-Attendre boîte de dialogue apparaît à l'application doit être verrouillé, mais simplement désactiver la fenêtre de l'application n'est pas une bonne idée parce que tous les DataGrids perdraient leur statut (SelectedItem
).
Ce que j'ai pour l'instant fonctionne mais il y a quelques problèmes:
Une nouvelle WaitXUI est créé à l'aide de l'option de création de l'usine de méthode. La méthode de création s'attend à ce texte de la légende et une refernce à l'hôte de contrôle qui doit être verrouillé. La méthode de création de jeux de la StartupLocation de la fenêtre, le texte de la légende et de l'armée de verrouillage:
WaitXUI wait = WaitXUI.Create("Simulation running...", this);
wait.ShowDialog(new Action(() =>
{
//long running operation
}));
Avec la surcharge méthode ShowDialog la WaitXUI peuvent ensuite être affichées. ShowDialog surcharge de ne s'attendre à une Action qui s'enroule le long de l'exécution de l'opération.
Dans le ShowDialog surcharge je viens de commencer l'Action dans son propre thread et de désactiver le contrôle d'hôte (réglez l'Opacité à 0,5 et de définir IsEnabled false) et que l'appel ShowDialog de la classe de base.
public bool? ShowDialog(Action action)
{
bool? result = true;
//start a new thread to start the submitted action
Thread t = new Thread(new ThreadStart(delegate()
{
//start the submitted action
try
{
Dispatcher.UnhandledException += Dispatcher_UnhandledException;
Dispatcher.Invoke(DispatcherPriority.Normal, action);
}
catch (Exception ex)
{
throw ex;
}
finally
{
//close the window
Dispatcher.UnhandledException -= Dispatcher_UnhandledException;
this.DoClose();
}
}));
t.Start();
if (t.ThreadState != ThreadState.Stopped)
{
result = this.ShowDialog();
}
return result;
}
private new bool? ShowDialog()
{
DisableHost();
this.Topmost = true;
return base.ShowDialog();
}
private void DisableHost()
{
if (host != null)
{
host.Dispatcher.Invoke(new Action(delegate()
{
this.Width = host.Width - 20;
host.Cursor = Cursors.Wait;
host.IsEnabled = false;
host.Opacity = 0.5;
}));
}
}
Voici les problèmes:
- La désactivation de l'hôte résultats de contrôle dans la perte de statut de l'information (SelectedItems...)
- La WaitXUI est parfois montré pour seulement quelques millisecondes lorsque le thread se termine un peu ms après la WaitXUI est montré
- Parfois, la boîte de dialogue n'apparaît pas à tous, bien que le fil est toujours en cours d'exécution
Ces sont les principaux problèmes qui viennent à mon esprit pour le moment. Comment ce principe peut-il être amélioré, ou ce que d'autres méthodes peuvent être employées pour résoudre ce problème?
Merci d'avance!
- Pas même aller à la poste comme une question, comme il est laid. Jeu de chaque contrôle à IsEnabled = false. Ou de capturer n'importe quelle entrée à la Fenêtre et de l'ensemble e.manipulés = true.
- C'est certainement un duplicata.
- stackoverflow.com/questions/3480966/...
- Mais cela ne résout pas mes problèmes.
- Il y a des questions similaires, mais avec tous les autres (en bas) les exigences! En indiquant ma question comme un doublon et ne pas poster une solution n'est pas utile 😉
Vous devez vous connecter pour publier un commentaire.
Un peu de la pensée latérale est toujours utile lors du développement d'applications WPF. Vous pouvez répondre à vos exigences facilement avec juste un
Grid
, unRectangle
, unbool
propriété (que vous pouvez déjà avoir) et unBooleanToVisibilityConverter
et vous n'aurez pas à désactiver tous les contrôles.L'idée est simple. Ajouter un blanc
Rectangle
en avant du contenu de votre vue avec sesOpacity
ensemble de propriétés entre0.5
et autour de0.75
. Les données de lier sonVisibility
propriété de labool
bien à votre modèle d'affichage ou de code derrière et plug dans leBooleanToVisibilityConverter
:Maintenant, lorsque vous souhaitez désactiver les commandes, il suffit de régler le
bool
propriététrue
et laRectangle
fera l'INTERFACE utilisateur evanoui:MainWindow.xaml
et votrebool
propriété dans la vue principale de modèle, alors vous besoin d'un seul. Mettre tous normal de votre contenu de l'application où il est ditPut your main content here
.BooleanToVisibilityConverter
, qui est inclus avec le .NET Framework. Par conséquent, il serait clair pour vous que la référence à la mystérieuseBoolToVisibilityConverter
était rien de plus qu'une erreur de frappe et que vous devez utiliser celui-ciBooleanToVisibilityConverter
à la place. Mais merci pour votre commentaire.N'avez pas vraiment besoin de créer propre mise en œuvre, je pense que c'est redondant.
prendre un coup d'oeil dans déjà créé composant, comme BusyIndicator, pour des besoins similaires. ce qui est essentiel et efficace. .
plus d'info de codeplex