2013-03-15 1 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(() =>{.......... 또는 다른 것을 사용하여이 문제를 해결할 수 있습니까?

편집 : 나 한테 전화하려고 다른 클래스에서이 라벨 변경 작업을 해요로-잘 별도의 스레드

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 내 질문을 해결

status_lable.Dispatcher.Invoke(...) 
+0

왜 투표가 다운 되었습니까? – iJay

+0

아마,이 질문은 번잡 한 시간에 응답 되었기 때문일 수 있습니다. 일부 '인터넷 검색'은 적절한 해결책을 제공합니다. – DHN

답변

22

, 사람이 필요합니다 희망 : 오프라인 var에 윈의 반환 오류 The calling thread cannot access this object because a different thread owns it.

+1

정말 고마워! – MDDDC

2

시도 조각 아래 주셔서 감사합니다, 저를 인도 해주십시오. 그러나 이것이 최적화 된 방법인지 여부를 모릅니다. 내 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

응답 해 주셔서 감사합니다. 하지만 내 문제는 다른 스레드로 인해 발생합니다. – 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의 범위에서 발생 했으므로 default {get; MainWindow.xaml.cs 내의 set (또는 XAML의 컨트롤 정의).

부모 윈도우의 코드 숨김에서이 ​​(단순화 된 예)와 같이 별도의 스레드에서 MainWindow를 실행합니다.핵심은이 Window_Loaded()의 내부에 인스턴스화에도 불구하고, 세계의 주요 정의하는 것입니다 : 코드 숨김 내 MainWindow를에서 그런

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

     } 

, 나는 코드 숨김에서 모든 것을 정의하고 MainWindow를의 코드 숨김 내에서 발송자를 사용의 복잡성을 피하기 .xaml.cs. 내 응용 프로그램에는 상위 창에서 main을 수정하는 위치가 몇 개 밖에 없으므로이 방법이 더 간단하지만 사용자의 접근 방식도 똑같이 유효합니다. 다시 한 번 감사드립니다!

2

대답 덕분에 그들은 저를 올바른 방향으로 인도했습니다. 내가 메시지가 namedPipeline를 통해 수신 될 때

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

이 최소화 된 창을 표시하려면

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

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

그런 다음 다른 thred에서 실행되는 다른 클래스 내 이벤트 핸들러에서 :이 간단한 해결책을 종료 .

관련 문제