简体   繁体   English

WPF Silverlight Datagrid实时刷新? 计时器?

[英]WPF Silverlight Datagrid in real time, refresh? Timer?

I have certain datagrid which I need to "refresh" every... lets say 1 min. 我有一些数据网格,我需要“刷新”每个...让我们说1分钟。

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? 是否有一个不那么“脏”的解决方案?

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的最佳方法是将其绑定到项目集合,并每隔X分钟更新一次项目的源集合。

<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. 这样您就不必引用DataGrid本身,因此您的UI逻辑和应用程序逻辑保持分离,如果您的刷新需要一段时间,您可以在后台线程上运行它而不会锁定您的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. 因为WPF无法更新从另一个线程在一个线程上创建的对象,所以您可能希望获取数据并将其存储在后台线程上的临时集合中,然后在主UI线程上更新绑定集合。

For the timing bit, use a Timer or possibly a DispatcherTimer if needed. 对于时序位,如果需要,请使用TimerDispatcherTimer

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();
}

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> ? 不喜欢在ObservableCollection<T>缺少像样的AddRange / ReplaceRange Me neither, but here is an descendant to ObservableCollection<T> to add a message efficient AddRange , plus unit tests: 我也不是,但这里是ObservableCollection<T>的后代,以添加消息高效的AddRange ,以及单元测试:

ObservableCollection Doesn't support AddRange method, so I get notified for each item added, besides what about INotifyCollectionChanging? ObservableCollection不支持AddRange方法,因此除了INotifyCollectionChanging外,我还会收到添加的每个项目的通知?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM