Закрываемый табитем. Как добавить текстовое поле? - PullRequest
0 голосов
/ 11 ноября 2011

Я работаю над многопоточным приложением, в котором для каждого нового потока открывается новая вкладка «закрываемый».Я получил код для закрываемых табитем от этого сайта , но я также хочу иметь текстовое поле в табитеме.Я устал добавлять текстовое поле во время выполнения из основного метода, но он не был доступен из потока, который был создан после.Каков наилучший способ сделать эту работу?Я ищу лучший способ добавить текстовое поле на закрываемые вкладки, которые я могу редактировать из других рабочих потоков.

РЕДАКТИРОВАТЬ: Я добавил несколько примеров кода, чтобы показать, что я 'я пытаюсь достичь.

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 недоступен.

С наилучшими пожеланиями!

Ответы [ 2 ]

0 голосов
/ 11 ноября 2011

WPF не может изменять элементы, созданные в другом потоке, отличном от текущего

Если вы еще этого не сделали, я настоятельно рекомендую вам взглянуть на шаблон проектирования MVVM. Это отделяет уровень пользовательского интерфейса от уровня бизнес-логики. Ваше приложение становится вашими ViewModel классами, а слой пользовательского интерфейса (Views) - это просто симпатичный интерфейс, который позволяет пользователям легко взаимодействовать с ViewModels.

Это означает, что все ваши компоненты пользовательского интерфейса будут совместно использовать один поток, в то время как более длительные процессы, такие как извлечение данных или сжатие чисел, могут безопасно выполняться в фоновых потоках.

Например, вы можете связать свой TabControl.ItemsSource с ObservableCollection<TabViewModels>, а когда вы выполните AddTabCommand, вы запустите нового фонового работника для добавления нового TabViewModel в коллекцию MainViewModel.TabViewModels.

Как только фоновый работник заканчивает свою работу. пользовательский интерфейс автоматически получает уведомление о наличии нового элемента в коллекции и рисует для вас новый TabItem в TabControl, используя любой указанный вами DataTemplate.

0 голосов
/ 11 ноября 2011

После просмотра ваших изменений ясно, что мой оригинальный пост не отвечал на исходный вопрос.

Я думаю, чтобы получить доступ к текстовому полю, как вам нужно, вам нужно привести 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...