2011-03-18 33 views
0

我有更新列表框的問題。
零件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我的應用程序正確刷新後。謝謝大家的幫助。

回答

0

我看不到你的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,但我認爲你有一個。

+0

這是我仍然想念的,謝謝 – 2011-03-18 11:08:39

0

通過這個替換給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線程調用。這是(很簡單)分派器對象的目的。

+0

我在我的名字空間找不到Dispatcher.Invoke。 – 2011-03-18 10:37:04

+0

這取決於你的MVVM框架。例如,如果你使用MVVMLight工具包,你將不得不做''GalaSoft.MvvmLight.Threading.DispatcherHelper.UIDispatcher.Invoke(新操作(RaisePropertyChanged(「GetLinkInfo」));' – 2011-03-18 10:46:02

+0

我在嘗試,但仍然有些問題。屬性是執行但不具有約束力:( – 2011-03-18 10:54:28