可观察的集合未更新

时间:2013-11-14 15:20:23

标签: c# xaml windows-phone-8 observablecollection

我在Windows手机项目中遇到了一些麻烦。

我以编程方式创建并添加到我的视图中的项目在使用observable集合时似乎没有更新。 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" });
    }


}

有关如何解决此问题的任何建议?

祝你好运, 纳斯

4 个答案:

答案 0 :(得分:0)

如果您在集合中添加或删除项目,ObservableCollection应自动更新。

如果您修改了集合本身的内容,则需要触发一些事件以通知视图元素已更改。也就是说,模型应该实现INotifyPropertyChanged

答案 1 :(得分: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;
                    }
                };

当发生这种情况时,再次画出你的观点。

答案 2 :(得分:0)

如果您想要此功能,您还应该在ViewModel中使用Imaplement INotifyPropertyChanged

它适用于我的代码

答案 3 :(得分:0)

As you say "But if I update the viewmodel from another view, hit back on my phone nothing happens."

Just confirm if you are creating new object of ViewModel in other view or not. If yes then you might be updating observable collection of this newly created intense.

Try making your viewModel singleton.