Silverlight:如何将List <t>绑定到数据网格</t>

时间:2010-08-14 15:53:34

标签: silverlight mvvm datagrid silverlight-4.0 observablecollection

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; }

3 个答案:

答案 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的新实例并分配给该属性。在这种情况下,当前分配的对象将与您在数据可用时创建的新对象不同。