Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 可观察收集<;T>;通过MVVM进行绑定不需要';不要更新视图_Wpf_Mvvm_Binding_Observablecollection - Fatal编程技术网

Wpf 可观察收集<;T>;通过MVVM进行绑定不需要';不要更新视图

Wpf 可观察收集<;T>;通过MVVM进行绑定不需要';不要更新视图,wpf,mvvm,binding,observablecollection,Wpf,Mvvm,Binding,Observablecollection,我有以下简化的视图模型 public class UserViewModel : IUserViewModel { public DelegateCommand<object> NewUser { get; private set; } public ObservableCollection<UserInfo> UserList { get; set; } public UserViewModel( ) { NewUser =

我有以下简化的视图模型

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 );
    }
}
视图本身包含一个绑定到UserViewModel的UserList的列表框:

<ListBox ItemsSource="{Binding UserList}" DisplayMemberPath="UserID" />
[编辑]

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

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如下所示:

viewModel.UserList.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler( UserList_CollectionChanged );
<UserControl ...>
    <Button Command="{Binding NewUser}" Content="New user"/>
</UserControl>
[/编辑]

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


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

您可以发布实际添加新用户的代码吗?它似乎可能发生在不同于UI的线程上?尝试使用Dispatcher.Invoke…

我认为您需要使用双向绑定

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

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


你能发布你的新用户命令代码吗?

我看到你的UserList属性有一个setter-当你对用户列表进行更改时,你是清除并添加到当前的ObservableCollection中,还是创建一个新的?你能发布实际添加新用户的代码吗?我把问题移到了一个注释中。。。对不起,但这没用。我是否必须为双向绑定更改视图模型IMElement InotifyProperty?我刚刚为自己创建了一个非常简单的测试应用程序,它似乎可以在没有双向绑定的情况下工作。我没有像你那样使用“命令”(我只是在codebehind中添加了一些东西),但这不重要。我可以发布代码,如果你认为这是有益的。只是注意到你对不同视图的编辑。这显然与你的问题有关,所以我所发布的任何东西都帮不了你,对不起!在ItemsSource属性上设置TwoWay时不会执行任何操作,因为ItemsControl不会更改绑定到它们的集合。为了使TwoWay产生任何效果,ListBox必须在内部将新集合实例分配给其ItemsSource属性,然后将其推送到VM并替换以前分配给UserList的整个集合实例。这显然是不可取的,这就是为什么它不能以这种方式工作。NewUser命令的代码已经发布在第一段代码中。NewUser命令ia分配了一个指向OnNewUser()的新委托命令。这个方法只是创建一个新的UserInfo实例并将其添加到集合中。依赖关系通过IoC容器得到解决。容器已将UserViewModel的另一个实例注入UserButtonBarViewModel。将ContainerControlled LifetimeManager添加到UserViewModel后,它就可以工作了。谢谢你的帮助,我得道歉。setter没有使用,我刚刚忘记删除它。对不起,不过还是谢谢你。
public partial class UserButtonBarView : IUserButtonBarView
{

    public UserButtonBarView( ) {
        InitializeComponent( );
    }

    public IUserButtonBarViewModel Model {
        get {
            return DataContext as IUserButtonBarViewModel;
        }
        set {
            DataContext = value;
        }
    }
}
<ListBox ItemsSource="{Binding UserList, Mode=TwoWay}" DisplayMemberPath="UserID" />