2013-03-15 7 views
7

私はWPFアプリケーションで作業しています。 MainWindow.xamlに「Status_label」というラベルがあります。そのコンテンツを別のクラス(signIn.cs)から変更したいと考えています。 通常、私はこの別のクラスのWPFメインウィンドウのラベルを変更し、別のスレッド

var mainWin = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is MainWindow) as MainWindow; 
mainWin.status_lable.Content = "Irantha signed in"; 

を行うことができるよしかし、私の問題は、私はsignIn.csクラスで異なるスレッドを経由してそれにアクセスしようとしているとき、ある、それはエラーを与える:

The calling thread cannot access this object because a different thread owns it. 

Dispatcher.Invoke(new Action(() =>{..........などで解決できますか?

EDIT: 私はつもりコール別のクラスからこのラベル変更アクションだとしてウェル-として別のスレッド

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")); 
} 

l INEするvarのMainWinのリターンエラーThe calling thread cannot access this object because a different thread owns it.

+0

なぜこれがダウン投票されたのですか? – iJay

+0

おそらく、この質問は時間が浪費されているので答えました。いくつかの「グーグル」はあなたに適切な解決策を提供します。 – DHN

答えて

22

誰かがこれを必要と願っています。しかし、これが最適化された方法であるかどうかは分かりません。私mainWindow.xaml.cs

:私のSignIn.csから

public MainWindow() 
    { 
     main = this; 
    } 

    internal static MainWindow main; 
    internal string Status 
    { 
     get { return status_lable.Content.ToString(); } 
     set { Dispatcher.Invoke(new Action(() => { status_lable.Content = value; })); } 
    } 

クラス

MainWindow.main.Status = "Irantha has signed in successfully"; 

これは私のために正常に動作します。 詳細はこちらからChange WPF window label content from another class and separate thread

歓声!!

+1

素晴らしい!ありがとうたくさんの! – MDDDC

2

スニペット以下試してくださいありがとう、私を導いてください、私は私の質問を解決

status_lable.Dispatcher.Invoke(...) 
+1

お返事ありがとうございます。私の問題は別のスレッドのためです。 – iJay

+0

あなたは何を意味するのか理解していません。別スレッドでそうしたいですか? status_lable.Dispatcher.BeginInvoke(...)または Task.Factory.StartNew(()=> {status_lable.Dispatcher.BeginInvoke(...);});を使用できます。 – David

+0

しかし、私のエラーはvar mainWin行から戻ってきますが、別の方法でmainWindowのstatus_labelにアクセスできますか?私はあなたがそれをチェックすることができます質問を編集? – iJay

1

ありがとうございました!私は若干異なる解決策で巻き上げましたが、あなたは正しい答えをあなたに明示しました。

私のアプリケーションでは、mainに多くのコントロールがあり、mainのメソッド呼び出しの大部分はmainのスコープ内から発生していましたので、デフォルトの{get; MainWindow.xaml.cs内でset(またはXAMLでコントロールを定義するだけです)。

親ウィンドウのコードビハインドでは、このような別のスレッドでMainWindowを起動します(簡略化された例)。キーは)それはWindow_Loaded(の内側にインスタンス化されるにもかかわらず、世界的に主要な定義することである:それはシンプルなシングルスレッドのアプリケーションであるかのように

public ParentWindow() 
    { 
     InitializeComponent(); 
    } 

    MainWindow main; 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     Thread otherThread = new Thread(() => 
     { 
      main = new MainWindow(); 
      main.Show(); 

      main.Closed += (sender2, e2) => 
       main.Dispatcher.InvokeShutdown(); 

      System.Windows.Threading.Dispatcher.Run(); 
     }); 

     otherThread.SetApartmentState(ApartmentState.STA); 
     otherThread.Start(); 

    } 

はその後、私のメイン・ウィンドウのコードビハインドで、私はコントロールと対話します(私の場合、子スレッドからの親スレッドの制御はありません)。私は、しかし、このような親スレッドからメインを制御することができます。

private void button_Click(object sender, RoutedEventArgs e) 
     { 
      main.Dispatcher.Invoke(new Action(delegate() 
       { 
        main.myControl.myMethod(); 
       })); 

     } 

それをこのようにすることで、私はコードビハインドですべてのものを定義し、メインウィンドウのコードビハインド内からディスパッチャを使用しての複雑さを避けます.xaml.cs。私のアプリケーションでは、親ウィンドウからメインを変更する場所がほんの少ししかないので、これは私の方が簡単でしたが、あなたのアプローチは同様に有効です。再度、感謝します!

2

答えのおかげで、彼らは正しい方向に私を導いた。私は、メッセージがnamedPipelineを介して受信されたときに最小化したウィンドウを表示する

internal static void pipeServer_MessageReceived(object sender, MessageReceivedEventArgs e) 
    { 
     MainWindow.main.Dispatcher.Invoke(new Action(delegate() 
     { 
      MainWindow.main.WindowState = WindowState.Normal; 
     })); 
    } 

この:異なるthredで実行される別のクラスの私のEventHandlerに続いて

public partial class MainWindow : Window 
{ 
    public static MainWindow main; 

    public MainWindow() 
    { 
     InitializeComponent();       
     main = this; 
    } 
} 

:私はこの単純な解決策になってしまいました。

関連する問題