可观察的集合未更新

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可观察的集合未更新相关的知识,希望对你有一定的参考价值。

我在我的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" });
    }


}

关于如何解决这个问题的任何建议?

最好的问候,乔纳斯

答案

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

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

另一答案

你有一个名为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;
                    }
                };

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

另一答案

如果你想要这个功能,你也应该在ViewModel中使用Imaplement INotifyPropertyChanged

它适用于我的代码

另一答案

如你所说“但如果我从另一个视图更新视图模型,请回到我的手机上没有任何反应。”

只需确认您是否在其他视图中创建ViewModel的新对象。如果是,那么您可能正在更新这个新创建的激烈的可观察集合。

尝试制作你的viewModel单例。

以上是关于可观察的集合未更新的主要内容,如果未能解决你的问题,请参考以下文章

刷新 WPF Datagrid 未绑定到可观察集合?

可观察的集合没有在 UI 更改时更新

Kendo 可观察复选框未通过 jQuery .prop("checked") 更新

敲除可观察字段未在输入值更改时更新

具有可观察集合类型的 Viewmodel 的 MVVM ListView 不更新视图

使用 Linq 一次更新可观察集合项的两个字段