Как обновить на UI таблицу
Я использую WPF в качестве UI для Windows приложения. Мне нужно отобразить на нем таблицу из SQL Server. Начал следующим образом. Использую Prism
class MainVM : BindableBase
{
public MainVM()
{
currentTasks TaskList = new ObservableCollection<Task>(currentTasks.Tasks);
}
public ObservableCollection<Task> TaskList { get; private set; }
}
public class CurrentTasks : BindableBase
{
public CurrentTasks()
{
RefreshTasks();
timer = new Timer(5000);
timer.Elapsed += Timer_Elapsed;
timer.Enabled = true;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
RefreshTasks();
}
private void RefreshTasks()
{
using (var db = new MyDatabase())
{
var query = from b in db.Tasks select b;
foreach (Task task in query)
{
tasks.Add(task);
}
Tasks = new ReadOnlyObservableCollection<Task>(tasks);
}
}
private ObservableCollection<Task> tasks = new ObservableCollection<Task>();
public ReadOnlyObservableCollection<Task> Tasks { get; private set; }
private Timer timer;
}
По таймеру я собираюсь обновлять таблицу. Как её обновить на UI? Может какие-нибудь подходы к таким задачам подскажите :)
Ответы (1 шт):
1) MainVM сделать как DataContext у окна
MainWindow.xaml
<Window.DataContext>
<local:MainVM/>
</Window.DataContext>
При этом из кода конструктор MainVM вызывать не нужно, а если потребуется обратиться к существующему экземпляру из класса MainWindow, это можно сделать так:
MainVM vm = DataContext as MainVM;
2) Далее создать класс с данными, в которых будут храниться ячейки таблицы. К сожалению, я не работал с Entity или Prizm, поэтому вам решать, как у вас будет выглядеть класс с данными. Важно, что если вы хотите при любых програмных изменениях в данных, видеть их на экране, то он должен реализовывать INotifyPropertyChanged интерфейс, или наследовать BindableBase, как в вашем случае с использованием MVVM Light. Я сам MVVM Light не использую, поэтому этот ответ создан без учета его преимуществ.
К примеру, пусть данные содержат одно свойство строкового типа, тогда получится что-то вот такое:
DataItem.cs
public class DataItem : INotifyPropertyChanged
{
private string _myValue;
public string MyValue
{
get => _myValue;
set { _myValue = value; OnPropertyChanged(nameof(MyValue)); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
3) В MainVM нужно добавить коллекцию с этим типом данных.
MainVM.cs
public class MainVM : INotifyPropertyChanged
{
private ObservableCollection<DataItem> _gridData;
public ObservableCollection<DataItem> GridData;
{
get => _gridData;
set
{
_gridData = value;
OnPropertyChanged(nameof(GridData));
}
}
public MainVM()
{
// здесь можно проинициализировать коллекцию с данными, если требуется
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
4) Добавить DataGrid в UI.
MainWindow.xaml
<DataGrid ItemsSource="{Binding GridItems}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextBoxColumn Width="*" Binding="{Binding MyValue}" />
</DataGrid.Columns>
</DataGrid>
Так как изменение ItemsSource автоматически меняет DataContext у таблицы, то {Binding MyValue} уже идет относительно коллекции, а не относительно окна