2013-11-14 80 views
0

Im在我的windows phone項目中遇到了一些麻煩。Observable collection not updated

我用編程方式創建並添加到我的視圖中的項目似乎在使用可觀察集合時得到更新。 viewmodel和datacontext是正確的,但在視圖中沒有任何反應。

查看:

async void OnLoaded(object sender, RoutedEventArgs e) 
    { 

     if (InspectionMainMenu.Children.Count() > 0) 
      return; 
     await InspectionMainPageViewModel.Instance.LoadData(); 
     this.DataContext = InspectionMainPageViewModel.Instance; 



     int nrOfGridRows = InspectionMainPageViewModel.Instance.MenuItems.Count/2; 

     //check if there is need to add another row 
     if (InspectionMainPageViewModel.Instance.MenuItems.Count % 2 > 0) 
      nrOfGridRows++; 

     Grid grid1 = new Grid(); 
     grid1.Name = "grid1"; 
     grid1.Margin = new Thickness { Top = 0, Left = 0, Bottom = 12, Right = 0 }; 
     InspectionMainMenu.Children.Add(grid1); // Note: parentControl is whatever control you are added this to 
     grid1.ColumnDefinitions.Add(new ColumnDefinition()); 
     grid1.ColumnDefinitions.Add(new ColumnDefinition()); 
     //grid1.DataContext = InspectionMainPageViewModel.Instance.MenuItems; 
     //Binding myBinding = new Binding("MenuItems"); 
     //myBinding.Source = InspectionMainPageViewModel.Instance; 

     //grid1.SetBinding(Grid.DataContextProperty, myBinding); 
     //Add the dynamic rows 
     for (int i = 0; i < nrOfGridRows; i++) 
     { 
      grid1.RowDefinitions.Add(new RowDefinition()); 
     } 

     int currentRow = 0; 
     int currentColumn = 0; 
     int currentItem = 0; 
     foreach(InspectionMenuItem item in InspectionMainPageViewModel.Instance.MenuItems) 
     { 

      InspectionCategory menuBox = new InspectionCategory(); 
      menuBox.Title = item.Header; 
      menuBox.BgColor = App.Current.Resources["Blue"].ToString(); 
      menuBox.SetValue(Grid.RowProperty, currentRow); 
      menuBox.SetValue(Grid.ColumnProperty, currentColumn); 
      menuBox.Margin = new Thickness { Top = 0, Left = 6, Bottom = 6, Right = 6 }; 
      menuBox.IconType = "/images/appicons/"+ item.IconName +""; 
      menuBox.Tap += test2_Tap; 
      grid1.Children.Add(menuBox); 

      if (currentItem % 2 > 0) 
       currentRow++; 

      if (currentItem % 2 > 0) 
       currentColumn = 0; 
      else 
       currentColumn = 1; 

      currentItem++; 

     } 

    } 

型號:

public class InspectionMenuItem : ViewModelBase 
{ 

    string _header; 
    string _bgColor; 
    string _iconName; 
    bool _isRead; 

    public int id { get; set; } 
    /// <summary> 
    /// Header. 
    /// </summary> 
    public string Header 
    { 
     get 
     { 
      return _header; 
     } 
     set 
     { 
      _header = value; 
      OnPropertyChanged("Header"); 

     } 
    } 
    /// <summary> 
    /// BgColor. 
    /// </summary> 
    public string BgColor 
    { 
     get 
     { 
      return _bgColor; 
     } 
     set 
     { 
      _bgColor = value; 
      OnPropertyChanged("BgColor"); 

     } 
    } 
    /// <summary> 
    /// IconName 
    /// </summary> 
    public string IconName 
    { 
     get 
     { 
      return _iconName; 
     } 
     set 
     { 
      _iconName = value; 
      OnPropertyChanged("IconName"); 

     } 
    } 


} 

視圖模型:

public class InspectionMainPageViewModel : ViewModelBase, INotifyPropertyChanged 
{ 
    private static InspectionMainPageViewModel instance; 
    private TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); 

    private ObservableCollection<InspectionMenuItem> menuItems; 
    private ObservableCollection<ProtocolItem> protocolItems; 

    private string chassisNumber; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="MainViewModel"/> class. 
    /// </summary> 
    public InspectionMainPageViewModel() 
    { 
     this.menuItems = new ObservableCollection<InspectionMenuItem>(); 
     this.protocolItems = new ObservableCollection<ProtocolItem>(); 
    } 

    /// <summary> 
    /// Gets the instance. 
    /// </summary> 
    public static InspectionMainPageViewModel Instance 
    { 
     get 
     { 
      if (instance == null) 
      { 
       instance = new InspectionMainPageViewModel(); 
      } 

      return instance; 
     } 
    } 

    public ObservableCollection<InspectionMenuItem> MenuItems 
    { 
     get 
     { 
      return this.menuItems; 
     } 
    } 

    public ObservableCollection<ProtocolItem> ProtocolItems 
    { 
     get 
     { 
      return this.protocolItems; 
     } 
    } 

    public string ChassisNumber 
    { 
     get 
     { 
      return this.chassisNumber; 
     } 
    } 
    /// <summary> 
    /// Gets or sets a value indicating whether this instance is data loaded. 
    /// </summary> 
    public bool IsDataLoaded 
    { 
     get; 
     set; 
    } 

    public async Task LoadData() 
    { 
     if (this.IsDataLoaded) 
     { 
      return; 
     } 
     GetMenuItems(); 
     GetProtocolItems(); 

     SetDummyData(); 
     // this.news = await CRMService.GetNews(); 
     this.IsDataLoaded = true; 
    } 

    private void SetDummyData() 
    { 
     this.chassisNumber = "JN1HS36P8LW107899"; 
    } 


    public void GetMenuItems() 
    { 
     this.menuItems.Add(new InspectionMenuItem { Header = "Kund", IconName = "user_128.png", BgColor = "Blue" }); 
     this.menuItems.Add(new InspectionMenuItem { Header = "Fordon", IconName = "car_128.png", BgColor = "Blue" }); 
     this.menuItems.Add(new InspectionMenuItem { Header = "Identifiering", IconName = "check_128.png", BgColor = "Blue" }); 
     this.menuItems.Add(new InspectionMenuItem { Header = "Anmärkning", IconName = "user_128.png", BgColor = "Blue" }); 
     this.menuItems.Add(new InspectionMenuItem { Header = "Test", IconName = "user_128.png", BgColor = "Blue" }); 
    } 

    public void GetProtocolItems() 
    { 
     this.protocolItems.Add(new ProtocolItem { Header = "Spindelled", Summary = "Fastsättning bristfällig", ProtocolImageUri = "user_128.png" , State="Tidigare anmärkningar"}); 
     this.protocolItems.Add(new ProtocolItem { Header = "Färdbroms bromsskiva", Summary = "Risk för bromsbortfall", ProtocolImageUri = "user_128.png", State = "Tidigare anmärkningar" }); 
     this.protocolItems.Add(new ProtocolItem { Header = "Infästning bromssystem", Summary = "Sprickor", ProtocolImageUri = "user_128.png", State = "Tidigare anmärkningar" }); 
     this.protocolItems.Add(new ProtocolItem { Header = "Motor", Summary = "Topplocket sprucket", ProtocolImageUri = "user_128.png", State = "Anmärkningar" }); 
     this.protocolItems.Add(new ProtocolItem { Header = "Lysen", Summary = "Felvinklat halvljus", ProtocolImageUri = "user_128.png", State = "Anmärkningar" }); 
     this.protocolItems.Add(new ProtocolItem { Header = "Kylare", Summary = "Läckande kylare", ProtocolImageUri = "user_128.png", State = "Anmärkningar" }); 
    } 


} 

上的任何建議,就如何解決這個問題?如果從集合添加或刪除項目

最好的問候, 喬納斯

+3

你已經在那裏發佈了很多代碼,但是從你的問題中不清楚它究竟是什麼不工作。你能澄清嗎? –

+0

實際上,如果我仍然在視圖中更新viewmodel中可觀察集合中的任何項目時,我的視圖會更新。但是,如果我從另一個視圖更新視圖模型,則在我的手機上回擊沒有任何反應。我究竟做錯了什麼? –

+0

您是否在更新集合或集合中的項目? – chustar

回答

0

ObservableCollection應自動更新。

如果您修改集合本身的內容,但您需要觸發一些事件以通知視圖該元素已更改。也就是說,模型應該實現INotifyPropertyChanged

+0

INotifyPropertyChanged已實施,如果您查看InspectionMenuItem OnPropertyChanged已實施。該代碼在我的基類中實現。 奇怪的是,observable Collection更新了頁面。但是,當我回到我的手機時,不是。 –

0

您有一個名爲OnCollectionChanged與嘗試事件:

http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx

你可以看,當一個元素被添加到集合或刪除,清除...

obsList.CollectionChanged += (sender, eventArgs) => 
       { 
        switch (eventArgs.Action) 
        { 
         case NotifyCollectionChangedAction.Remove: 
          foreach (var oldItem in eventArgs.OldItems) 
          { 

          } 

          break; 
         case NotifyCollectionChangedAction.Add: 

          break; 
        } 
       }; 

時發生這種情況,再次吸引你的觀點。

+0

在我的viewmodel中實現了該方法,並且在使用正確的操作替換集合中的項目時觸發了該事件。 但是當我點擊手機上的後退按鈕時,我的gui仍然沒有更新。 如果我在進入視圖時調試並設置斷點,則viewmodel和datacontext具有更新的項目。 創建項目並直接在xaml中進行綁定時從來沒有遇到這個問題。但我在這個解決方案中沒有選擇,我不得不以編程方式添加內容。 我可以通過刪除視圖中的內容並再次添加它來解決這個問題,但這感覺像是一個糟糕的解決方案。 –

+0

當您再次導航時,請嘗試再次放入DataContext。也許綁定從視圖中刪除,並且必須重新重新建立。 – toroveneno

+0

沒有。沒有工作。我在視圖中添加了一個點擊事件,因此我可以更新該集合。 gui可以正確更新,即使我在導航中回擊並返回到視圖並再次觸發事件。只有當我使用手機上的後退按鈕以及更新後的視圖模式時,纔會出現這些問題。 –

0

如果你想要這個功能,你應該在視圖模型Imaplement INotifyPropertyChanged

它的工作在我的代碼

0

至於你說的「但是,如果我從另一個視圖更新視圖模型,打回我的電話什麼發生。」

只需確認是否在其他視圖中創建ViewModel的新對象。如果是,那麼你可能會更新這個新創建的激烈的可觀察收集。

嘗試製作您的viewModel單身人士。

相關問題