0

I have 2 forms. First form contains the datagridview and on the second form the users can change a single value in the datagridview in first form. The problem is if the user changes a value, the same value in other cells are changed too.

Ex) Before:

A B B C D

B B C D E

After(If I would try to change only one B after A to Z, it will change all Bs):

A Z Z C D

Z Z C D E

Form 1:

private void callForm2(object sender, EventArgs e)
{
    Form2 f2 = new Form2();
    f2.Show();
    f2.Text = this.dataGridView1.CurrentCell.Value.ToString();
}

Form 2:

private void button1_Click(object sender, EventArgs e)
{
    string edit = File.ReadAllText(@"C:\Master.txt");
    edit = edit.Replace(Text, textBox1.Text); //first Text = old value, textBox1 = new value
    File.WriteAllText(@"C:\Master.txt", edit);
    string message = "Item is modified on the list!";
    string caption = "Success";
    MessageBoxButtons button = MessageBoxButtons.OK;
    MessageBoxIcon icon = MessageBoxIcon.Information;
    MessageBox.Show(message, caption, button, icon);
    this.Close();
    //Changes Successfully, but if the cell value is same it changes all the same values
}

The Form 1 gets the data from a text file

private void button1_Click(object sender, EventArgs e)  //Add txt to program
{
    if (File.Exists(@"C:\Master.txt"))    //Look fot txt
    {
        using (StreamReader master = File.OpenText(@"C:\Master.txt")) //txt to table
        {
            int row = 0;
            string s = String.Empty;
            while ((s = master.ReadLine()) != null)
            {
                string[] columns = s.Split(',');
                dataGridView1.Rows.Add();
                for (int i = 0; i < columns.Length; i++)
                {
                    dataGridView1[i, row].Value = columns[i];
                }
                row++;
            }
        }
    }
    else
    {
        string message = "Program was not able to find the text file.";
        string caption = "Failed";
        MessageBoxButtons button = MessageBoxButtons.OK;
        MessageBoxIcon icon = MessageBoxIcon.Warning;
        MessageBox.Show(message,caption,button,icon);
    }
}
user2349228
  • 19
  • 1
  • 6
  • What is the data in the DataGridView? How do you get it and add to the DGV? How and when is it updated? – Eugene Podskal Aug 17 '14 at 17:43
  • The DGV is getting the data from a text file. In Form 2, there is a textbox. When the button1 is clicked, it changes the selected cell and write it in the text file – user2349228 Aug 17 '14 at 17:49
  • The source of the problem is obvious - Replace replaces every occurence of old substring that is being reflected in the DGV. So the question now is how do you read values from the file and put them into the DGV? – Eugene Podskal Aug 17 '14 at 17:51
  • I am using Streamreader to read the values in Form 1. Then, in Form 2, I am just using WriteAllText to write the changed value to the text file. Is there any way to replace one single cell, not all the substring? – user2349228 Aug 17 '14 at 18:13
  • How do you parse the file and put its contents to the DataGridView? Or is there some more intricate relationship between file and DGV? – Eugene Podskal Aug 17 '14 at 18:14
  • I have created a button that calls out the text file. I will upload it on my question. – user2349228 Aug 17 '14 at 18:16

2 Answers2

0

By executing edit = edit.Replace(Text, textBox1.Text); you are replacing all occurence of the character/string...
try something like this

var regex = new Regex(Regex.Escape("A"));
var newText = regex.Replace(Text, textBox1.text, 1);

Hope this helped

Coder
  • 886
  • 1
  • 12
  • 28
0

PROBLEM:

You use String.Replace method on the entire content of the file when you actual goal is to change one specific comma-separated value on specific row that corresponds to DataGridView cell.

SOLUTION:

To modify only the desired string record you have to know in which row and column(both in DGV and text file) it exists. You get row and column from this.dataGridView1.CurrentCell corresponding RowIndex and ColumnIndex properties.

You can give them to the 2nd form in the same manner you give the Text, just do not forget to create appropriate properties:

f2.Text = this.dataGridView1.CurrentCell.Value.ToString();
f2.RowIndex = this.dataGridView1.CurrentCell.RowIndex; 
f2.ColumnIndex = this.dataGridView1.CurrentCell.ColumnIndex;

public class Form2
{
    public Int32 RowIndex {get; set;}
    // ...


}

So, now you know at what position the change should occur. And while it is possible to manually walk through the file and change only the needed value for simplicity I'd recommend you to use a bit different approach:

Not just loading the data into the datagridview, but also storing them in corresponding jagged array:

public class MyForm
{

// To store your currently loaded values
public List<String[]> Values{get; set;}

// Load button
...
    using (StreamReader master = File.OpenText(@"C:\Master.txt")) //txt to table
    {
        this.values = new List<String[]>();

        int row = 0;
        string s = String.Empty;
        while ((s = master.ReadLine()) != null)
        {
            string[] columns = s.Split(',');
            // Save the line
            values.Add(columns);

            dataGridView1.Rows.Add();
            for (int i = 0; i < columns.Length; i++)
            {
                dataGridView1[i, row].Value = columns[i];
            }
            row++;
        }
    }

Then you give this values list to the second form before using it:

...

f2.Values = this.values;

And on form2 button1_Click:

private void button1_Click(object sender, EventArgs e)
{
    this.Values[this.RowIndex][this.ColumnIndex] = textBox1.Text;

    string edit = String.Join(
        Environment.NewLine, 
        this.Values.
            Select(array => 
                String.Join(",", array)).
            ToArray());

    File.WriteAllText(@"C:\Master.txt", edit);
    // ...        
}

It is not the most effective or nice solution but it should work.

P.S.: If you want to improve your File IO understanding you could try to change the value inside the file without storing and full rewriting of its contents.

Eugene Podskal
  • 10,270
  • 5
  • 31
  • 53
  • Thank you for your answer. I assumed that f2.ColumnIndex = this.dataGridView1.CurrentCell.RowIndex; should be f2.ColumnIndex = this.dataGridView1.CurrentCell.ColumnIndex; Also, add public List Values { get; set; } in form 2. However, when I click the button it deletes the entire row and only show System.Char[] – user2349228 Aug 17 '14 at 23:14
  • @user2349228 Fixed minor issues, should work. Sorry for not reacting, just missed the comment notification. – Eugene Podskal Aug 22 '14 at 19:53
  • Thank you so much! The issue is fixed!! – user2349228 Aug 24 '14 at 02:27