C# Как обновить BindingSource.DataSource DataTable при изменении структуры - PullRequest
0 голосов
/ 08 мая 2020

Как я могу сохранить BindingSource DataSource, если источником является DataTable и структура этой таблицы изменилась?

Я создаю список BindingSource объектов (boundSrcs), которые я использую для обновления пользовательского интерфейса WinForm при событии.

Прямо сейчас у меня есть два объекта, где boundSrcs[0].DataSource - это список, а boundSrcs[1].DataSource - это данные. Список инициализируется, привязан к boundSrcs[0] и остается той же длины. Когда список обновляется и я поднимаю свое событие, boundSrcs[0] обновляется - он работает.

Когда я пытаюсь обновить данные boundSrcs[1], это не работает. Структура таблицы изменяется после ее инициализации - есть ли способ сохранить ссылку DataSource при изменении структуры?

Код для создания создания BindingSources и повторной привязки по событию:

    private WebsiteViewModel DataControlObj = new WebsiteViewModel();
    private List<BindingSource> boundSrcs = new List<BindingSource>();

    public Form1()
    {
        InitializeComponent();

        DataControlObj.RebindSrcs += new WebsiteViewModel.BoundSrcUpdate(RebindSources);

        BindingSource comboSrc = new BindingSource();            
        comboSrc.DataSource = DataControlObj.numMeasureList;
        this.comboBox1.DataSource = comboSrc;
        boundSrcs.Add(comboSrc);

        BindingSource gridSrc = new BindingSource();
        gridSrc.DataSource = DataControlObj.TestData;
        this.dataGridView1.DataSource = gridSrc;
        boundSrcs.Add(gridSrc);
    }

    private void RebindSources()
    {
        foreach (BindingSource src in boundSrcs)
        {
            src.ResetBindings(true);
            Console.WriteLine("Is it the list " + (src.DataSource == DataControlObj.numMeasureList));
            Console.WriteLine("Is it the table " + (src.DataSource == DataControlObj.TestData)); // Always false once table structure changes
        }            
    }

Инициализация Код:

public List<int> numMeasureList = new List<int>() { 1, 2, 3 };
public DataTable TestData { get; private set; } = new DataTable();

Изменение таблицы данных:

    public bool CheckandSetTable(string filename, bool tf)
    {
        DataTable table = csvIO.GetDataTableFromCSVFile(filename, false);
        bool valid = CheckValidTestPattern(table);
        if (valid)
        {
            TestData = table.Copy();
            OnSrcUpdate(); // Raises event RebindSrcs
        }
        return valid;
    }

После поиска ответа в течение нескольких часов я рассмотрел еще несколько вопросов, которые близки к тому, что я Я спрашиваю о:

DataGridView не обновляется в C# при правильном источнике привязки

Refre sh DataGridView при обновлении источника данных

DataGridView DataSource не обновляется

Я благодарен за любую помощь в этом вопросе и прошу прощения, если на него ответили, но я не смог его найти

******** РЕДАКТИРОВАТЬ ********************

Я нашел способ обойти свою проблему.

После дальнейшего тестирования более простого случая оказалось, что моя проблема заключалась в DataTable.Copy метод, который является проблемой. Я также пробовал использовать DataTable.Clone, но обнаружил, что это не работает - эти методы не просто копируют схему и данные и каким-то образом удаляют привязку данных. Чтобы исправить свою проблему, я написал несколько методов, чтобы скопировать схему исходной таблицы данных, а затем скопировать фактическое ItemArray из каждой строки:

        public static void Main(string[] args)
    {
        DataTable dt1 = new DataTable();
        DataTable dt2 = new DataTable();
        DataTable dt3 = new DataTable();

        dt2 = dt1;
        dt3.Columns.Add("Name");
        dt3.Columns.Add("Email");
        dt3.Rows.Add("Mark", "markw@madeupemail.com");
        dt1 = dt3.Copy();
        Console.WriteLine(dt2 == dt1);

        dt1.Columns.Clear();
        dt1.Clear();
        dt2 = new DataTable();
        dt2 = dt1;
        dt1.Columns.Add("Name");
        dt1.Columns.Add("Email");
        dt1.Rows.Add("Mark", "markw@madeupemail.com");
        Console.WriteLine(dt2 == dt1);

        dt2 = new DataTable();
        dt2 = dt1;
        JustDataCopy(dt3, dt1);
        Console.WriteLine(dt2 == dt1);

    }

    public static void JustDataCopy(DataTable src, DataTable dest)
    {
        ImportStructure(src, dest);
        ImportData(src, dest);
    }

    public static void ImportStructure(DataTable src, DataTable dest) 
    {
        dest.Columns.Clear();
        dest.Clear();
        //foreach(DataColumn dc in dest.Columns) {dest.Columns.Remove(dc);}
        foreach(DataColumn dc in src.Columns) {dest.Columns.Add(dc.ColumnName, dc.DataType);}
    }

    public static void ImportData(DataTable src, DataTable dest)
    {
        foreach(DataRow dr in src.Rows) {dest.Rows.Add(dr.ItemArray);}
    }
...