Avalonia UI + Community Toolkit. Проблемы с DataGrid
коллеги. Пишу приложение во фреймворке Avalonia с Community Toolkit MVVM, которое по таймеру получает из сокета данные и сохраняет текущие значения в ObservalCollection. На View-шке в TabControl лежит DataGrid, которая биндится к этой коллекции. Как мне заставить DataGrid обновлять данные самостоятельно? Значения в коллекции меняются, DataGrid обновляет их при клике на шапку или переключении закладок TabControl... TextBlock, привязанный к ObservalProperty и получающий значение из этой же коллекции, исправно все отображает в такт с таймером... Я понимаю, что по какой-то причине DataGrid не получает уведомление об изменении значений в ItemSource, но не могу понять причину. Насколько я имею представление о Community Toolkit, она как раз решает проблему с реализацией INotifyPropertyChanged. Я пробовал добавлять в Binding "UpdateSourceTrigger=PropertyChanged", заменить DataGrid на ItemsControl, бесполезно. В документации по Avalonia примеры основаны на ReactiveUI, что не актуально для Community Toolkit, а по последней источников очень мало (или я не там ищу). Помогите разобраться с этой проблемой, она критична для проекта. Скорее всего многие начинающие кодить в Avalonia сталкивались с подобным. Или у кого-то есть ссылка на код, в котором реализована изложенная ситуация.
View
<StackPanel Margin="0,10,0,0">
<TextBlock Name="Lev1Text" Margin="4" Text="{Binding Lev1}"/>
<DataGrid Margin="20" ItemsSource="{Binding SensorData, UpdateSourceTrigger=PropertyChanged}"
IsReadOnly="True" GridLinesVisibility="All"
BorderThickness="1" BorderBrush="Gray">
<DataGrid.Columns>
<DataGridTextColumn Header="Параметр" Binding="{Binding paramName}"/>
<DataGridTextColumn Header="Значение" Binding="{Binding dataValue, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
</DataGrid>
<!--
<ItemsControl Name="GridDataItems" ItemsSource="{Binding SensorData}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="0,0,0,0" CornerRadius="2"
BorderBrush="Gray" BorderThickness="1"
Padding="5">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding paramName}"
Width="120"/>
<TextBlock Background="Transparent"
Text="{Binding dataValue}"
Width="50"/>
<TextBlock Background="Transparent"
Text="{Binding paramUnits}"
Width="120"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
-->
</StackPanel>
ViewModel
private ObservableCollection<MssSensorData> _sensorData;
public ObservableCollection<MssSensorData> SensorData
{
get { return _sensorData; }
set { SetProperty(ref _sensorData, value); }
}
public MainWindowViewModel()
{
LoadMssTree(); //Загрузка дерева
SensorData = new ObservableCollection<MssSensorData>();
LoadRegParams(); // Определение параметров для отображения
SetTimer(); // Запускаем таймер чтения данных
}
Model
public class MssSensorData
{
public int sid { get; set; }
public int dc { get; set; }
public string? paramName { get; set; }
public string? paramUnits { get; set; }
public double dataValue { get; set; }
}
Ответы (1 шт):
Задача решена изменением модели. ObservalCollection не отправляет уведомления во View об изменении своих свойств. Это нужно сделать в классе, описывающем модель данных для коллекции. Спасибо @AlexanderSt за полезный комментерий.
public class MssSensorData : INotifyPropertyChanged
{
public int sid { get; set; }
public int dc { get; set; }
public string? paramName { get; set; }
public string? paramUnits { get; set; }
public event PropertyChangedEventHandler? PropertyChanged;
private double _dataValue { get; set; }
public double dataValue
{
get { return _dataValue; }
set
{
if (_dataValue != value)
{
_dataValue = value;
OnPropertyChanged("dataValue");
}
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}