2012-11-27 72 views
0

我有一个动态数据库,数据库中的数据将在一分钟内更新。现在,我在我的WPF项目中创建了一个数据网格,并且希望显示数据库中的所有数据。当我运行我的项目时,datagrid将只显示静态数据(项目运行前的数据)。我怎么能确保我的数据网格将保持更新本身后我运行它?顺便说一句,我使用LINQ SQL和C#为我的WPF项目。如何创建一个动态的WPF数据网格?

我的DataGrid的代码片段:

<DataGrid AutoGenerateColumns="False" Name="MyDataGrid" VerticalAlignment="Top" Width="185" > 
    <DataGrid.Columns> 
      <DataGridTextColumn Header="Date" Width="60" Binding="{Binding Date}" /> 
      <DataGridTextColumn Header="Time" Width="55" Binding="{Binding Time}"/> 
      <DataGridTextColumn Header="Id" Width="69" Binding="{Binding id}" /> 
    </DataGrid.Columns> 
</DataGrid> 

代码片段后面我的代码:

public MainWindow() 
{ 
     InitializeComponent(); 

     using (MyDummyDataContext db = new MyDummyDataContext()) 
     { 
      var query = from p in db.Ids 
         orderby p.Id descending 
         select new 
         { 
          Date = p.Date, 
          Time = p.Time, 
          id = p.Id 
         }; 
      MyDataGrid.ItemsSource = query; 
     } 
} 

回答

1

这里是我的2美分:

  1. 绑定您的DataGird的的ItemsSource到一个ObservableCollection 。
  2. 在加载的事件处理程序中初始化集合。
  3. 在计时器的回调中添加一个计时器,您可以从数据库刷新收集。注意:如果您使用.NET 4.5,则支持更新ObservableCollection窗体后台线程。否则,您需要手动处理线程同步。

这里是在后台数据更新的链接,可能是不完美贴合您的问题,但你可以得到一些想法:

Observable Collection Cross-Thread Change Notification

编辑:

我只是写了一个示例(为了简单起见,我使用DispatcherTimer更新UI线程中的集合。要更新后台线程中的数据,您需要使用System.Timers.Timer,并使用链接中的方法。):

App.xaml.cs:

using System.Windows; 

namespace DataGridTest 
{ 
/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     var vm = new MainWindowViewModel(); 
     var mainWindow = new MainWindow { DataContext = vm }; 
     mainWindow.Show(); 
    } 
} 
} 

MainWindow.xaml

<Window x:Class="DataGridTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <DataGrid AutoGenerateColumns="False" Name="MyDataGrid" VerticalAlignment="Top" Width="185" 
       ItemsSource="{Binding Persons}"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="Id" Width="60" Binding="{Binding Id}" /> 
      <DataGridTextColumn Header="Name" Width="55" Binding="{Binding Name}"/> 
     </DataGrid.Columns> 
    </DataGrid> 
</Grid> 

MainWindow.cs:

using System.Windows; 

namespace DataGridTest 
{ 
using System; 
using System.ComponentModel; 
using System.Windows.Threading; 

public class Person : INotifyPropertyChanged 
{ 
    private int _id; 

    private string _name; 

    public int Id 
    { 
     get 
     { 
      return _id; 
     } 

     set 
     { 
      if (this._id == value) 
       return; 

      this._id = value; 
      this.OnPropertyChanged("Id"); 
     } 
    } 
    public string Name 
    { 
     get 
     { 
      return _name; 
     } 

     set 
     { 
      if (this._name == value) 
       return; 

      this._name = value; 
      this.OnPropertyChanged("Name"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    private readonly DispatcherTimer _timer = new DispatcherTimer(); 

    public MainWindow() 
    { 
     InitializeComponent(); 

     _timer.Interval = TimeSpan.FromSeconds(1); 
     _timer.Tick += this._timer_Tick; 
     _timer.Start(); 
    } 

    private void _timer_Tick(object sender, EventArgs e) 
    { 
     var vm = this.DataContext as MainWindowViewModel; 
     if(vm != null) 
      vm.Refresh(); 
    } 
} 
} 

MainWindowViewModel.cs

namespace DataGridTest 
{ 
    using System.Collections.ObjectModel; 
    using System.ComponentModel; 

public class MainWindowViewModel : INotifyPropertyChanged 
{ 
    private readonly ObservableCollection<Person> _persons = new ObservableCollection<Person>(); 

    private static int _id = 3; 

    public ObservableCollection<Person> Persons 
    { 
     get 
     { 
      return _persons; 
     } 
    } 

    public MainWindowViewModel() 
    { 
     _persons.Add(new Person { Id = 1, Name = "A" }); 
     _persons.Add(new Person { Id = 2, Name = "B" }); 
     _persons.Add(new Person { Id = 3, Name = "C" }); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public void Refresh() 
    { 
     _persons.Add(new Person() { Id = ++_id, Name = _id.ToString() }); 
    } 

} 

}

+0

你有任何的链接或例子可以告诉我吗?谢谢 – 0070

+0

请注意,如果我问你为什么要用ObservableCollection做这样的事情?我知道如果您希望发生事件,如果在更新/删除记录时需要运行任何方法,但在此阶段感觉有点矫枉过正,那可能会很好。从来没有使用ObservableCollection,所以很高兴知道我是否错过了很酷的东西。 –