我有一个可观察的集合,它正在从网络线程中填充。如果使用虚拟数据从构造函数填充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>
答案 0 :(得分:2)
您必须在viewmodel中更新集合时提升PropertyChanged事件 并且您的viewmodel必须实现INotifyPropertyChanged
答案 1 :(得分:1)
用户界面无法知道您的收藏何时更新。你必须实际通知它。为此,您需要遵循以下步骤:
从INotifyPropertyChanged
复制粘贴此代码。我不会在这里详细介绍,但这是非常通用的代码,可以用于任何类。
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string PropertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(PropertyName));
}
}
现在,无论何时更新列表,请调用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没有更新,所以首先检查是否有真正的项目添加到集合中,第二次确保您的代码中没有任何内容将整个集合设置为新的引用...希望有所帮助