通过MVVM的ObservableCollection <t>绑定不会更新视图</t>

时间:2010-10-15 11:40:29

标签: wpf mvvm binding observablecollection

我有以下简化的ViewModel

public class UserViewModel : IUserViewModel
{
    public DelegateCommand<object> NewUser { get; private set; }

    public ObservableCollection<UserInfo> UserList { get; set; }

    public UserViewModel( ) {
        NewUser = new DelegateCommand<object>( OnNewUser );

        this.UserList = new ObservableCollection<UserInfo>( );
        UserList.Add( new UserInfo( "Peter" );
        UserList.Add( new UserInfo( "Paul" );
        UserList.Add( new UserInfo( "Mary" );
    }

    private void OnNewUser( object parameter ) {
        UserInfo user = new UserInfo( "User"+DateTime.Now.ToLongTimeString(), 0, true, false, false );
        UserList.Add( user );
    }
}

此视图模型是(简化)视图的数据上下文:

public partial class UserView : ViewBase
{
    public UserView( UserViewModel viewModel ) {
    InitializeComponent( );

    this.DataContext = viewModel;
    }
}

视图本身包含一个绑定到UserViewModel的UserList的ListBox:

<ListBox ItemsSource="{Binding UserList}" DisplayMemberPath="UserID" />

初始化视图模型时,会将用户添加到列表中。此用户显示在列表框中。之后调用NewCommand时,新用户将被添加到列表中。但列表框不会与新用户一起更新。

我在视图模型和视图中添加了一个CollectionChanged处理程序。视图处理程序在构造函数中添加如下:

viewModel.UserList.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler( UserList_CollectionChanged );

[编辑]

将新用户添加到集合的命令由来自不同视图的按钮触发:

public class UserButtonBarViewModel : IUserButtonBarViewModel
{

    public UserButtonBarViewModel( IUserButtonBarView view, IUserViewModel mainModel ) {
        this.View = view;
        NewUser = mainModel.NewUser;
        this.View.Model = this;
    }

    public ICommand NewUser { get; private set; }

    public IUserButtonBarView View {get; private set; }
}

UserButtonBarView如下所示:

<UserControl ...>
    <Button Command="{Binding NewUser}" Content="New user"/>
</UserControl>

视图的代码背后:

public partial class UserButtonBarView : IUserButtonBarView
{

    public UserButtonBarView( ) {
        InitializeComponent( );
    }

    public IUserButtonBarViewModel Model {
        get {
            return DataContext as IUserButtonBarViewModel;
        }
        set {
            DataContext = value;
        }
    }
}

[/编辑]

有趣的是,视图模型中的处理程序是在将新用户添加到集合时执行的,但未调用视图的处理程序。

为什么还没有调用视图的处理程序?当视图模型中的集合发生更改时,为什么列表框不会自动更新?

4 个答案:

答案 0 :(得分:3)

听起来您正在某处创建ViewModel的第二个副本(可能在您的ButtonViewModel中),而NewUser按钮正在将一个用户添加到一个副本,而ListBox仍然绑定到另一个副本。

您可以发布NewUser命令代码吗?

答案 1 :(得分:0)

你能发布实际添加新用户的代码吗?看起来它可能发生在与UI不同的线程上?尝试使用Dispatcher.Invoke ...

答案 2 :(得分:0)

我认为您需要使用TwoWay绑定。

<ListBox ItemsSource="{Binding UserList, Mode=TwoWay}" DisplayMemberPath="UserID" />

答案 3 :(得分:0)

我看到你的UserList属性有一个setter - 当你对用户列表进行更改时,你是清除并添加到当前的ObservableCollection,还是创建一个新的?