Как очищать textBox при каждом нажатии на кнопку

не могу понять логику работы, в начале события button_onclick вызываю textBox.Clear(), т.е. жду что при каждом нажатии на эту кнопку текстБокс будет очищаться, но если не закрывать форму этого не происходит, результат вывода накапливается. В этом куске кода:

private void but_OK_Click(object sender, EventArgs e)
        {
            txt_output.Clear();
            string str_input = txt_input.Text;

            Format_Rule(str_input);

            for (int i = 0; i < str_in.Count; i++)
            {
                txt_output.Text += str_in.GetKey(i) + " " + str_in.Get(i) + Environment.NewLine;
            }
        }

Тут весь код

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ТЯП_Лаб1
{
    public partial class Form1 : Form
    {
        NameValueCollection str_in = new NameValueCollection();

        string alphabet = "abcdefghijklmnopqrstuvwxyz";
        string alpha_number = "0123456789";
        string alpha_operand = "-+*/";

        private bool Search_Operand(string str)
        {
            for (int i = 0; i < alpha_operand.Length; i++)
            {
                if (str.Contains(alpha_operand[i]))
                {
                    return true;
                }
            }
            return false;
        }

        private bool Search_Number(string str)
        {
            for (int i = 0; i < alpha_number.Length; i++)
            {
                if (str.Contains(alpha_number[i]))
                {
                    return true;
                }
            }
            return false;
        }

        private bool Search_Word(string str)
        {
            for (int i = 0; i < alphabet.Length; i++)
            {
                if (str.Contains(alphabet[i]))
                {
                    return true;
                }
            }
            return false;
        }
        
        private void Format_Rule(string str )
        {
            string str_oper = "";
            string str_set = "";

            if (!Search_Operand(str))
            {
                for (int i = 0; i < str.Length; i++)
                {
                    if(i == str.Length)
                        str_set += str[i];
                    else
                        str_set += str[i] + " | ";
                }

                str_in.Add("S->", "T");
                str_in.Add("T->", "T | TF");
                str_in.Add("F->", str_set);

            }
            else
            {
                for (int i = 0; i < str.Length; i++)
                {
                    if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
                    {
                        if(i != str.Length)
                            str_oper += str[i] + "T" + " | ";
                        else
                            str_oper += str[i] + "T";
                    }
                    else
                    {
                        if(i != str.Length)
                            str_set += str[i] + " | ";
                        else
                            str_set += str[i];
                    }
                }

                str_in.Add("S->", str_oper);
                str_in.Add("T->", "T | TF");
                str_in.Add("F->", str_set);
            }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void but_OK_Click(object sender, EventArgs e)
        {
            txt_output.Clear();
            string str_input = txt_input.Text;

            Format_Rule(str_input);

            for (int i = 0; i < str_in.Count; i++)
            {
                txt_output.Text += str_in.GetKey(i) + " " + str_in.Get(i) + Environment.NewLine;
            }
        }
    }
}

как должно быть

как не должно быть


Ответы (1 шт):

Автор решения: aepot

Вероятно проблема в том что вы не очищаете коллекцию str_in, и добавляются в неё новые значения, которые затем у вас отображаются через зарятую.

Уберите объявление

NameValueCollection str_in = new NameValueCollection(); // убрать строку

И попробуйте вот так через возвращение значения

// добавил тип возвращаемого значения
private NameValueCollection Format_Rule(string str)
{
    string str_oper = "";
    string str_set = "";
    NameValueCollection str_in = new NameValueCollection(); // добавил строку

    if (!Search_Operand(str))
    {
        for (int i = 0; i < str.Length; i++)
        {
            if (i == str.Length)
                str_set += str[i];
            else
                str_set += str[i] + " | ";
        }

        str_in.Add("S->", "T");
        str_in.Add("T->", "T | TF");
        str_in.Add("F->", str_set);

    }
    else
    {
        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
            {
                if (i != str.Length)
                    str_oper += str[i] + "T" + " | ";
                else
                    str_oper += str[i] + "T";
            }
            else
            {
                if (i != str.Length)
                    str_set += str[i] + " | ";
                else
                    str_set += str[i];
            }
        }

        str_in.Add("S->", str_oper);
        str_in.Add("T->", "T | TF");
        str_in.Add("F->", str_set);
    }
    return str_in; // вернул результат
}

Далее немного перепишу код следующего метода, чтобы строку формировать не в контроле, а через StringBuilder.

private void but_OK_Click(object sender, EventArgs e)
{
    NameValueCollection str_in = Format_Rule(txt_input.Text);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < str_in.Count; i++)
    {
        sb.AppendLine(str_in.GetKey(i) + " " + str_in.Get(i));
    }
    txt_output.Text = sb.ToString();
}

Должно сработать. Очищать текстбокс здесь не требуется, так как его значение будет просто заменяться на новое.


А если ещё красивее сделать, то строку

sb.AppendLine(str_in.GetKey(i) + " " + str_in.Get(i));

Лучше записать так

sb.Append(str_in.GetKey(i)).Append(' ').AppendLine(str_in.Get(i));

Ещё косметическое замечание. В C# не принято использовать символы подчёркивания в названии методов, несмотря на то что Winforms их в названиях методов по умолчанию подставляет. По возможности стоит избегать в названиях сокращений и аббревиатур, это упрощает чтение кода. Также методы стоит писать с большой буквы итого методы можно переименовать так:

Search_Operand -> SearchOperand
Search_Number -> SearchNumber
Search_Word -> SearchWord
Format_Rule -> FormatRule
but_OK_Click -> ButtonOKClick или даже OnButtonOKClick для обработчика события проще читается.
То есть если все обработчики событий будут начинаться на "On", их будет легче идентифицировать как обработчики.

И последнее, вместо NameValueCollection я бы посоветовал вам познакомиться с более популярным и удобным Dictionary<TKey, TValue>, в вашем случае это будет Dictionary<string, string>.

→ Ссылка