Click here to Skip to main content
15,890,123 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
//Hi, I've been working on this problem for more than a week and now I think I need help here.
//My goal: bind DataTable to DataGrid in MVVM.
//Here is the question:

//in MainWindow.xaml, the code is :
<Grid>
  <DataGrid x:Name="dg" ItemsSource = "{Binding dtSrc}"/>
  <Button x:Name="loaddata" Command="{Binding File_OpenCommand}"/>
</Grid>

//in MainWindow.xaml.cs
public partial class MainWindow : Window
{
  public MainWindow()
  {
     this.DataContex = new MainWindowViewModel;
  }
}

//in MainWindowViewModel.cs
public class MainWindowViewModel
{
  public MainWindowViewModel()
  {
    File_OpenCommand = new DelegateCommand(new Action<object>(File_Open));
  }
  
  public DataTable dtSrc {get;set;}
  public DelegateCommand File_OpenCommand;
  public void File_Open(object obj)
  {
      // here is the problem:
      //dtSrc has data, but DataGrid refuse to refresh and show them.
      dtSrc = LoadData();
  }
}

//in DelegateCommand.cs
public class DelegateCommand : ICommand
{
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    public DelegateCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}


What I have tried:

I'm a rookie in WPF and Googled many demos and samples, still, I'm stuck here.
Posted
Updated 6-Mar-17 14:52pm
v3
Comments
[no name] 6-Mar-17 20:36pm    
You need to implement INotifyPropertyChanged

1 solution

The DataTable class pre-dates WPF and was designed for WinForms applications. WPF & WinForms use two very different Binding systems.

To demonstrate this, if you bind a List class to a WPF ItemsContainer control like <codeDataGrid, any changes to the collection will not be reflected. This is due to the <code>INotifyCollectionChanged and INotifyPropertyChanged not being implemented. You can see this when you look at the DataTable[^] class:
C#
[SerializableAttribute]
public class DataTable : MarshalByValueComponent, IListSource, 
	ISupportInitializeNotification, ISupportInitialize, ISerializable, 
	IXmlSerializable
WPF has a special collection class called ObservableCollection<T>. Looking at ObservableCollection<t>[^] class you can see the two interfaces for binding are implemented:
C#
[SerializableAttribute]
public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, 
	INotifyPropertyChanged
You might be able to exten the DataTable class to capture key events and reflect the row changes, however each cell will also require the INotifyPropertyChanged interface implemented as well. It would be far simplier to modify your code to work with the ObservableCollection<T> and data model classes (with INotifyPropertyChanged implemented).

If you want to learn more about how the WPF binding system works, Pete O'Hanlon has a great multipart series that he is doing at the moment: Bare Metal MVVM - Where The Code Meets The Road - Part 1[^]
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900