Reputation: 1712
I have certain datagrid which I need to "refresh" every... lets say 1 min.
Is a timer the best option?
public PageMain()
{
InitializeComponent();
DataGridFill();
InitTimer();
}
private void InitTimer()
{
disTimer = new Timer(new TimeSpan(0, 1, 0).TotalMilliseconds);
disTimer.Elapsed += disTimer_Elapsed;
disTimer.Start();
}
void disTimer_Elapsed(object sender, ElapsedEventArgs e)
{
DataGridFill();
}
private void DataGridFill()
{
var items = GetItems(1);
ICollectionView itemsView =
CollectionViewSource.GetDefaultView(items);
itemsView.GroupDescriptions.Add(new PropertyGroupDescription("MyCustomGroup"));
// Set the view as the DataContext for the DataGrid
AmbientesDataGrid.DataContext = itemsView;
}
Is there a less "dirty" solution?
Upvotes: 1
Views: 1430
Reputation: 54801
My prefered approach:
public sealed class ViewModel
{
/// <summary>
/// As this is readonly, the list property cannot change, just it's content so
/// I don't need to send notify messages.
/// </summary>
private readonly ObservableCollection<T> _list = new ObservableCollection<T>();
/// <summary>
/// Bind to me.
/// I publish as IEnumerable<T>, no need to show your inner workings.
/// </summary>
public IEnumerable<T> List { get { return _list; } }
/// <summary>
/// Add items. Call from a despatch timer if you wish.
/// </summary>
/// <param name="newItems"></param>
public void AddItems(IEnumerable<T> newItems)
{
foreach(var item in newItems)
{
_list.Add(item);
}
}
/// <summary>
/// Sets the list of items. Call from a despatch timer if you wish.
/// </summary>
/// <param name="newItems"></param>
public void SetItems(IEnumerable<T> newItems)
{
_list.Clear();
AddItems(newItems);
}
}
Don't like lack of decent AddRange
/ReplaceRange
in ObservableCollection<T>
? Me neither, but here is an descendant to ObservableCollection<T>
to add a message efficient AddRange
, plus unit tests:
Upvotes: 1
Reputation: 132588
The best way to "Refresh" a DataGrid
is to bind it to a collection of items, and update the source collection of items every X minutes.
<DataGrid ItemsSource="{Binding MyCollection}" ... />
This way you never have to reference the DataGrid
itself, so your UI logic and application logic stay separated, and if your refresh takes a while you can run it on a background thread without locking up your UI.
Because WPF can't update objects created on one thread from another thread, you may want to get your data and store in a temporary collection on a background thread, then update your bound collection on the main UI thread.
For the timing bit, use a Timer
or possibly a DispatcherTimer
if needed.
var timer = new System.Windows.Threading.DispatcherTimer();
timer.Tick += Timer_Tick;
timer.Interval = new TimeSpan(0,1,0);
timer.Start();
private void Timer_Tick(object sender, EventArgs e)
{
MyCollection = GetUpdatedCollectionData();
}
Upvotes: 2