Closable tabitem。如何添加文本框?

时间:2011-11-11 10:43:03

标签: c# wpf multithreading textbox

我正在开发一个多线程应用程序,为每个新线程打开一个新的“可关闭”选项卡。我从this site获得了可关闭的tabitems的代码,但我也希望在tabitem中有一个文本框。我厌倦了在运行时从main方法添加文本框,但是无法从之后创建的线程访问它。这项工作的最佳方法是什么?我正在寻找将文本框添加到可关闭选项卡的最佳方法,我可以从其他工作线程编辑它。

修改 我添加了一些示例代码来展示我想要实现的目标。

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

这是工人阶级。

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。

最诚挚的问候!

2 个答案:

答案 0 :(得分:0)

看到你的编辑后,很明显我原来的帖子没有回答原来的问题。

我认为以您希望的方式访问文本框需要将tabItem.Content转换为文本框。

下面的内容可以正常工作

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

答案 1 :(得分:0)

WPF无法修改在不同线程上创建的项目,而不是当前的线程

如果您还没有,我强烈建议您查看MVVM设计模式。这将UI层与业务逻辑层分开。您的应用程序将成为您的ViewModel类,UI层(视图)只是一个漂亮的界面,允许用户轻松地与ViewModel交互。

这意味着所有UI组件都将共享一个线程,而较长时间运行的进程(如检索数据或处理数字)可以安全地在后台线程上完成。

例如,您可以将TabControl.ItemsSource绑定到ObservableCollection<TabViewModels>,当您执行AddTabCommand时,您将启动新的后台工作程序以添加新的TabViewModel MainViewModel.TabViewModels集合。

一旦后台工作人员完成了它的工作。 UI会自动通知集合中有一个新项目,并使用您指定的任何DataTemplate为您在TabItem中绘制新的TabControl