ListBox - CollectionViewSource - 多线程 - 定时器 - 不更新
我有更新列表框的问题。
零件OD Window.xamlListBox - CollectionViewSource - 多线程 - 定时器 - 不更新
DataContext="{Binding Link, Source={StaticResource Computer}}">
<Window.Resources>
<CollectionViewSource Source="{Binding GetLinkInfo}" x:Key="compLink">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Grupa" />
<scm:SortDescription PropertyName="Host" />
</CollectionViewSource.SortDescriptions>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Grupa" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<ListBox x:Name="_lbLink" ItemsSource="{Binding Source={StaticResource compLink}}">
</ListBox>
而且Window.xaml.cs
ViewModel.cs 的private void InitializedTimers()
{
_timer = new System.Timers.Timer();
_timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
_timer.Interval = 10 * 1000;
_timer.Enabled = true;
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
MainViewModelLocator mvm = Application.Current.Resources["Computer"] as MainViewModelLocator;
LinkViewModel lvm = mvm.Link;
if (lvm != null)
{
if ((from t in lvm.GetLinkInfo
where t.State == MRPLink.Link.StateLink.NOTCHECK
select t).Count() > 0)
{
int id = (from t in lvm.GetLinkInfo
where t.State == MRPLink.Link.StateLink.NOTCHECK
select t).First().ID;
lvm.UpdateStatus(id, MRPLink.Link.StateLink.CZECKOK, "xxxx");
}
}
}
零件
public void UpdateStatus(int id, StateLink aState, string aIp)
{
_localinfo.Where(t => t.ID == id).ToList().ForEach(t =>
{
t.State = aState;
if (!String.IsNullOrEmpty(aIp))
{
t.LastIp = aIp;
t.LastSea = DateTime.Now;
}
});
RaisePropertyChanged("GetLinkInfo");
}
属性的调用,但没有更新列表框。
在我看来,这与计时器有关。但我不知道如何避开。
Thx寻求帮助。
ADDED
- I校正符号(选择吨).Count之间()> 0)从==
- 当我改变定时器DispatcherTimer我有存取权限DataContent,但不是全自动更新。
LinkViewModel lvm = this.DataContext as LinkViewModel;
我可以使用_lbLink.Items.Refresh();任何变化:(之后
ADDED2
重播Stave B后,我想DispatcherHelper
我用它像
Unit testing with MVVM Light & DispatcherHelper
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
lvm.UpdateStatus(id, MRPLink.Link.StateLink.CZECKOK, "xxx");
//_lbLink.Items.Refresh();
});
但不会刷新窗台
ADDED3:
在此更改后,我看到执行属性GetLinkInfo但在ListBox中不刷新:(
ADDED4:
评论blindmeis我的应用程序正确刷新后。谢谢大家的帮助。
我看不到你的GetLinkInfo定义在哪里,所以我假设如下。
在你的窗口的datacontext中你有一个属性,你只需要初始化集合一次,只需添加,删除编辑项目,如果你需要。
public ObservableCollection<LinkInfo> GetLinkInfo
{get; set;}
在计时器线程或要更新您的状态,任何其他梅索德,所以只是做
Application.Current.Dispatcher.BeginInvoke(new Action(() =>lvm.UpdateStatus(id, MRPLink.Link.StateLink.CZECKOK, "xxxx");));
现在重要的东西,如果您添加或删除的项目到您的收藏中的ObservableCollection会提升INotifyPropertyChanged并更新您的用户界面。如果更新集合中的现有项目,则要更新的项目(类)应实现INotifyPropertyChanged。我不知道你的列表框正在显示什么,导致无法看到任何DataTemplate,但我认为你有一个。
通过这个替换给updateStatus代码:
public void UpdateStatus(int id, StateLink aState, string aIp)
{
_localinfo.Where(t => t.ID == id).ToList().ForEach(t =>
{
t.State = aState;
if (!String.IsNullOrEmpty(aIp))
{
t.LastIp = aIp;
t.LastSea = DateTime.Now;
}
});
Dispatcher.Invoke(()=>RaisePropertyChanged("GetLinkInfo"));
}
的UI相关的工作必须从UI线程调用。这是(很简单)分派器对象的目的。
我在我的名字空间找不到Dispatcher.Invoke。 – 2011-03-18 10:37:04
这取决于你的MVVM框架。例如,如果你使用MVVMLight工具包,你将不得不做''GalaSoft.MvvmLight.Threading.DispatcherHelper.UIDispatcher.Invoke(新操作(RaisePropertyChanged(“GetLinkInfo”));' – 2011-03-18 10:46:02
我在尝试,但仍然有些问题。属性是执行但不具有约束力:( – 2011-03-18 10:54:28
这是我仍然想念的,谢谢 – 2011-03-18 11:08:39