Problem:
I'm looking to create a DataGrid
that updates automatically as new objects gets added into an ObservableCollection
. As a prototype, I've made a Timer
that adds new, unique objects into the ObservableCollection
. The class in question inherits from a custom ObservableObject
class that inherits from the INotifyPropertyChanged
interface. Using breakpoints, I can see that the ObservableCollection
updates, the ObservableObject
class gets called and sets the right values, but the DataGrid
never displays anything.
MainWindow.xaml:
<DataGrid Name="dg" ItemsSource="{Binding Path=DataColl, Mode=TwoWay}" >
</DataGrid>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public ObservableCollection<DataClass> DataColl = new ObservableCollection<DataClass>();
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Timer aTimer;
aTimer = new Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 5000;
aTimer.Enabled = true;
}
int index = 0;
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
DataColl.Add(new DataClass() { ID = index, time = string.Format("{0:HH:mm:ss tt}", DateTime.Now),source="AIS"});
index++;
}
}
DataClass.cs
public class DataClass : ObservableObject
{
private int _id;
public int ID
{
get
{
return _id;
}
set
{
SetProperty(ref _id, value);
}
}
public string time { get; set; }
public string source { get; set;}
}
ObservableObject.cs
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propName));
}
}
protected bool SetProperty<T>(ref T storage, T value,
[CallerMemberName] String propertyName = null)
{
if (Equals(storage, value)) return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
}
Any help is appreciated!
Change your observable collection declaration as
private ObservableCollection<DataClass> dataColl;
public ObservableCollection<DataClass> DataColl
{
get { return dataColl; }
set { dataColl = value; }
}
initialize the collection inside the constructor and change your timer event as
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
Dispatcher.Invoke(() =>
{
DataColl.Add(new DataClass() { ID = index, time = string.Format("{0:HH:mm:ss tt}", DateTime.Now), source = "AIS" });
index++;
});
}