Обновление DataGrid C в реальном времени#

#c# #wpf #xaml

#c# #wpf #xaml

Вопрос:

Я создаю пользовательский интерфейс, который визуализирует некоторые части симулятора. Я должен представить некоторые значения в формате таблицы, однако я не могу заставить таблицу непрерывно обновляться, когда она уже инициализирована (она инициализирована правильными значениями, но затем становится статичной, когда вы смотрите на нее, поэтому вам нужно перейти на другую страницу, а затем вернуться, чтобы обновить таблицу). Это и есть код:

 lt;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"gt;   lt;DataGrid Name="dataTable" MinWidth="500" Margin="10 10 10 10" HorizontalContentAlignment="Center" HorizontalAlignment="Center"/gt; lt;/Pagegt;  

И код c# выглядит так

 public partial class RawDataPage : Page {  Listlt;TankModulegt; tankList;  public RawDataPage(Listlt;TankModulegt; list)  {  tankList = list;  InitializeComponent();  Listlt;displayModulegt; data = loadTable();  dataTable.ItemsSource = data;  Task.Run(() =gt; updateLoop());   }  public Listlt;displayModulegt; loadTable()  {  Listlt;displayModulegt; modules = new Listlt;displayModulegt;();  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);  }  } }  

Комментарии:

1. Я думаю, вам следует попробовать привязать свойство ItemsSource объекта DataTable к свойству модулей ObservableCollectionlt;displayModulegt; и обновить это свойство.

2. Спасибо, разберусь в этом! Мой опыт работы в C# очень ограничен, не хотите ли уточнить?

Ответ №1:

Привязка данных лучше всего работает в этих случаях.

Для начала измените список резервуаров со списка на коллекцию ObservableCollection и привяжите сетку данных к списку резервуаров. Теперь всякий раз, когда вы добавляете или удаляете новый элемент в tankList, сетка данных будет обновляться, чтобы отразить изменения.

Кодовая часть должна выглядеть следующим образом:

 // 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 ObservableCollectionlt;TankModulegt; TankList { get; set; }   public RawDataPage(Listlt;TankModulegt; list)  {  DataContext = this; // This will bind this instance as the data context of the view   tankList = new ObservableCollectionlt;TankModulegt;(list);  } }  

В представлении:

 lt;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"gt;   lt;DataGrid Name="dataTable" ItemsSource="{Binding TankList}" MinWidth="500" Margin="10 10 10 10" HorizontalContentAlignment="Center" HorizontalAlignment="Center"/gt; lt;/Pagegt;  

Примечание. Если вы измените элемент в списке танков, представление может не обновиться. В этом случае класс TankModule должен реализовать INotifyPropertyChanged. Вы также можете сделать что-то подобное после изменения элемента списка, чтобы обновить список:

 ObservableCollectionlt;TankModulegt; copy = TankList; TankList = null; TankList = copy;  

Кроме того, рекомендуется использовать модель представления вместо выполнения всего этого в коде.