none
How can I force a textBox to push back changed data to its DataSource by code ? RRS feed

  • Question

  • Hello. My DataTable has a lot of columns and one to any number of rows. Some of the columns are placed on a DataGridView. The rest of them are represented by textBoxes. I provide a dialog to let uses change any column to uppercase.

    Let say table1 has 5 rows, It's on the first row. textBox1.Text = "". Foucs is on textBox1. The user type "abc" on textBox1.

    The user hits a button to bring up a dialog to do the uppercase()

    After the user hit "confirm" button, columns related to textBox1 are changed to uppercase. But textBox1.Text still show "abc" until the user uses the mouse to click on the second row and click on the first row again do textBox1.Text become "ABC"

    I tried to cope with the problem by calling textBox20.Focus(), SendKeys.Send("{TAB}") to move focus from textBox1 trying to force the updating. These do move focus from textBox1. But its DataSource still doesn't get updated . Clicking another textBox forces textBox1 to send Changed text to its DataSource. Using code to move focus doesn't have the same effect. And textBoxes do not have EndEdit() as DataGridViews do. Finally I resorted to bindingSouce1.ResetBindings(false). It worked. I don't like to call ResetBindings(false) too often because it focus DataGridView to move its current cell to the first column.

    Are there other methods I can force a textBox to update its changed text to its DataSource by code ? Thanks.

    Monday, February 10, 2020 9:24 AM

Answers

  • Hello,

    If this was a list then implementing INotifyPropertyChanged with a BindingList would solve this issue.

    Have you tried using ResetCurrentItem which only does a reset of the current row. In the following example pressing a button changes the DataColumn PartName to upper case then resets binding only for the current row. So changing the value in the DataGridView or TextBox then pressing the button without leaving the row works.

    public partial class Form1 : Form
    {
        private readonly BindingSource _bindingSource = new BindingSource();
        public Form1()
        {
            InitializeComponent();
            Shown += Form1_Shown;
        }
    
        private void Form1_Shown(object sender, EventArgs e)
        {
    
            _bindingSource.DataSource = MockedDataOperations.LoaDataTable();
            dataGridView1.DataSource = _bindingSource;
    
            PartNameTextBox.DataBindings.Add("Text", _bindingSource, "PartName", 
                true, 
                DataSourceUpdateMode.OnValidation);
    
            QuantityTextBox.DataBindings.Add("Text", _bindingSource, "Quantity");
            CostTextBox.DataBindings.Add("Text", _bindingSource, "Cost");
    
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            var currentRow = ((DataRowView) _bindingSource.Current).Row;
    
            currentRow.SetField("PartName", currentRow.Field<string>("PartName").ToUpper());
            _bindingSource.ResetCurrentItem();
    
        }
    }


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by AlanChong Tuesday, February 11, 2020 12:36 AM
    Monday, February 10, 2020 10:53 AM
    Moderator

All replies

  • Hello,

    If this was a list then implementing INotifyPropertyChanged with a BindingList would solve this issue.

    Have you tried using ResetCurrentItem which only does a reset of the current row. In the following example pressing a button changes the DataColumn PartName to upper case then resets binding only for the current row. So changing the value in the DataGridView or TextBox then pressing the button without leaving the row works.

    public partial class Form1 : Form
    {
        private readonly BindingSource _bindingSource = new BindingSource();
        public Form1()
        {
            InitializeComponent();
            Shown += Form1_Shown;
        }
    
        private void Form1_Shown(object sender, EventArgs e)
        {
    
            _bindingSource.DataSource = MockedDataOperations.LoaDataTable();
            dataGridView1.DataSource = _bindingSource;
    
            PartNameTextBox.DataBindings.Add("Text", _bindingSource, "PartName", 
                true, 
                DataSourceUpdateMode.OnValidation);
    
            QuantityTextBox.DataBindings.Add("Text", _bindingSource, "Quantity");
            CostTextBox.DataBindings.Add("Text", _bindingSource, "Cost");
    
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            var currentRow = ((DataRowView) _bindingSource.Current).Row;
    
            currentRow.SetField("PartName", currentRow.Field<string>("PartName").ToUpper());
            _bindingSource.ResetCurrentItem();
    
        }
    }


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by AlanChong Tuesday, February 11, 2020 12:36 AM
    Monday, February 10, 2020 10:53 AM
    Moderator
  • Hi Karen. Thanks. I think ResetCurrentItem() is a good choice. Calling ResetBindings() confuses the users because it always bring the the current cell to the first row and first column.
    Tuesday, February 11, 2020 12:39 AM