Changement WPF mainwindow étiquette à partir d'une autre classe et thread séparé
Je travaille sur une application WPF. J'ai un label nommé "Status_label" dans MainWindow.xaml
. et je veux en changer le contenu d'une classe différente (signIn.cs).
Normalement, je suis capable de faire ce
var mainWin = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is MainWindow) as MainWindow;
mainWin.status_lable.Content = "Irantha signed in";
Mais mon problème est que quand j'essaye d'accéder via un thread différent dans signIn.cs de la classe, il donne une erreur:
The calling thread cannot access this object because a different thread owns it.
Puis-je résoudre ce problème en utilisant Dispatcher.Invoke(new Action(() =>{..........
ou autre chose?
EDIT:
Je vais appeler ce changement sur l'étiquette de l'action à partir d'une autre classe que-bien-comme thread séparé
MainWindow.xaml
<Label HorizontalAlignment="Left" Margin="14,312,0,0" Name="status_lable" Width="361"/>
SignIn.cs
internal void getStudentAttendence()
{
Thread captureFingerPrints = new Thread(startCapturing);
captureFingerPrints.Start();
}
void mySeparateThreadMethod()
{
var mainWin = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is MainWindow) as MainWindow;
mainWin.status_lable.Dispatcher.Invoke(new Action(()=> mainWin.status_lable.Content ="Irantha signed in"));
}
ligne var mainWin retour d'erreurThe calling thread cannot access this object because a different thread owns it.
Merci de me guider,
Merci
Peut-être, parce que cette question a été répondu à une hundered fois. Certains "googler" serait de vous fournir une solution adéquate.
OriginalL'auteur iJay | 2013-03-15
Vous devez vous connecter pour publier un commentaire.
J'ai résolu ma question, espère que quelqu'un aura besoin de cela. Mais ne sais pas si c'est le optimisé façon.
Dans mon mainWindow.xaml.cs :
de mon SignIn.cs classe
Cela fonctionne très bien pour moi.
Vous pouvez trouver plus de détails à partir d'ici, Changement de fenêtre WPF étiquette de contenu à partir d'une autre classe et d'thread séparé
cheers!!
OriginalL'auteur iJay
essayer ci-dessous extrait de:
Ne comprends pas ce que tu veux dire.Voulez-vous le faire dans le thread séparé? Vous pouvez utiliser status_lable.Répartiteur.BeginInvoke(...) ou d'une Tâche.Usine.StartNew(()=> {status_lable.Répartiteur.BeginInvoke(...);}); si vous voulez être plus reponsive
Mais mon retour en cas d'erreur de var mainWin ligne, puis-je accéder à mainWindow de status_label par un autre chemin? J'ai édité la question peut u pls vérifier ça?
Ce sont deux questions en fait. Vous mélangées mais votre titre est sur filetée d'accès. Je pense que j'ai répondu à votre question sur l'accès multithread. Comme pour l'accès à la status_label, vous devez fournir une fonction ou une propriété de sorte que vous pouvez accéder à votre mainwin classe. Par exemple, dans votre classe de contrôle utilisateur (où le status_label est situé), vous pouvez fournir une propriété appelée StatusCtrl d'offre public/accès interne.
OriginalL'auteur David
Merci pour les réponses, elles m'ont conduit dans la bonne direction. J'ai fini avec cette solution simple:
Ensuite dans mon gestionnaire d'événements dans une autre classe qui s'exécute dans un autre thred:
Cette option pour afficher la fenêtre réduite lorsque j'message est reçu par l'intermédiaire d'un namedPipeline.
OriginalL'auteur Kasper Halvas Jensen
Merci! Je me suis retrouvé avec un peu différente de la solution, mais on m'a orienté dans la bonne direction avec votre réponse.
Pour mon application, j'ai beaucoup de commandes en main, et la plupart des appels de méthode sur les principales ont été effectués à partir de la portée de la main, de sorte qu'il était plus simple d'utiliser la valeur par défaut { get; set } dans MainWindow.xaml.cs (ou simplement de définir les contrôles en XAML).
Dans mes parent de la fenêtre de code-behind, je lance le MainWindow dans un thread séparé comme ceci (exemple simplifié). L'essentiel est de définir principale à l'échelle mondiale, même si elle est instancié à l'intérieur de Window_Loaded():
Puis, dans ma MainWindow code-behind, je viens d'interagir avec les commandes comme si c'était un simple single-threaded application (il n'y a pas de contrôle de la société mère filetage de l'enfant thread dans mon cas). Je peux, cependant, le contrôle principal de la société mère thread comme celui-ci:
En le faisant de cette manière, j'évite la complexité de tout définir dans le code-behind et à l'aide du répartiteur de l'intérieur le code-behind de MainWindow.xaml.cs. Il ya seulement quelques endroits dans ma demande d'où je modifier principale de la fenêtre parent, donc c'était plus simple pour moi, mais votre approche me semble tout aussi valable. Merci encore!
OriginalL'auteur Elemental Pete