How to use bindingList and BindingSource at multiple places

Rajkumar Rao 100 Reputation points
2023-12-02T17:07:39.0266667+00:00

Hi ,

I have a BindingList and a BindingSource defined in a separate class . besides that i also have a custom datagridview , a datagridview on a form named form 1 , and two textbox on the form named form 2 . one of these textbox is used to add values to the BindingList and the other Textbox is used to update .

I am facing two problems and request expertise

  1. Although i have coded but I am looking for a Best way by which this same Binding list is available to all three forms . so that whenever any form update a item or add a item in BindingList , it should reflect in all the forms .
  2. I don't know how to code the Binding logics for both the update and add buttons in form2 .

DataRepository.cs

  namespace Rajr
{
    public static class DataRepository
    {
        private static BindingList<Item> dataList;
        public static BindingList<Item> DataList
        {
            get { return dataList; }
            set
            {
                if (dataList != null)
                    dataList.ListChanged -= DataList_ListChanged;

                dataList = value;

                if (dataList != null)
                    dataList.ListChanged += DataList_ListChanged;
            }
        }

        public static BindingSource DataSource { get; set; }

        static DataRepository()
        {
            DataList = new BindingList<Item>();
            DataSource = new BindingSource(DataList, null);
        }

        private static void DataList_ListChanged(object sender, ListChangedEventArgs e)
        {
            DataSource.ResetBindings(false);
        }
    }

    public class Item : INotifyPropertyChanged
    {
        private string itemName;
        public string ItemName
        {
            get { return itemName; }
            set
            {
                if (itemName != value)
                {
                    itemName = value;
                    OnPropertyChanged();
                }
            }
        }

        private int quantity;
        public int Quantity
        {
            get { return quantity; }
            set
            {
                if (quantity != value)
                {
                    quantity = value;
                    OnPropertyChanged();
                }
            }
        }

        private string measuringUnits;
        public string MeasuringUnits
        {
            get { return measuringUnits; }
            set
            {
                if (measuringUnits != value)
                {
                    measuringUnits = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}


CustomDatagridview.cs

  public partial class CustomDatagridview : DataGridView
    {
        private bool inGotoNextControl = false;
        public CustomDatagridview()
        {
            this.AllowUserToAddRows = false;
            this.ColumnHeadersVisible = false;
            this.RowHeadersVisible = false;
            InitializeComponent();
            DataSource = DataRepository.DataSource;

        }

Form1.cs

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // add some data 
            DataRepository.DataList.Add(new Item { ItemName = "Cookies", Quantity = 10, MeasuringUnits = "Pcs" });
            DataRepository.DataList.Add(new Item { ItemName = "Bread", Quantity = 5, MeasuringUnits = "Box" });
            DataRepository.DataList.Add(new Item { ItemName = "Candy", Quantity = 2, MeasuringUnits = "Pcs" });
            dataGridView1.DataSource = DataRepository.DataSource;
        }  

        private void Form1_Load(object sender, EventArgs e)
        {
           
        }
    }


form2.cs

It has three textboxes each for updating and adding items in ItemName , Quantity and MeasuringUnits .

public partial class Form2 : Form
{
   

    public Form2()
    {
        InitializeComponent();

        
    }

    private void Add_Click(object sender, EventArgs e)
    {
        // Add in  the BindingList
       
    }


}
Developer technologies Windows Forms
Developer technologies C#
{count} votes

2 answers

Sort by: Most helpful
  1. gekka 12,206 Reputation points MVP Volunteer Moderator
    2023-12-03T05:52:30.94+00:00

    Add BindingSource in DataRepository to DataBindings of TextBox in Form2 .

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // add some data 
            DataRepository.DataList.Add(new Item { ItemName = "Cookies", Quantity = 10, MeasuringUnits = "Pcs" });
            DataRepository.DataList.Add(new Item { ItemName = "Bread", Quantity = 5, MeasuringUnits = "Box" });
            DataRepository.DataList.Add(new Item { ItemName = "Candy", Quantity = 2, MeasuringUnits = "Pcs" });
            dataGridView1.DataSource = DataRepository.DataSource;
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            if (Application.OpenForms.OfType<Form2>().FirstOrDefault() != null)
            {
                return;
            }
    
            var frm2 = new Form2();
            frm2.StartPosition = FormStartPosition.CenterParent;
            frm2.Show(this);
        }
    }
    
    public partial class Form2 : Form
    {
        private TextBox txbItemName;
        private TextBox txbQuantity;
        private TextBox txbMeasuringUnits;
        private Button btnAdd;
    
        public Form2()
        {
            //InitializeComponent();
    
            txbItemName = new TextBox();
            txbQuantity = new TextBox();
            txbMeasuringUnits = new TextBox();
            btnAdd = new Button() { Text = "Add New Item" };
    
            txbItemName.DataBindings.Add(new Binding(nameof(TextBox.Text), DataRepository.DataSource, nameof(Item.ItemName)));
            txbQuantity.DataBindings.Add(new Binding(nameof(TextBox.Text), DataRepository.DataSource, nameof(Item.Quantity)));
            txbMeasuringUnits.DataBindings.Add(new Binding(nameof(TextBox.Text), DataRepository.DataSource, nameof(Item.MeasuringUnits)));
    
            this.Controls.Add(txbItemName);
            this.Controls.Add(txbQuantity);
            this.Controls.Add(txbMeasuringUnits);
            this.Controls.Add(btnAdd);
    
            for (int i = 1; i < this.Controls.Count; i++)
            {
                this.Controls[i].Top = this.Controls[i - 1].Bottom + 5;
            }
    
            btnAdd.Click += Add_Click;
        }
    
        private void Add_Click(object sender, EventArgs e)
        {
    
            DataRepository.DataSource.Add(new Item());
            //DataRepository.DataSource.Add(new Item() { ItemName = "Empty", Quantity = 0, MeasuringUnits = "Pcs" });
    
            DataRepository.DataSource.MoveLast();
        }
    }
    

  2. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2023-12-03T12:11:11.7733333+00:00

    Consider a singleton to share data. The following works but can be optimized, I did just enough to show sharing data between forms.

    See the full source code here.

    public sealed class DataSource
    {
        private static readonly Lazy<DataSource> Lazy = 
            new(() => new DataSource());
    
        public static DataSource Instance => Lazy.Value;
    
        public readonly BindingSource BindingSource = new();
        public BindingList<Book> BindingList = new();
    
        private DataSource()
        {
            BindingList = new BindingList<Book>(DataOperations.Books());
            BindingSource.DataSource = BindingList;
        }
    }
    

    To set to the main form.

    private void OnShown(object sender, EventArgs e)
    {
        _bindingList = DataSource.Instance.BindingList;
        _bindingSource.DataSource = _bindingList;
        dataGridView1.DataSource = _bindingSource;
    }
    

    In a child form

    public partial class EditForm : Form
    {
        private readonly int _position;
    
        public EditForm()
        {
            InitializeComponent();
            Shown += EditFormShown;
        }
    
        public EditForm(int position)
        {
            InitializeComponent();
            Shown += EditFormShown;
            _position = position;
        }
    
        private void EditFormShown(object sender, EventArgs e)
        {
            TitleTextBox.DataBindings.Add(
                "Text",
                DataSource.Instance.BindingList[_position],
                "Title");
    
            PriceTextBox.DataBindings.Add(
                "Text",
                DataSource.Instance.BindingList[_position],
                "Price");
        }
    
        private void SaveButton_Click(object sender, EventArgs e)
        {
            DataSource.Instance.BindingSource.ResetCurrentItem();
            DialogResult = DialogResult.OK;
        }
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.