2011-06-21 9 views
5

winformsからWPFにプロジェクトを移行しています。私のコードがWinFormsに基づいていたときに、スレッドがアクセス権を持っているかどうかをチェックするために(this.InvokeRequired)使用しました。今私は私のメインフォームに基づいて、次のコードを使用します:バックグラウンドワーカーからのUIアクセスに関する問題

// this is the delegate declaration to Allow Background worker thread to write to Log Output 
    delegate void LogUpdateCallBack(String LogMessage); 

    // method to update the Log Window from the Background Thread 
    public void LogUpdate(String LogMessage) 
    { 
     Console.WriteLine("Entering"); 
     if (!Application.Current.Dispatcher.CheckAccess()) 
     { 
      Console.WriteLine("Thread doesn't have UI access"); 
      LogUpdateCallBack callback = new LogUpdateCallBack(LogUpdate); 
      Application.Current.Dispatcher.Invoke(callback, LogMessage); 
     } 
     else 
     { 
      Console.WriteLine("Thread has UI access"); 
      listBox_Output.Items.Add(LogMessage); 
      Console.WriteLine(LogMessage); 
      // listBox_Output.TopIndex = listBox_Output.Items.Count - 1; 
     } 
     Console.WriteLine("Exiting"); 
    } 

私が持っている問題は、リストボックスが更新されていないということです。エラーや例外はありません。他のUIコントロールを更新しようとしました。 LogMessageは出力ウィンドウに書き込んでいますので、私は困惑しています。

Entering 
Thread doesn't have UI access 
Entering 
Thread has UI access 
My LogMessage is output here 
Exiting 
Exiting 
Entering 
Thread doesn't have UI access 
Entering 
Thread has UI access 
My LogMessage is output here 
Exiting 
Exiting 

が、私はそれが私のリストボックスではなく運の問題だ場合だけチェックするために、他のUIコントロールを更新しようとしました:

はここでサンプルコンソール出力です。

CheckAccess()に切り替える以外に、私が新しいWPFコードで行った唯一の大きな変更は、バックグラウンドワーカーで実行中のすべてのコードを別のクラスのベースにすることです。問題の一部になるのか?

-

@JonRaynor

私はあなたのアイデアを試してみました:

Application.Current.Dispatcher.BeginInvoke(new LogUpdateCallBack(LogUpdate), LogMessage) 

I出力

Console.WriteLine(listBox_Output); 

は私がリストを見れば、私のリストボックスはまだ、更新されていませんしかし、ボックスアレイの成長:

System.Windows.Controls.ListBox Items.Count:2020 
System.Windows.Controls.ListBox Items.Count:2021 
System.Windows.Controls.ListBox Items.Count:2022 
System.Windows.Controls.ListBox Items.Count:2023 
System.Windows.Controls.ListBox Items.Count:2024 
System.Windows.Controls.ListBox Items.Count:2025 

ただし、フォームに変更はありません。これは非常に混乱しています!

+0

リストボックス上の任意のデータバインディングを? Page_LoadイベントのItems.Add( "test")は機能しますか? –

+0

データバインディングがありません。ListBoxを他の領域から難なくアップデートしています。私はリストボックスの問題になった場合に備えて、他のUIコントロールを更新しようとしました。 – mrbencowell

+0

もう1つ奇妙なことに注意してください。コンソールでlistBox_Outputを出力すると、項目が追加されていることがわかります(項目数が報告されている)ので、UIが追加されていないようです全く更新されました。私はlistBox_Output.InvalidateVisual()を試した。何の効果もありません。 – mrbencowell

答えて

1

私はこれを最終的に解決しました。

私の問題は、別のスレッドと別のクラスの両方からLogUpdateメソッドを呼び出すときに、メインクラスの新しいインスタンスを作成するのではなく、このクラスにリストボックスを含むメインフォームへの参照を渡す必要がありました。二次クラスのフォーム。

そうではなく、私の第二のクラスで、この宣言を持っている:

public MainWindow MainForm = new MainWindow(); 

私は二クラスのメソッドに、フォームの参照を渡すために必要な:

public void Plot(BackgroundWorker worker, MainWindow MainForm) 
2

私はWPFでも始まりました。以前のWinFormsのやり方から再学習しなければなりませんでした。私は...私の画面(フォーム)にWPFでは

public delegate void WorkCompleted(); 

     /// <summary> 
     /// Marks the end of the progress 
     /// </summary> 
     private void ProgressComplete() 
     { 
      if (!this.Dispatcher.CheckAccess()) 
      { 
       this.Dispatcher.BeginInvoke(new WorkCompleted(ProgressComplete), System.Windows.Threading.DispatcherPriority.Normal, null); 
      } 
      else 
      { 
       this.buttonClose.Visibility = Visibility.Visible; 
       this.progressBarStatus.IsIndeterminate = false; 
      } 
     } 
+0

提案していただきありがとうございます。私はこの方法を試して、どこに行っても見ていきます。 – mrbencowell

0

をBeginInvokeを()と構文のこのタイプを使用してきた、すべてのUIコントロールがDispatcherObjectから派生しています。つまり、ListBoxコントロール自体がディスパッチ可能なオブジェクトであることを意味します。フォーム自体に頼るのではなく、そのオブジェクトのDispatcherを呼び出すようにしてください。代理人のパラメータを取り出してください(とにかくLogMessage変数にアクセスできるため):

public void LogUpdate(string LogMessage) 
{ 
    Console.WriteLine("Entering"); 
    if (listBox_Output.Dispatcher.CheckAccess()) 
    { 
     listBox_Output.Dispatcher.Invoke(new LogUpdateCallBack(delegate 
     { 
      listBox_Output.Items.Add(LogMessage); 
     })); 
     Console.WriteLine(LogMessage); 
    } 
} 
+0

提案してくれてありがとうございますが、別のクラスのMainFormのインスタンスを宣言したことを誤解していましたが、これでmainformへのアクセスが可能になると仮定しましたが、コントロール私は結果を見ませんでした。 – mrbencowell

関連する問題