【问题标题】:how to dynamically add content to a rich text box in a wpf application using xaml如何使用 xaml 将内容动态添加到 wpf 应用程序中的富文本框
【发布时间】:2019-10-16 18:07:39
【问题描述】:

我正在开发一个 GUI,用户可以在其中连接到服务器并读取数据。数据需要显示在 GUI 上。为此,我使用了 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# 新手。提前致谢

编辑: 按钮单击事件后,我的应用程序连接到服务器。我还启动了一个从套接字读取数据的并行任务。

面临的问题:占用过多的 CPU 时间(我可以在任务管理器的进程下看到高达 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();
            }

        }

【问题讨论】:

    标签: c# wpf data-binding richtextbox


    【解决方案1】:

    您可以查找Item 以在Titles 中更新并设置其Content 属性。

    例如,这设置ObservableCollection&lt;Item&gt;中第一项(索引0)的属性:

    Titles[0].Content += "append...";
    

    Item 类还应该实现 INotifyPropertyChanged 以便您在不切换选项卡的情况下查看更改:

    public class Item : INotifyPropertyChanged
    {
        public string Header { get; set; }
    
        private string _content;
        public string Content
        {
            get { return _content; }
            set { _content = value; OnPropertyChanged(nameof(Content)); }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    【讨论】:

    • 非常感谢。我能够显示内容。然而,我的数据只显示一次,无论我更新这样的内容:Task.Run(() => { String str = tcpClient.GetDataFromServer(); item.Content += str; }
    • 在您的示例中item 是什么,您是否按照我向您展示的那样实现INotifyPropertyChanged
    • 我通过无限循环运行任务来修复它,我错过了。因此,数据的获取只发生了一次。
    猜你喜欢
    • 1970-01-01
    • 2012-12-07
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2013-09-23
    • 1970-01-01
    • 2013-09-04
    相关资源
    最近更新 更多