MVVM模式在我的Silverlight4应用程序中实现。
最初,我在ViewModel中使用ObservableCollection对象:
public class SquadViewModel : ViewModelBase<ISquadModel>
{
public SquadViewModel(...) : base(...)
{
SquadPlayers = new ObservableCollection<SquadPlayerViewModel>();
...
_model.DataReceivedEvent += _model_DataReceivedEvent;
_model.RequestData(...);
}
private void _model_DataReceivedEvent(ObservableCollection<TeamPlayerData> allReadyPlayers, ...)
{
foreach (TeamPlayerData tpd in allReadyPlayers)
{
SquadPlayerViewModel sp = new SquadPlayerViewModel(...);
SquadPlayers.Add(sp);
}
}
...
}
以下是用于网格显示的XAML代码:
xmlns:DataControls="clr-namespace:System.Windows.Controls;
assembly=System.Windows.Controls.Data"
...
<DataControls:DataGrid ItemsSource="{Binding SquadPlayers}">
...</DataControls:DataGrid>
并且我的ViewModel绑定到视图的DataContext属性。
此集合(SquadPlayers)在创建后未更改,因此我想将其类型更改为
List<SquadPlayerViewModel>
。当我这样做时,我也添加了
RaisePropertyChanged("SquadPlayers")
在'_model_DataReceivedEvent'方法的末尾(用于通知网格列表数据已更改。
问题是在初始显示网格时没有显示任何记录...只有当我点击任何列标题时,它才会“排序”并显示列表中的所有项目......
问题1:为什么数据网格最初不包含项目? Q2:如何让它们自动显示?
感谢。
P.S。这是我的视图模型中新List对象的声明:
public List<SquadPlayerViewModel> SquadPlayers { get; set; }
答案 0 :(得分:3)
你不能使用List作为绑定源,因为List没有实现INotifyCollectionChanged它需要WPF / Silverlight知道集合的内容是否发生了变化。 WPF / Sivlerlight比可以采取进一步行动。
我不知道你为什么需要List&lt;&gt;在您的视图模型上,但如果出于抽象原因,您可以使用IList&lt;&gt;代替。但请确保放置ObservableCollection&lt;&gt;的实例在它上面,而不是List&lt;&gt;。无论您在ViewModel Binding中使用什么类型,只关心运行时类型。
所以你的代码应该是这样的:
//Your declaration
public IList<SquadPlayerViewModel> SquadPlayers { get; set; }
//in your implementation for WPF/Silverlight you should do
SquadPlayers = new ObservableCollection<SquadPlayerViewModel>();
//but for other reason (for non WPF binding) you can do
SquadPlayers = new List<SquadPlayerViewModel>();
我通常使用这种方法来抽象NHibernate返回的“Proxied”域模型。
答案 1 :(得分:2)
您需要将SquadPlayers列表定义为:
private ObservableCollection<SquadPlayerViewModel> _SquadPlayers;
public ObservableCollection<SquadPlayerViewModel> SquadPlayers
{
get
{
return _SquadPlayers;
}
set
{
if (_SquadPlayers== value)
{
return;
}
_SquadPlayers= value;
// Update bindings, no broadcast
RaisePropertyChanged("SquadPlayers");
}
}
答案 2 :(得分:1)
问题是,当PropertyChanged
事件通知绑定“更改”时,值实际上没有更改,集合对象仍然是同一个对象。如果他们认为价值没有真正改变,一些控制可以节省一些不必要的工作。
尝试创建ObservableCollection
的新实例并分配给该属性。在这种情况下,当前分配的对象将与您在数据可用时创建的新对象不同。