Я разрабатываю графический интерфейс, где пользователь может подключиться к серверу и читать данные. Данные должны отображаться в графическом интерфейсе. Для этого я использую TabControl, чье ContentTemplate установлено в RichTextBox. Код XAML выглядит следующим образом:
<TabControl x:Name="tabControl1" HorizontalAlignment="Stretch" MinHeight="50" Margin="0,0,0,0.2" Width="884"
ItemsSource="{Binding Titles, Mode=TwoWay}" Height="454" VerticalAlignment="Bottom">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<RichTextBox Margin="10" VerticalScrollBarVisibility="Visible" >
<FlowDocument>
<Paragraph FontSize="12" FontFamily="Courier New">
<Run Text="{Binding Content}"></Run>
</Paragraph>
</FlowDocument>
</RichTextBox>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
Фоновый код для добавления новой вкладки и установки ее заголовка / содержимого (статический) ниже
public class MainWindowVM : INotifyPropertyChanged
{
public MainWindowVM()
{
Titles = new ObservableCollection<Item>();
}
public class Item
{
public string Header { get; set; }
public string Content { get; set; }
}
public ObservableCollection<Item> Titles
{
get { return _titles; }
set
{
_titles = value;
OnPropertyChanged("Titles");
}
}
static int tabs = 1;
private ObservableCollection<Item> _titles;
private ICommand _addTab;
private ICommand _removeTab;
public ICommand AddTab
{
get
{
_addTab = new TabRelayCommand(
x =>
{
AddTabItem();
});
return _addTab;
}
}
public ICommand RemoveTab
{
get
{
_removeTab = new TabRelayCommand(
x =>
{
RemoveTabItem();
});
return _removeTab;
}
}
private void RemoveTabItem()
{
if (Titles.Count > 0)
{
Titles.Remove(Titles.Last());
tabs--;
}
}
public Item AddTabItem()
{
var header = "Log_" + tabs;
var content = "Content " + tabs;
var item = new Item { Header = header, Content = content };
Titles.Add(item);
tabs++;
OnPropertyChanged("Titles");
return item;
}
public void AddTabItem(string strFileName, string strContent)
{
var header = strFileName;
var content = strContent;
var item = new Item { Header = header, Content = content };
Titles.Add(item);
tabs++;
OnPropertyChanged("Titles");
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Однако мне нужно установить содержимоезаголовок динамически (данные читаются из сокета). Я могу прочитать данные, которые у меня есть в формате строки. Пожалуйста, предложите мне, как мне установить содержимое RichTextBox, добавив строку. Я новичок в C #. Заранее спасибо
Редактировать : после нажатия кнопки мое приложение подключается к серверу. Также я запускаю параллельное задание, которое читает данные из сокета.
Проблема: Слишком много процессорного времени занято (я вижу до 80 в разделе Процессы в диспетчере задач).
private void BtnConnect_Click(object sender, RoutedEventArgs e)
{
//connect
TCPClientClass tcpClient = TCPConnHandler.ConnectToService(tbIPAddress.Text);
if (tcpClient != null)
{
MessageBox.Show("Connected to " + tbIPAddress.Text);
//open new tab
var item = MainWindowVMObj.AddTabItem();
//now run a task to display the data in the tab
Thread thTabControl = new Thread(() =>
{
while (tcpClient.Connected)
{
String str = tcpClient.GetDataFromServer();
if (!String.IsNullOrEmpty(str))
tabControl1.Dispatcher.BeginInvoke((Action)(() => item.Content += str));
Thread.Sleep(200);
}
//item.Dispatcher.BeginInvoke
});
thTabControl.Start();
}
}