【发布时间】:2023-03-08 21:30:01
【问题描述】:
这两天我一直在查看有关此问题的 Stackoverflow 帖子,但我似乎无法理解为什么我的代码无法正常工作
当我更改 ObservableCollection 中的项目时,我似乎无法更新 UI 中的数据网格。
我知道ObservableCollection 不会触发PropertyChanged 事件,如果其中的项目发生更改。
似乎其他人已通过将INotifyPropertyChanged 添加到模型并在属性更改时调用OnPropertyChanged 来成功完成此操作。我已经实现了这一点,并检查了PropertyChanged 事件是否正在发生。
向集合中添加新项目时 UI 会更新。
我意识到这可能是线程问题,但我真的不明白如何检查或修复它。
我对编程还很陌生,并试图围绕 MVVM 进行思考。
有什么建议吗?
型号:
public class ModelObj : INotifyPropertyChanged
{
public string Name { get; set; }
public string IpAddress { get; set; }
private DateTime timer;
public DateTime Timer
{
get { return timer; }
set
{
timer = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
视图模型:
public class MainViewModel : ViewModelBase
{
public ObservableCollection<ModelObj> ModelObjects { get; } = new ObservableCollection<ModelObj>();
private IUdpDataService _udpDataService;
public MainViewModel(IUdpDataService udpDataService)
{
_udpDataService = udpDataService;
}
public void StartUdpDataService()
{
_udpDataService.StartBroadCasting();
_udpDataService.ReceivedDataEvent += ParseReceivedData;
}
private void ParseReceivedData(string receivedData)
{
// This object contains all the information in the received data packet.
UdpPacket udpPacket = new UdpPacket(receivedData);
// This object only contains the object name, IpAddress and a time variable.
ModelObj modelObj = new ModelObj
{
Name = udpPacket.Name,
IpAddress = udpPacket.IpEthernet,
Timer = DateTime.Now,
};
App.Current.Dispatcher.Invoke((Action)delegate
{
UpdateList(modelObj);
});
}
private void UpdateList(ModelObj modelObj)
{
var testObj = ModelObjects.FirstOrDefault(x => x.Name == modelObj.Name);
if (testObj != null)
{
testObj = modelObj
}
else
{
ModelObjects.Add(modelObj);
testObj = modelObj;
}
}
}
查看:
public partial class MainWindow : Window
{
private MainViewModel _viewModel;
public MainWindow(MainViewModel viewModel)
{
InitializeComponent();
_viewModel = viewModel;
DataContext = _viewModel;
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
_viewModel.StartUdpDataService();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
Settings.Default.Save();
base.OnClosing(e);
}
}
XAML:
<DataGrid Grid.Row="0" ItemsSource="{Binding Path=ModelObjects}"
IsReadOnly="True"
Background="white"
RowHeaderWidth ="0"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="auto" MinWidth="150"/>
<DataGridTextColumn Header="IP address" Binding="{Binding IpAddress}" Width="*"/>
<DataGridTextColumn Header="Timer" Binding="{Binding Timer, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
【问题讨论】:
-
如果您更改单元格中的值,
..PropertyChanged不会触发,直到您正在编辑的单元格失去焦点(单击另一个单元格),您可能需要实现INotifyPropertyChanging和 @987654333 @
标签: c# wpf user-interface mvvm inotifypropertychanged