如何每 1 分钟刷新一次由 DataProvider 填充的 DataGrid

How to refresh a DataGrid that has been populated by a DataProvider every 1min

我有以下 xaml,如您所见,DataGrid 正在通过 DataProvider 填充。

<Window x:Class="MobileDeviceAuthenticator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MobileDeviceAuthenticator"
        Title="Device Authorization" Height="381" Width="879" AllowDrop="True">
    <Window.Resources>
        <!-- create an instance of our DataProvider class -->
        <ObjectDataProvider x:Key="MobileManagerDataProvider" ObjectType="{x:Type local:MobileManagerDataProvider}"/>
        <!-- define the method which is invoked to obtain our data -->
        <ObjectDataProvider x:Key="MOBILE_MANAGER" ObjectInstance="{StaticResource MobileManagerDataProvider}" MethodName="GetDevices"/>
        <!-- create an instance of our DataProvider class -->
        <ObjectDataProvider x:Key="MobileRequestDataProvider" ObjectType="{x:Type local:MobileRequestDataProvider}"/>
        <!-- define the method which is invoked to obtain our data -->
        <ObjectDataProvider x:Key="MOBILE_REQUESTS" ObjectInstance="{StaticResource MobileRequestDataProvider}" MethodName="GetDevices"/>
    </Window.Resources>
    <Grid Name="GridContainer" >
        <Grid>
            <DataGrid Name="dgAuthorization" 
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch" 
                      DataContext="{Binding Source={StaticResource MOBILE_MANAGER}}" 
                      ItemsSource="{Binding}" 
                      AutoGenerateColumns="False" >
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Path=DESCRIPTION}" Header="Description" />
                    <DataGridTextColumn Binding="{Binding Path=DEVICE_TYPE}" Header="Device Type" IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding Path=DEVICE_ID}" Header="Device ID" IsReadOnly="True" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
        <Grid>
            <DataGrid Name="dgRequest" 
                      SelectionMode="Single" 
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch"
                      DataContext="{Binding Source={StaticResource MOBILE_REQUESTS}}"
                      ItemsSource="{Binding}"  
                      AutoGenerateColumns="False" >
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Path=DESCRIPTION}" Header="Description" />
                    <DataGridTextColumn Binding="{Binding Path=DEVICE_TYPE}" Header="Device Type" IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding Path=DEVICE_ID}" Header="Device ID" IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding Path=REQUEST_DATE}" Header="Request Date" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
</Window>

这里是 DataProvider class 代码

public class MobileManagerDataProvider
{
    private MobileManagerDataSetTableAdapters.MOBILE_MANAGERTableAdapter mmAdapter;
    private MobileManagerDataSet mmDataSet;

    public MobileManagerDataProvider()
    {
        mmDataSet = new MobileManagerDataSet();
        mmAdapter = new MobileManagerDataSetTableAdapters.MOBILE_MANAGERTableAdapter();
        mmAdapter.Fill(mmDataSet.MOBILE_MANAGER);

        mmDataSet.MOBILE_MANAGER.MOBILE_MANAGERRowChanged += new MobileManagerDataSet.MOBILE_MANAGERRowChangeEventHandler(AuthenticationRowModified);
        mmDataSet.MOBILE_MANAGER.MOBILE_MANAGERRowDeleted += new MobileManagerDataSet.MOBILE_MANAGERRowChangeEventHandler(AuthenticationRowModified);
    }

    public DataView GetDevices()
    {
        return mmDataSet.MOBILE_MANAGER.DefaultView;
    }

    void AuthenticationRowModified(object sender, MobileManagerDataSet.MOBILE_MANAGERRowChangeEvent e)
    {
        mmAdapter.Update(mmDataSet.MOBILE_MANAGER);
    }
}

在代码隐藏中,我想设置一个 Timer 每分钟刷新一次 DataGrids

Timer 很容易,但是我无法刷新数据。我已经尝试了以下一些陈述。

ObjectDataProvider dataProvider = this.TryFindResource("MobileManagerDataProvider") as ObjectDataProvider;
dataProvider.Refresh();

dgAuthorization.Items.Refresh();

CollectionViewSource.GetDefaultView(dgAuthorization.ItemsSource).Refresh();

没有用,我该如何实现?

这是一个完整的工作示例,每次你 select 一个项目(两次不同的项目)它都会添加一个新的随机值作为新行DataGrid

我已经用一个示例将新数据绑定到 DataGrid 每次你 select 其中的一个项目时,你可以扩展那个案例,所以每次你的集合改变时,它都会自动反映在您的 DataGrid 中,因此只要您的数据发生变化,您只需传递给 GridData 属性 它们就会在视图中更新

MainWindow.xaml

<Window x:Class="BindingDataGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingDataGrid"
        Title="MainWindow" Height="350" Width="525">

        <Window.DataContext>
            <local:MainViewModel />
        </Window.DataContext>
    <Grid>
        <DataGrid  ColumnWidth="*" 
                    IsReadOnly="True"
                    AutoGenerateColumns="False"
                    SelectionMode="Single" 
                    HorizontalContentAlignment="Center" 
                    ItemsSource="{Binding GridData}"
                    SelectedItem="{Binding SelectedData, UpdateSourceTrigger=PropertyChanged}"
                    CanUserResizeRows="False"
                    ScrollViewer.CanContentScroll="True"
                    ScrollViewer.VerticalScrollBarVisibility="Auto"
                    ScrollViewer.HorizontalScrollBarVisibility="Auto">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Column 01" Binding="{Binding Column1}"   Width="*"/>
                <DataGridTextColumn Header="Column 02" Binding="{Binding Column2}"   Width="*"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

MainWindow.xaml.cs 这里什么都没有,只是删除未使用的引用

using System.Windows;

namespace BindingDataGrid  //`BindingDataGrid` is my namespace
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

您需要的所有参考资料 在您的 MainViewModel

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;

MainViewModel

public class MainViewModel: INotifyPropertyChanged
{
    Random _rnd = new Random();
    private MyGridData _selectedData;
    private ObservableCollection<MyGridData> _gridData;
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public MainViewModel()
    {
        var newData = new List<MyGridData>
        {
            new MyGridData { Column1 = "AAAAAA 01", Column2 = "aaaaaaaa 02" },
            new MyGridData { Column1 = "BBBBBB 01", Column2 = "bbbbbbbb 02" },
            new MyGridData { Column1 = "CCCCCC 01", Column2 = "cccccccc 02" },
        };
        GridData = new ObservableCollection<MyGridData>(newData);
    }

    public MyGridData SelectedData
    {
        get { return _selectedData; }
        set
        {
            if (value == _selectedData) //if same item selected
                return;
            _selectedData = value;
            OnPropertyChanged();

            DoSomethingWhenValueChanged(); // Will add a new line
        }
    }
    public ObservableCollection<MyGridData> GridData
    {
        get { return _gridData; }
        set
        {
            if (value == _gridData)
                return;
            _gridData = value;
            OnPropertyChanged();
        }
    }

    private void DoSomethingWhenValueChanged()
    {
        var newData = GridData.ToList();
        newData.Add(new MyGridData { Column1 = (_rnd.Next(100)).ToString(), Column2 = (_rnd.Next(1000)).ToString() }); //Add new random item

        GridData = new ObservableCollection<MyGridData>(newData);  //update your DataGrid
    }
}

public class MyGridData
{
    public string Column1 { get; set; }
    public string Column2 { get; set; }
}