【问题标题】:How to create a dynamic WPF datagrid?如何创建动态 WPF 数据网格?
【发布时间】:2012-11-27 08:08:42
【问题描述】:

我有一个动态数据库,数据库中的数据将在一分钟内更新。现在,我在我的 WPF 项目中创建了一个数据网格,我想显示数据库中的所有数据。当我运行我的项目时,数据网格将只显示静态数据(项目运行前的数据)。如何确保我的数据网格在运行后保持自行更新?顺便说一句,我在我的 WPF 项目中使用 linq to sql 和 C#。

我的数据网格的代码 sn-p:

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

我的代码后面的代码 sn-p:

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

【问题讨论】:

    标签: c# wpf linq datagrid


    【解决方案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() });
        }
    
    }
    

    }

    【讨论】:

    • 介意我问你为什么要用 ObservableCollection 做这样的事情?我知道,如果在我们更新/删除记录时需要运行任何方法,如果您希望有事件可能会很好,但在这个阶段感觉有点矫枉过正。从来没有使用过 ObservableCollection,所以很高兴知道我是否错过了任何很酷的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 2012-02-19
    • 2016-05-12
    • 2017-05-12
    • 1970-01-01
    相关资源
    最近更新 更多