简体   繁体   English

如何创建动态WPF数据网格?

[英]How to create a dynamic WPF datagrid?

i have a dynamic database whereby the data in the database will be updated within a minute. 我有一个动态数据库,数据库中的数据将在一分钟内更新。 Now, i created a datagrid in my WPF project and i want to show all the data from the database. 现在,我在WPF项目中创建了一个数据网格,我想显示数据库中的所有数据。 When i run my project, the datagrid will only show the static data(data before the project run). 当我运行我的项目时,datagrid将仅显示静态数据(项目运行之前的数据)。 How can i make sure my datagrid will keep update itself after i run it? 我如何确保我的数据网格在运行后将保持自身更新 Btw, i using linq to sql and C# for my WPF project. 顺便说一句,我为WPF项目使用linq to sql和C#。

code snippet for my datagrid: 我的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>

code snippet for my code behind: 我的代码背后的代码段:

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

Here is my 2 cents: 这是我的2美分:

  1. Bind your DataGird's ItemsSource to an ObservableCollection. 将您的DataGird的ItemsSource绑定到ObservableCollection。
  2. Initialize the collection on the loaded event handler. 在加载的事件处理程序上初始化集合。
  3. Add an timer, in the timer's callback, you can refresh the collection from database. 添加一个计时器,在计时器的回调中,您可以刷新数据库中的集合。 Note:if you are using .NET 4.5, there is support for updating ObservableCollection form background thread. 注意:如果使用的是.NET 4.5,则支持更新ObservableCollection表单后台线程。 Otherwise, you need to handle the thread synchronization manually. 否则,您需要手动处理线程同步。

Here is a link for updating data in background, may be not perfect fit your problem, but you can get some ideas: 这是在后台更新数据的链接,可能不完全适合您的问题,但是您可以得到一些建议:

Observable Collection Cross-Thread Change Notification 可观察的集合跨线程更改通知

Edit: 编辑:

I just wrote an example(For simplicity, I use DispatcherTimer which updates the collection in UI thread. To update data in background thread, you need to use System.Timers.Timer instead, and use the method in the link.): 我只是写了一个示例(为简单起见,我使用DispatcherTimer来更新UI线程中的集合。要更新后台线程中的数据,您需要改用System.Timers.Timer,并在链接中使用方法。):

App.xaml.cs: 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 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: 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 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() });
    }

}

} }

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

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