可观察的集合未更新
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单例。
以上是关于可观察的集合未更新的主要内容,如果未能解决你的问题,请参考以下文章
Kendo 可观察复选框未通过 jQuery .prop("checked") 更新