Silverlight:如何绑定List到数据网格
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:如何让它们自动显示?
谢谢。
PS 这是我的视图模型中新 List 对象的声明:
public List<SquadPlayerViewModel> SquadPlayers { get; set; }
MVVM pattern is implemented in my Silverlight4 application.
Originally, I worked with ObservableCollection of objects in my ViewModel:
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);
}
}
...
}
Here is a peacie of XAML code for grid displaying:
xmlns:DataControls="clr-namespace:System.Windows.Controls;
assembly=System.Windows.Controls.Data"
...
<DataControls:DataGrid ItemsSource="{Binding SquadPlayers}">
...</DataControls:DataGrid>
and my ViewModel is bound to DataContext property of the view.
This collection (SquadPlayers) is not changed after its creation so I would like to change its type to
List<SquadPlayerViewModel>
. When I did that, I also added
RaisePropertyChanged("SquadPlayers")
in the end of '_model_DataReceivedEvent' method (to notify the grid that list data are changed.
The problem is that on initial displaying grid doesn't show any record... Only when I click on any column header it will do 'sorting' and display all items from the list...
Question1: Why datagrid doesn't contain items initially?
Q2: How to make them displayed automatically?
Thanks.
P.S. Here is a declaration of the new List object in my view-model:
public List<SquadPlayerViewModel> SquadPlayers { get; set; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您不能使用 List 作为绑定源,因为 List 没有实现 INotifyCollectionChanged 它需要 WPF/Silverlight 了解集合的内容是否更改。 WPF/Sivlerlight 可以采取进一步的行动。
我不知道为什么你需要 List<>在您的视图模型上,但如果出于抽象原因,您可以使用 IList<>反而。但请确保将 ObservableCollection<> 的实例放在在其上,而不是列表<>。无论您在 ViewModel Binding 中使用什么类型,都只关心运行时类型。
所以你的代码应该像这样:
我通常使用这种方法来抽象 NHibernate 返回的“代理”域模型。
You can't use List as a binding source, because List not implement INotifyCollectionChanged it is require for WPF/Silverlight to have knowledge for whether the content of collection is change or not. WPF/Sivlerlight than can take further action.
I don't know why you need List<> on your view model, but If for abstraction reason you can use IList<> instead. but make sure you put instance of ObservableCollection<> on it, not the List<>. No matter what Type you used in your ViewModel Binding Only care about runtime type.
so your code should like this:
I usually used this approach to abstract my "Proxied" Domain Model that returned by NHibernate.
您需要将您的 SquadPlayers 列表定义如下:
You'll need to have your SquadPlayers List defined something like this:
问题是,虽然
PropertyChanged
事件通知“更改”的绑定,但值实际上并未更改,但集合对象仍然是同一个对象。如果某些控件认为值没有真正改变,它们就会节省一些不必要的工作。尝试创建 ObservableCollection 的新实例并分配给该属性。在这种情况下,当前分配的对象将与您在数据可用时创建的新对象不同。
The problem is that whilst the
PropertyChanged
event informs the binding of a "change" the value hasn't actually changed, the collection object is still the same object. Some controls save themselves some percieved unnecessary work if they believe the value hasn't really changed.Try creating a new instance of the
ObservableCollection
and assigning to the property. In that case the currently assigned object will differ from the new one you create when data is available.