2011-11-11 7 views
0

マルチスレッドアプリケーションでは、新しいスレッドごとに新しい「クローズ可能」タブが開かれています。私はthis siteからクローズ可能なtabitemsのコードを得ましたが、私はまた、tabitemにテキストボックスを持っています。メインメソッドからランタイム中にテキストボックスを追加するのに疲れましたが、後で作成されたスレッドからアクセスできませんでした。この仕事をする最も良い方法は何ですか?私は、他のワーカースレッドから編集できる、閉じることのできるタブにテキストボックスを追加する最善の方法を探しています。閉じるtabitem。テキストボックスを追加するには?

編集: 私は達成しようとしていることを示すためにいくつかのサンプルコードを追加しました。

namespace SampleTabControl 
{ 
    public partial class Window1 : Window 
    { 
    public static Window1 myWindow1; 

    public Window1() 
    { 
     myWindow1 = this; 
     InitializeComponent(); 
     this.AddHandler(CloseableTabItem.CloseTabEvent, new RoutedEventHandler(this.CloseTab));  
    } 

    private void CloseTab(object source, RoutedEventArgs args) 
    { 
     TabItem tabItem = args.Source as TabItem; 
     if (tabItem != null) 
     { 
     TabControl tabControl = tabItem.Parent as TabControl; 
     if (tabControl != null) 
      tabControl.Items.Remove(tabItem); 
     } 
    } 

    private void btnAdd_Click(object sender, RoutedEventArgs e) 
    { 
     Worker worker = new Worker(); 

     Thread[] threads = new Thread[1]; 
     for (int i = 0; i < 1; i++) 
     { 
     TextBox statusBox = new TextBox(); 

     CloseableTabItem tabItem = new CloseableTabItem(); 
     tabItem.Content = statusBox; 
     MainTab.Items.Add(tabItem); 

     int index = i; 
     threads[i] = new Thread(new ParameterizedThreadStart(worker.start)); 
     threads[i].IsBackground = true; 
     threads[i].Start(tabItem); 
     }  
    } 
    } 
} 

これはWorkerクラスです。

namespace SampleTabControl 
{ 
    class Worker 
    { 
    public CloseableTabItem tabItem; 

    public void start(object threadParam) 
    { 
     tabItem = (CloseableTabItem)threadParam; 
     Window1.myWindow1.Dispatcher.BeginInvoke((Action)(() => { tabItem.Header = "TEST"; }), System.Windows.Threading.DispatcherPriority.Normal); 
     //Window1.myWindow1.Dispatcher.BeginInvoke((Action)(() => { tabItem.statusBox.Text //statusbox is not accesible here= "THIS IS THE TEXT"; }), System.Windows.Threading.DispatcherPriority.Normal); 

     while (true) 
     { 
     Console.Beep(); 
     Thread.Sleep(1000); 
     } 
    } 

    } 
} 

私がコメントアウトした行では、statusBoxにアクセスできません。

よろしく!

答えて

0

編集を確認した後、元の投稿が元の質問に回答していなかったことは明らかです。

私はあなたがテキストボックスにtabItem.Contentをキャストする必要がある方法でテキストボックスにアクセスすると思います。以下のような

何かがWPFは、あなたがまだの場合は、私は非常にあなたがに見えることをお勧めします現在の1

その後、別のスレッドで作成された項目を変更することはできません

TextBox t = tabItem.Content as TextBox; 
if (t != null) 
    Window1.myWindow1.Dispatcher.BeginInvoke((Action)(() => { t.Text = "THIS IS THE TEXT";}), System.Windows.Threading.DispatcherPriority.Normal); 
+0

はい、私はディスパッチャについて知っていますが、実行時にテキストボックスを閉じることができるタブに追加すると、アクセスできなくなります。私はあなたが見ることができるようにいくつかのサンプルコードを追加します。 – Arya

+0

"TextBox t = tabItem.ContentをTextBoxとして;"実行時にプログラムをクラッシュさせます。 – Arya

+0

私はちょうどエラーメッセージをチェックし、これは "それは別のスレッドが所有しているため、このオブジェクトにアクセスすることはできません"ということです。私はそれを修正する方法を教えていただけますか? – Arya

0

を仕事ができますMVVMデザインパターンこれにより、UIレイヤーとビジネスロジックレイヤーが分離されます。あなたのアプリケーションは、あなたのViewModelクラスになり、UIレイヤー(ビュー)は、ユーザーがViewModelと簡単にやり取りできるようにする簡単なインターフェイスです。

これは、すべてのUIコンポーネントが1つのスレッドを共有し、データの取得や数値の処理などの実行中のプロセスがすべてバックグラウンドスレッドで安全に実行できることを意味します。

はたとえば、あなたはあなたのTabControl.ItemsSourceObservableCollection<TabViewModels>に特異的に結合することができ、あなたが実行したときにAddTabCommandあなたはMainViewModel.TabViewModelsコレクションに新しいTabViewModelを追加する新しいバックグラウンドワーカーを開始します。

バックグラウンドワーカーが終了すると、そのジョブが終了します。 UIにはコレクション内に新しいアイテムがあることが自動的に通知され、指定するDataTemplateを使用してTabControlに新しいTabItemが描画されます。

関連する問題