#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;
Кроме того, рекомендуется использовать модель представления вместо выполнения всего этого в коде.