我在ViewModel中有一个ObservableCollection,它在View中按下ApplicationBar按钮时添加新条目。绑定到此ObservableCollection的ListBox不显示新的/更新的条目,它确实在应用程序加载时显示集合的项目。 ViewModel实现了INotifyPropertyChanged,当一个项添加到ObservableCollection(或)集时,我确实调用了NotifyPropertyChanged。
ViewModel - 根据从服务器读取的内容,将新项目添加到可观察集合中。
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<SubsViewModel> _itemsUnread;
public ObservableCollection<SubsViewModel> UnreadItems
{
get
{
return _itemsUnread;
}
set
{
_itemsUnread = value;
NotifyPropertyChanged("Updated");
}
}
void reader_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "Updated":
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
UnreadItems.Clear();
foreach (ItemViewModel subs in ItemsAll)
{
....
UnreadItems.Add(subs);
}
}
);
IsDataUpdated = true;
NotifyPropertyChanged(e.PropertyName);
break;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (null != this.PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
view - 设置datacontext和itemsource
<ListBox x:Name="SecondListBox" Margin="0,0,-12,0" ItemsSource="{Binding UnreadItems, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,7">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ItemTitle}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextLargeStyle}"/>
...
public MainPage()
{
_mainView = new MainViewModel();
InitializeComponent();
// Set the data context of the listbox control to the sample data
DataContext = _mainView;
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
viewModel中对observablecollection的任何添加/更新都不会反映在列表框中。我已经阅读了很多地方,notifypropertychanged是解决方案,但我已经没有改变,仍然看到问题。我缺少什么想法?
来自@ compoenet_tech的建议 通过在按下ApplicationBar buttin时添加新项目。我确实看到列表框显示新项目
SubsViewModel newitem = new SubsViewModel();
newitem.itemTitle = "test";
newitem.itemCount = test;
_itemssUnread.Add(newitem); test++;
因此,在Dispatcher Invoke之外执行Add()确实有效。但现在问题是我使用回调从webservice获取新列表,这是我将条目添加到unreaditems集合的地方。我不能(??)在调度员之外做。
(web service) =callback=> ViewModel =observablecollection=> View
如何通知viewmodel在回调之外更新集合,我不必使用dispather调用? (或)使用调度程序调用而不是通过交叉线程引用崩溃。
由于
答案 0 :(得分:2)
请在使用前实例化Observable集合。
在MainViewModel
的构造函数中编写以下代码,如
public MainViewModel() { _itemsUnread = new ObservableCollection(); }
无需执行函数reader_PropertyChanged
。
调用NotifyPropertyChanged
时,请使用属性名称作为参数,如
public ObservableCollection UnreadItems { 得到 { return _itemsUnread; } 组 { _itemsUnread = value; NotifyPropertyChanged( “UnreadItems”); } }
答案 1 :(得分:1)
几点说明:
1)根据MSDN,ObservableCollection已经为Silverlight实现了INotificatCollectionChanged,所以你不必重新实现它。
2)这个代码在setter中:
NotifyPropertyChanged("Updated");
有一些问题:
a)它只会在整个集合对象本身被更改时执行,而不是在集合中的项目发生更改时执行。
b)如果a按您希望的那样实现,那么string参数应该是更改为UnreadItems
的属性。
<强>更新强>
我还怀疑(在下面的评论中注明),添加Invoke
中的项目会导致通知消息丢失。我建议更改代码以直接添加项目,而不是在Invoke语句中。
答案 2 :(得分:0)
你的UnreadItems属性应该在
的构造函数中初始化UnreadItems = new ObservableCollection();