简体   繁体   中英

Realtime update of DataGrid C#

Im creating a UI that visualizes som parts of a simulator. I am supposed to present some of the values in a table format, however I'm unable to get the table to update continuously when its already initialized (it initialized with the correct values, but is then static when you look at it, so you have to go to another page and then back to get the table to update) This is the code:

<Page x:Class="SimulatorUI.RawDataPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:SimulatorUI"
      mc:Ignorable="d" 
      d:DesignHeight="950" d:DesignWidth="750"
      Title="RawDataPage">

    <DataGrid Name="dataTable" MinWidth="500" Margin="10 10 10 10" HorizontalContentAlignment="Center" HorizontalAlignment="Center"/>
</Page>

And the c# code looks like this

    public partial class RawDataPage : Page
{
    List<TankModule> tankList;
    public RawDataPage(List<TankModule> list)
    {
        tankList = list;
        InitializeComponent();
        List<displayModule> data = loadTable();
        dataTable.ItemsSource = data;
        Task.Run(() => updateLoop());   
    }
    public List<displayModule> loadTable()
    {
        List<displayModule> modules = new List<displayModule>();
        foreach(TankModule tank in tankList)
        {
            modules.Add(new displayModule(tank));
        }
        return modules;
    }     
    internal async Task updateLoop()
    {
        for (; ; )
        {
            dataTable.ItemsSource = null;
            dataTable.ItemsSource = loadTable();
            await Task.Delay(1000);
        }
    }
}

Data binding works best in these cases.

Change the tankList from List to ObservableCollection to begin with, and bind the DataGrid to tankList . Now, whenever you will add or remove a new item in tankList , the DataGrid will update to reflect the change.

The code-behind should look like this:

// Add this using to use ObservableCollection
using System.Collections.ObjectModel;

public partial class RawDataPage : Page
{
    // I've renamed tankList to TankList, as it is a convention to name public properties in Pascal case
    public ObservableCollection<TankModule> TankList { get; set; }

    public RawDataPage(List<TankModule> list)
    {
        DataContext = this; // This will bind this instance as the data context of the view

        tankList = new ObservableCollection<TankModule>(list);
    }
}

In the View:

<Page x:Class="SimulatorUI.RawDataPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:SimulatorUI"
      mc:Ignorable="d" 
      d:DesignHeight="950" d:DesignWidth="750"
      Title="RawDataPage">

    <DataGrid Name="dataTable" ItemsSource="{Binding TankList}" MinWidth="500" Margin="10 10 10 10" HorizontalContentAlignment="Center" HorizontalAlignment="Center"/>
</Page>

Note: if you modify an item in TankList, the view might not get updated. You can do something like this after modifying the list item to refresh the list:

ObservableCollection<TankModule> copy = TankList;
TankList = null;
TankList = copy;

Also, it is recommended to use a view model instead of doing all these in the code-behind.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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