【问题标题】:Button "clear" on a TextBox line appears only once文本框行上的“清除”按钮仅出现一次
【发布时间】:2018-08-01 10:21:20
【问题描述】:

我设法用很少的代码在 TextBox 行上获得了一个清晰的按钮。这会在单击时删除相应的行及其自身。但是该按钮只出现一次。它应该在每次单击每条附加行时生成。有人可以帮我吗?非常感谢。

是WinForm VS2010 C#

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

namespace Daten_zu_TextBox_Test
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Button btn1 = new Button();
        btn1.Name = "btn";
        btn1.Click += new EventHandler(btn1_Click);
        btn1.Size = new Size(18, 18);
        btn1.Text = "X";
        btn1.ForeColor = Color.Red;
        textBox1.Controls.Add(btn1);

        string sent = ("\t" + "Testline1");

        textBox1.AppendText(sent);
        textBox1.AppendText(Environment.NewLine);
    }

    void btn1_Click(object sender, EventArgs e)
    {
        textBox1.Controls.Clear();
        textBox1.Text = textBox1.Text.Remove(1, textBox1.Lines[0].Length + 0 );
        textBox1.Text = textBox1.Text.Remove(0, textBox1.Lines[0].Length + 0);
    }

  }
}

private int ButtonCount2 = 0;
private int Btn2Y = 18;
private void button2_Click(object sender, EventArgs e)
{
    Button btn2 = new Button();
    btn2.Name = "btn2" + ButtonCount2;
    btn2.Click += new EventHandler(btn2_Click);
    btn2.Size = new Size(18, 18);
    btn2.Location = new Point(1, Btn2Y * ButtonCount2);

    ButtonCount2++;

    btn2.Text = "X";
    btn2.ForeColor = Color.Red;
    textBox2.Controls.Add(btn2);

    string sent = ("\t" + "Testline" + ButtonCount2);

    textBox2.AppendText(sent);
    textBox2.AppendText(Environment.NewLine);
}
void btn2_Click(object sender, EventArgs e)
{
    var bt2 = sender as Button;
    var bt2Id = textBox2.Controls.IndexOf(bt2);
    textBox2.Controls.Remove(bt2);
    var lines = textBox2.Text.Replace("\r\n", "\n").Split('\n').ToList();
    lines.RemoveAt(bt2Id);
    textBox2.Text = string.Join("\r\n", lines);

    foreach (Button btn2 in textBox2.Controls)
    {
        var Id2 = int.Parse(btn2.Name.Replace("btn2", ""));

        if (Id2 > bt2Id)
        {
            var b2 = textBox2.Controls.Find(btn2.Name, false)[0];
            var loc2 = btn2.Location;
            b2.Location = new Point(loc2.X, loc2.Y - Btn2Y);
         }
    }
    ButtonCount2--;
}

第二个按钮如下所示。

【问题讨论】:

  • 你能把你得到的输出作为图像发布吗?有点难以理解您的要求
  • 看起来像这样。如果按下文本框行中的清除“X”按钮,则使用该按钮删除整行。但他只出现过一次。这应该出现在每一行上,以便可以单独删除每一行。
  • 请考虑转移到此用例的适当控件!想到一个 Listview 或者可能是一个 DataGridView。 TextBox 对于这种事情完全没用,你现在应该已经注意到了..

标签: c# winforms


【解决方案1】:

您将所有X 按钮放在同一位置,位于textbox 之上。实现一些增加按钮 Y 位置的逻辑。可能是这样的:

//... your code here ...
btn1.ForeColor = Color.Red;
//increase Y
// for each control that is inside of textBox, 
// lower your newly created button by count * 18 
// so that btn1.Top will be 0, 18, 36 etc...
btn1.Top = textBox1.Controls.Count * 18; 
textBox1.Controls.Add(btn1); 

另外,正如 WPFUser 所注意到的,在单击 X 按钮时,您将删除所有 X 按钮。我猜你应该删除最后一个,底部一个

编辑 2. 每个按钮都应该删除其对应的行,就像这样(没有测试它:))

void btn1_Click(object sender, EventArgs e)
{
    //remove right line
    text1.Text = text1.Lines[text1.Controls.IndexOf((Control)sender)].Remove(0);
    //remove button
    text1.Controls.Remove(text1.Controls.OfType<Button>().Last());
}

【讨论】:

  • 点击按钮时他正在清除所有控件。那是对的吗 ?我来自 WPF 背景,不确定 WF 控件 VisualTree。
  • @WPFUser 你是对的,OP 应该删除那一行
  • 他应该只用一键删除一行。所以每一行都可以单独删除。
  • @oRole no... 因为在他有 5 行并点击第二行的情况下 - 该行将被删除并且按钮将被移除。但是,随着线被移除,较低的线会上升。现在我们有 4 行和按钮,例如 X(空)X X X。所以,第二行没有 X,但第五行有一个,没有文本。
  • 大家好,太好了,非常感谢!!
【解决方案2】:

@jadolo ,您的代码是正确的,它每次都添加新按钮,但每个按钮都将位于同一位置,因此您将看不到所有按钮,像这样添加按钮的分配位置属性,因此所有按钮都正确显示.

Form1.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {

        int i = 0;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {


        }


        void btn1_Click(object sender, EventArgs e)
        {
            textBox1.Controls.Clear();
            textBox1.Text = textBox1.Text.Remove(1, textBox1.Lines[0].Length + 0);
            textBox1.Text = textBox1.Text.Remove(0, textBox1.Lines[0].Length + 0);
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            Button btn1 = new Button();
            btn1.Name = "btn"+i++;
            btn1.Click += new EventHandler(button1_Click_1);
            btn1.Size = new Size(18,18 );
            btn1.Text = "X";
            btn1.Location = new Point(0, i);
            i += 18;
            btn1.ForeColor = Color.Red;
            this.textBox1.Controls.Add(btn1);


            string sent = ("\t" + "Testline1");

            textBox1.AppendText(sent);
            textBox1.AppendText(Environment.NewLine);


        }
    }
}

设计:

输出:

希望对你有帮助。

【讨论】:

    【解决方案3】:

    以下是经过测试的工作代码。该按钮将与文本框字体大小的文本一致,默认为8

    private int ButtonCount = 0;
    private int BtnY = 13;
    
    private void button1_Click(object sender, EventArgs e)
    {
        Button btn1 = new Button();
        btn1.Name = "btn" + ButtonCount;
        btn1.Click += new EventHandler(btn1_Click);
        btn1.Size = new Size(18, 18);
        btn1.Location = new Point(1, BtnY * ButtonCount);
        btn1.Tag = ButtonCount;  // the last edit
    
        ButtonCount++;
    
        btn1.Text = "X";
        btn1.ForeColor = Color.Red;
        textBox1.Controls.Add(btn1);
    
        string sent = ("\t" + "Testline" + ButtonCount);
    
        textBox1.AppendText(sent);
        textBox1.AppendText(Environment.NewLine);
    }
    
    void btn1_Click(object sender, EventArgs e)
    {
        var bt = sender as Button;
        var btId = textBox1.Controls.IndexOf(bt);
        textBox1.Controls.Remove(bt);
        var lines = textBox1.Text.Replace("\r\n", "\n").Split('\n').ToList();
        lines.RemoveAt(btId);
        textBox1.Text = string.Join("\r\n", lines);
    
        foreach (Button btn in textBox1.Controls)
        {
            //var Id = int.Parse(btn.Name.Replace("btn", "")); // the last edit
            var Id = (int)btn.Tag;  // the last edit
    
            if (Id > btId)
            {
                var b = textBox1.Controls.Find(btn.Name, false)[0];
                var loc = btn.Location;
                b.Location = new Point(loc.X, loc.Y - BtnY);
            }
        }
        ButtonCount--;
    }
    

    【讨论】:

    • @L_J and Hiren Patel,感谢您提供进一步的解决方案。我仍然有文本在错误位置删除的问题。每个清除按钮都应删除同一行上的文本。另一个问题是删除时产生的空行。他们应该被推迟,这是所有的线路。
    • @JaDoLo 我编辑了代码。现在它应该像你描述的那样工作了。
    • 在没有看到代码的情况下很难说什么可以解决。我怀疑的一件事可能是从btn.Name 中提取的按钮的id。如果您更改了btn.Name,您也应该在此处更改var Id = int.Parse(btn.Name.Replace("btn", ""));。所以,为了避免这种情况,我稍微编辑了代码并将id保存到控件的Tag属性中。
    • 对我来说,附加的代码可以正常工作。我唯一需要更改的是private int Btn2Y = 13; 而不是18。 @JaDoLo 你现在的确切问题是什么?
    猜你喜欢
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    相关资源
    最近更新 更多