louisejackie Ответов: 1

Отказать в элементе управления DataGrid для обновления и отображения данных, где данные типа таблицы данных в WPF с использованием MVVM


// Привет, я работаю над этой проблемой уже больше недели, и теперь я думаю, что мне нужна помощь здесь.
//Моя цель: привязать DataTable к DataGrid в MVVM.
//Вот в чем вопрос:

//в MainWindow.xaml код выглядит следующим образом :
<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; }
    }
}


Что я уже пробовал:

Я новичок в WPF и погуглил много демо-версий и сэмплов, но все равно застрял здесь.

[no name]

Вам нужно реализовать INotifyPropertyChanged

1 Ответов

Рейтинг:
0

Graeme_Grant

То DataTable класс предшествует WPF и был разработан для приложений WinForms. В WPF &амп; приложения WinForms использовать две очень разные системы обязательного.

Чтобы продемонстрировать это, если вы свяжете List класс к WPF ItemsContainer контролируйте как < codeDataGrid, любые изменения в коллекции не будут отражены. Это связано с тем, что <code>INotifyCollectionChanged и INotifyPropertyChanged не реализуется. Вы можете увидеть это, когда посмотрите на объект DataTable[^] класс:

[SerializableAttribute]
public class DataTable : MarshalByValueComponent, IListSource, 
	ISupportInitializeNotification, ISupportInitialize, ISerializable, 
	IXmlSerializable
WPF имеет специальный класс коллекции под названием ObservableCollection<T>... Глядя на ObservableCollection< t>[^] класс вы можете видеть, что реализованы два интерфейса для привязки:
[SerializableAttribute]
public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, 
	INotifyPropertyChanged
Возможно, вы сможете расширить DataTable класс для захвата ключевых событий и отражения изменений строк, однако для каждой ячейки также потребуется INotifyPropertyChanged интерфейс также реализован. Было бы гораздо проще изменить свой код для работы с ObservableCollection<T> и классы моделей данных (с INotifyPropertyChanged реализованный).

Если вы хотите узнать больше о том, как работает система привязки WPF, у Пита О'Хэнлона есть отличная многосерийная серия, которую он делает в данный момент: Голый металл MVVM - где код встречается с дорогой-Часть 1[^]