Search code examples
c#wpfmvvmdata-bindingbinding

C# WPF DataGrid is not updated when binded to the DataTable programatically


DataGrid is not updated when ItemsSource bound programmatically to the DataTable.

I'm building a user control that can change its inner content by the condition (via MVVM).
Xaml example:

<Window ...>
    <grid x:Name="mainGrid" />
</Window>

Code-behind:

public partial class MainWindow : Window
{
    public MainViewModel mvm { get; set; } = new MainViewModel();

    public MainWindow()
    {
        InitializeComponent();

        this.DataContext = mvm;

        var dataGrid = new DataGrid()
        {
            Width = 400,
            Height = 400,
            AutoGenerateColumns = true,
            IsReadOnly = true,
        };

        var binding = new Binding("DefaultView")
        {
            Source = mvm.TableSource,
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
        };

        BindingOperations.SetBinding(dataGrid, DataGrid.ItemsSourceProperty, binding);

        mainGrid.Children.Add(dataGrid);
    }

    private void button_Click_1(object sender, RoutedEventArgs e)
    {
        mvm.TableSource.Columns.Add("test" + new Random().Next());
        mvm.TableSource.Rows.Add("test" + new Random().Next());
        mvm.Refresh(); //force update
    }
}

MainViewModel code:

public class MainViewModel:ModelBase // ModelBase implements INotifyPropertyChanged
{
    public DataTable TableSource {get;set;} = new DataTable()

    public void Refresh()
    {
        var temp = TableSource;
        TableSource = null;
        OnPropertyChanged("TableSource");
        TableSource = temp;
        OnPropertyChanged("TableSource");
    }
}

I expect to see the contents of the DataTable when it bound programmatically to the DataGrid (only empty rows are added in this case), but it only works properly when it bound via XAML. Any ideas what I could probably miss?


Solution

  • It's not clean how to imitate the same functionality in code, so I added a workaround where the columns are added before the actual binding.