MVVM C# WPF - 更改可观察集合中的项时 UI 不更新



我已经查看有关此问题的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>

您应该设置现有对象的 Timer 属性:

private void UpdateList(ModelObj modelObj)
{
    var testObj = ModelObjects.FirstOrDefault(x => x.Name == modelObj.Name);
    if (testObj != null)
    {
        testObj.Timer = modelObj.Timer
    }
    else
    {
        ModelObjects.Add(modelObj);
    }
}

您当前正在获取对现有对象的引用,然后将保存此引用的 testObj 变量设置为对传递给 UpdateList 方法的新ModelObj对象的引用。这不会更新the模型对象集合中的对象的 Timer 属性。

testObj = modelObj

没有效果。您只需将值放入变量即可。叫

    if (testObj != null)
    {
        ModelObjects.Replace(testObj,modelObj)
    }
    else
    {
        ModelObjects.Add(modelObj);
    }

如果您替换整个对象,则根本不需要实现 INotifyPropertyChanged

相关内容

  • 没有找到相关文章

最新更新