Silverlight:如何绑定List到数据网格

发布于 2024-09-15 00:53:22 字数 1562 浏览 11 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

会傲 2024-09-22 00:53:22

您不能使用 List 作为绑定源,因为 List 没有实现 INotifyCollectionChanged 它需要 WPF/Silverlight 了解集合的内容是否更改。 WPF/Sivlerlight 可以采取进一步的行动。

我不知道为什么你需要 List<>在您的视图模型上,但如果出于抽象原因,您可以使用 IList<>反而。但请确保将 ObservableCollection<> 的实例放在在其上,而不是列表<>。无论您在 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 返回的“代理”域模型。

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:

//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>();

I usually used this approach to abstract my "Proxied" Domain Model that returned by NHibernate.

瑾兮 2024-09-22 00:53:22

您需要将您的 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");
        }
    }

You'll need to have your SquadPlayers List defined something like this:


private ObservableCollection<SquadPlayerViewModel> _SquadPlayers;

    public ObservableCollection<SquadPlayerViewModel> SquadPlayers
    {
        get
        {
            return _SquadPlayers;
        }

        set
        {
            if (_SquadPlayers== value)
            {
                return;
            }

            _SquadPlayers= value;

            // Update bindings, no broadcast
            RaisePropertyChanged("SquadPlayers");
        }
    }

风吹雨成花 2024-09-22 00:53:22

问题是,虽然 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文