ObservableCollection不更新项目源

时间:2014-01-10 16:39:56

标签: c# wpf data-binding mvvm mvvm-light

我有一个可观察的集合,它正在从网络线程中填充。如果使用虚拟数据从构造函数填充OC,它将显示在UI上。我知道这些项目正在从网络线程添加到集合中,但项目计数永远不会在UI上更新。

我的观点模型如下:

public class ManikinStatusViewModel : DiViewModelBase
{
    private readonly ICommunicationService manikinCommunicationService;

    #region Properties
    public ObservableCollection<CasualtyStatusViewModel> Manikins { get; private set; }
    #endregion

    public ManikinStatusViewModel()
    {
        Manikins = new ObservableCollection<CasualtyStatusViewModel>();

        uow = UnitOfWorkFactory.Instance.CreateRunScenarioUnitOfWork(false);

        AccelermeterPacketData apd = new AccelermeterPacketData(56, 57, 58);

        manikinCommunicationService = new TestingCommunicationService(LoadAnalogSensorData(), apd);
        manikinCommunicationService.ManikinDataReceived += ManikinCommunicationService_ManikinDataReceived;

    }

    #region Events
    private void ManikinCommunicationService_ManikinDataReceived(object sender, ManikinDataReceivedEventArgs e)
    {
        if (e.ManiknDataPacket != null)
        {
            var manikin = Manikins.ToList().Find(m => m.ManikinId == e.ManiknDataPacket.SerialNumber);

            if (manikin == null)
            {
                Debug.WriteLine("Creating manikin with serial number: " + e.ManiknDataPacket.SerialNumber);

                CasualtyStatusViewModel csvm = new CasualtyStatusViewModel(e.ManiknDataPacket.SerialNumber);
                Manikins.Add(csvm);

                manikin = csvm;

                Debug.WriteLine("manikin count is: " + Manikins.Count());

            }

            manikin.UpdateManikinStatus(e.ManiknDataPacket);
        }
    }

    #endregion

我将manikins集合绑定到以下视图。

   <TabControl Grid.Row="1" ItemsSource="{Binding Manikins}" Name="ManikinsTabControl">
        <TabControl.Resources>
            <Style TargetType="TabItem">
                <Setter Property="Header" Value="Casualty"></Setter>
                <Setter Property="ContentTemplate" Value="{StaticResource CasualtyTemplate}"></Setter>
            </Style>
        </TabControl.Resources>
    </TabControl>

6 个答案:

答案 0 :(得分:2)

您必须在viewmodel中更新集合时提升PropertyChanged事件 并且您的viewmodel必须实现INotifyPropertyChanged

答案 1 :(得分:1)

用户界面无法知道您的收藏何时更新。你必须实际通知它。为此,您需要遵循以下步骤:

  1. INotifyPropertyChanged

  2. 实施/继承
  3. 复制粘贴此代码。我不会在这里详细介绍,但这是非常通用的代码,可以用于任何类。

    public event PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void OnPropertyChanged(string PropertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
    
  4. 现在,无论何时更新列表,请调用OnPropertyChanged方法并传递已更改的属性的名称。 (在您的情况下为OnPropertyChanged("Manikins")

答案 2 :(得分:1)

因此System.Collections.ObjectModel中有两种类型的可观察集合;一个在Remotion.Linq.Collections;显然,当使用单独的线程时,Remotion集合无法正确更新。更改为System.Collections.ObjectModel,现在看起来一切正常。

答案 3 :(得分:0)

您需要将项目添加到UI线程中的ObservableCollection<>,以便根据需要重新绘制/更新控件。

答案 4 :(得分:0)

您是否尝试过使用Distacher线程在UI线程上同步添加项目?这是值得尝试的事情:

而不是:

Manikins.Add(csvm);

您替换为:

Dispatcher.BeginInvoke(DispatcherPriority.Normal , new Action(() => 
{ 
    Manikins.Add(csvm); 
} 
));

希望这个肝脏

答案 5 :(得分:0)

当事件CollectionChanged实际上是在你添加/删除此集合中的项目时引发事件时,ObservableCollection更新UI ...如果hold集合更改了UI不会更新...我看到你使用了Manikins.Add ()方法实际上这很奇怪,UI没有更新,所以首先检查是否有真正的项目添加到集合中,第二次确保您的代码中没有任何内容将整个集合设置为新的引用...希望有所帮助