0

我怎样才能在richTextBox过滤器(例如连接combobox)中实现只负责显示包含所选单词(过滤器)的行?

我不是在谈论删除其他行 - 只是“隐藏”。

可能吗?

最终我可以使用另一种类型控件,但如果不需要,我想使用richTextBox。

我现在想,以某种结构存储数据,并基于这种使用的结构进行过滤。但不知道这是否是有效的解决方案。

4

5 回答 5

1

尝试做这样的事情

    public string[] RtbFullText;

    private void button7_Click(object sender, EventArgs e)
    {
        RtbFullText = richTextBox1.Text.Split('\n');
    }

    private void button8_Click(object sender, EventArgs e)
    {
        //Filter
        richTextBox1.Text = "";
        foreach (string _s in RtbFullText)
        {
            if (_s.Contains("Filter"))
                richTextBox1.Text += _s + "\n";
        }
    }
于 2012-04-17T09:59:16.517 回答
1

天哪,我做到了,使用这个类:

    public class ListWithRTB : IList
    {
        private List<string> _contents = new List<string>();
        private int _count;
        string lastsearch = "";

        public ListWithRTB()
        {
            _count = 0;
        }

        public object rtb;

        private void UpdateRtb(string search)
        {
            lastsearch = search;
            if (rtb is RichTextBox)
            {
                ((RichTextBox)rtb).Text = "";
                List<string> help_contents;
                if (search != "")
                    help_contents = _contents.Where(s => s.Contains(search)).ToList();
                else
                    help_contents = _contents;
                for (int i = 0; i < help_contents.Count; i++)
                {
                    ((RichTextBox)rtb).Text += help_contents[i] + "\n";
                }
            }
        }

        public void Filter(string search)
        {
            UpdateRtb(search);
        }

        public int Add(object value)
        {
            if (_count < _contents.Count + 1)
            {
                _contents.Add((string)value);
                _count++;
                UpdateRtb(lastsearch);
                return (_count);
            }
            else
            {
                return -1;
            }
        }

        public void RemoveAt(int index)
        {
            _contents.RemoveAt(index);
            _count--;
            UpdateRtb(lastsearch);
        }

        public void Clear()
        {
            _contents.Clear();
            UpdateRtb(lastsearch);
            _count = 0;
        }

        public bool Contains(object value)
        {
            return _contents.Contains((string)value);
        }

        public int IndexOf(object value)
        {
            return _contents.IndexOf((string)value);
        }

        public void Insert(int index, object value)
        {
            _contents.Insert(index,(string) value);
            _count++;
        }

        public bool IsFixedSize
        {
            get
            {
                return false;
            }
        }

        public bool IsReadOnly
        {
            get
            {
                return false;
            }
        }

        public void Remove(object value)
        {
            RemoveAt(IndexOf(value));
        }

        public object this[int index]
        {
            get
            {
                return _contents[index];
            }
            set
            {
                _contents[index] = value.ToString();
            }
        }

        public void CopyTo(Array array, int index)
        {
            int j = index;
            for (int i = 0; i < Count; i++)
            {
                array.SetValue(_contents[i], j);
                j++;
            }
        }

        public int Count
        {
            get
            {
                return _count;
            }
        }

        public bool IsSynchronized
        {
            get
            {
                return false;
            }
        }

        public object SyncRoot
        {
            get
            {
                return this;
            }
        }

        public IEnumerator GetEnumerator()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void PrintContents()
        {
            Console.WriteLine("List has a capacity of {0} and currently has {1} elements.", _contents.Count, _count);
            Console.Write("List contents:");
            for (int i = 0; i < Count; i++)
            {
                Console.Write(" {0}", _contents[i]);
            }
            Console.WriteLine();
        }

    }

这就是你如何使用它

ListWithRTB _mlrtb = new ListWithRTB();

    private void button1_Click(object sender, EventArgs e)
    {
        _mlrtb.rtb = richTextBox1;
        _mlrtb.Add("Filter");
        _mlrtb.Add("123");
        _mlrtb.Add("111 Filter");
    }

    private void button2_Click(object sender, EventArgs e)
    {
        _mlrtb.Filter("Filter");
    }

    private void button3_Click(object sender, EventArgs e)
    {
        _mlrtb.Filter("");
    }
于 2012-04-18T13:01:20.530 回答
1

所以你可以这样做

public class NewRichTextBox : RichTextBox
{
    public string[] TotalText;
    private bool filter = false;
    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        if (!filter)
            TotalText = Text.Split('\n');
    }
    public void Filter(string sf)
    {
        filter = true;
        Text = "";
        foreach (string _s in TotalText)
        {
            if (_s.Contains(sf))
                Text += _s + "\n";
        }
        filter = false;
    }
}

    public Form1()
    {
        InitializeComponent();
        NewRichTextBox myrtb = new NewRichTextBox();
        myrtb.Name = "NRTB";
        Controls.Add(myrtb);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        NewRichTextBox mtrb = (NewRichTextBox)Controls.Find("NRTB", false)[0];
        mtrb.Filter("Filter");
    }
于 2012-04-17T11:32:42.960 回答
0
 private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (!string.IsNullOrEmpty(SearchableString) && !string.IsNullOrEmpty(FullRichtxt))
        {
            var SplitedTxt = FullRichtxt.Split('\n').ToList<string>();
            List<string> filterlist = SplitedTxt.Where(x => x.Contains(contx.SearchableString)).ToList<string>();
            string FilterString=string.Empty;
            foreach(string str in filterlist)
            {
                FilterString+=str+"\n";
            }
           (RichTextBox1 as  RichTextBox).AppendText(FilterString);
        }
    }
于 2017-11-30T09:40:37.013 回答
0

我知道这是一个非常古老的问题,但是我遇到了同样的问题并实现了它,它也保留了任何 RTF 格式。

    /// <summary>
    /// This Control allows to filter the content of the RichTextBox by either manually
    /// calling <c>ApplyFilter(string)</c> with the search string or specifying a TextBox Control
    /// as a filter reference. 
    /// 
    /// Matching lines will be retained, other will be deleted.
    /// 
    /// Retains RTF formatting and when removing the filter restores the original content.
    /// 
    /// Ideal for a Debug Console.
    /// 
    /// </summary>
    public class RichFilterableTextBox : RichTextBox
    {
        private Timer timer;
        private string OriginalRTF = null;
        private TextBox _filterReference;
        private int _interval = 2000;

        public TextBox FilterReference
        {
            get => _filterReference;
            set
            {
                //if we had already a filter reference
                if (_filterReference != null)
                {
                    //we should remove the event
                    _filterReference.TextChanged -= FilterChanged;
                }

                _filterReference = value;

                //if our new filter reference is not null we need to register our event
                if (_filterReference != null)
                    _filterReference.TextChanged += FilterChanged;
            }
        }

        /// <summary>
        /// After the filter has been entered into the FilerReference TextBox 
        /// this will auto apply the filter once the interval has been passed.
        /// </summary>
        public int Interval
        {
            get => _interval;
            set
            {
                _interval = value;
                timer.Interval = Interval;
            }
        }
        public RichFilterableTextBox()
        {
            timer = new Timer();
            timer.Interval = Interval;
            timer.Tick += TimerIntervalTrigger;
        }

        public void SetFilterControl(TextBox textbox)
        {
            this.FilterReference = textbox;
        }

        public void ApplyFilter(string searchstring)
        {
            int startIndex = 0;
            int offset = 0;

            //check each line
            foreach (var line in this.Lines)
            {
                offset = 0;
                SelectionStart = startIndex + offset;
                SelectionLength = line.Length + 1;

                //if our line contains our search string/filter
                if (line.Contains(searchstring))
                {
                    //we apply an offset based on the line length
                    offset = line.Length;
                }
                else
                {
                    //otherwise delete the line
                    SelectedText = "";
                }

                //move the start index forward based on the current selected text
                startIndex += this.SelectedText.Length;
            }
        }

        private void FilterChanged(object sender, EventArgs e)
        {
            //take snapshot of original
            if (OriginalRTF == null)
            {
                OriginalRTF = this.Rtf;
            }
            else
            {
                //restore original
                Rtf = OriginalRTF;
                OriginalRTF = null;
            }

            timer.Stop();
            timer.Start();
        }
        private void TimerIntervalTrigger(object sender, EventArgs e)
        {
            //stop the timer to avoid multiple triggers
            timer.Stop();

            //apply the filter
            ApplyFilter(FilterReference.Text);
        }
        protected override void Dispose(bool disposing)
        {
            timer.Stop();
            timer.Dispose();

            base.Dispose(disposing);
        }
    }

此控件既可以单独使用,也可以通过调用 ApplyFilter(string searchString)具有所需搜索字符串的方法进行过滤。或者它可以连接到TextBox 您可以输入短语的位置。在设置的计时器间隔后,它将自动触发过滤。

我在运行时将其用作日志显示,我还将颜色代码应用于严重性,我的目标是保留格式并能够快速搜索/过滤。我附上了几张截图:

调试控制台示例

应用过滤器

仍有改进的空间,我希望这可以用作起始代码库。

于 2020-02-28T04:48:52.483 回答