【问题标题】:ListView Delete Refresh does not work?ListView 删除刷新不起作用?
【发布时间】:2016-05-17 22:01:42
【问题描述】:

我正在开发具有基本 CRUD 功能的 WPF MVVM 应用程序。我使用包含和显示用户数据的 ListView。当我添加或更新某些用户时 ListVew 会立即刷新,但在 Delete 命令后 ListView 不会刷新。在这种情况下,我必须关闭应用程序并再次运行以刷新 ListView。

XAML

<ListView  Name="LstUsers" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
              ScrollViewer.VerticalScrollBarVisibility="Disabled" IsSynchronizedWithCurrentItem="True"
              ItemsSource="{Binding ViewList.View, UpdateSourceTrigger=PropertyChanged, IsAsync=True}"
              SelectedItem="{Binding CurrentSelectedUser, Mode=TwoWay}" Height="150" Margin="0,40,10,260" Grid.ColumnSpan="2" Grid.RowSpan="2">

查看模型

private ObservableCollection<User> _users;


public UserViewModel()
{

  _users = new ObservableCollection<User>(GetAllUsers());

// Paging Control
  ViewList = new CollectionViewSource();
  ViewList.Source = Users;
  ViewList.Filter += new FilterEventHandler(ViewFilter);

  CurrentPageIndex = 0;
  itemcount = Users.Count;
  CalculateTotalPages();
}

#region DeleteCommand

    public ICommand DeleteUserCmd
    {
        get { return new RelayCommand(k => DeleteUser(CurrentSelectedUser)); }
    }

    // Delete user from database.
    private void DeleteUser (User user)
    {
        if(CurrentSelectedUser != null)
        {
            using (var userManager = new UserManager())
            {
                MessageBoxResult msgResult = MessageBox.Show("Are you sure to delete user?", "Delete user?", System.Windows.MessageBoxButton.OKCancel, MessageBoxImage.Asterisk);
                if (msgResult == System.Windows.MessageBoxResult.Yes)
                {
                    return;
                }
                userManager.Delete(user);
                MessageBox.Show("User is deleted!", "Confirm!", MessageBoxButton.OK, MessageBoxImage.Asterisk);

                // Refresh Listview after delete record.
                Users.Remove(user);
            }
        }
        else
            MessageBox.Show("You must select user!", "Warning!", MessageBoxButton.OK, MessageBoxImage.Exclamation);  
    }

    #endregion

型号

public CollectionViewSource ViewList { get; set; }

public ObservableCollection<User> Users
    {
        get
        {
            return _users;
        }
        set
        {
            _users = value;
            OnPropertyChanged("Users");
        }
    }

【问题讨论】:

  • ItemsSource="{Binding ViewList.View, UpdateSourceTrigger=PropertyChanged, IsAsync=True,ModeTwoWay}"
  • 试试这个 ViewList.View.Refresh();行后 OnPropertyChanged("Users");
  • 我没有尝试任何事情发生,当我在 ItemSource 中插入 Mode=TwoWay 作为您的第一条评论时,我收到错误:TwoWay 或 OneWayToSource 绑定无法在“System”类型的只读属性“View”上工作。 Windows.Data.CollectionViewSource'。
  • 在代码中删除用户后你的列表ViewList是否改变
  • 带断点的检查清单

标签: c# wpf mvvm refresh


【解决方案1】:

编辑:这是翻译错误吗?我注意到 Korisnici 是波斯尼亚语的“用户”

您将 ItemsSource 绑定到的 ViewList.View 是什么?

无论如何,您可能将项目绑定到属性“Users”,因此当您想要更新列表时调用 OnPropertyChanged("Users")。

但是,您要从“Korisnici”中删除用户:

// Refresh Listview-a after delete record.
Korisnici.Remove(user);
OnPropertyChanged("Users");

不是“用户”集合。除非 Korisnici.Remove 是您创建的方法?什么是科里斯尼奇?我想你想要:

// Refresh Listview-a after delete record.
Users.Remove(user);

注意,您不需要 OnPropertyChanged("Users") - 这是由 ObservableCollection 管理的,它实现 INotifyCollectionChanged 本身来通知集合的更改。

【讨论】:

  • 抱歉有错。我已经用英文翻译了代码,所以我没有看到这部分带有 "Korisnici" 。它是用户的收藏。我使用了 ViewList CollectionViewSource,因为我有使用 CollectionViewSource 的分页控件,并以这种方式绑定到 ItemSource。我在 Update 和 Add 方法上使用 OnPropertyChanged("Users") 并且evertything 运行良好,因此我包含在 Delete 命令中。
  • 如果在删除用户后更新或添加到列表会发生什么?然后它是否显示已删除的用户已消失?
  • 在这种情况下,我收到消息“用户已更新”,但如果您的意思是“已删除用户”,则在 ListView 中没有将字段更新为新值?其他记录运行良好,删除后?
  • 另外一个用户? (不是删除的那个)
  • 我已经删除了 OnPropertyChanged("Users") 和同样的东西。
【解决方案2】:

我添加了这一行

Users.Remove(Users.Where(i => i.UserId == user.UserId).Single());

而不是

Users.Remove(user);

现在当我在删除命令计数用户为负一但应用程序失败后调试代码时

对象引用未设置为对象的实例。

public User CurrentSelectedUser
    {
        get { return _user; }
        set
        {
            UserId = value.UserId;
            FirstName = value.FirstName;
            LastName = value.LastName;
            Username = value.Username;
            Password = value.Password;
            UserTypeId = value.UserTypeId;
            OnPropertyChanged("CurrentSelectedUser");
        }
    }

【讨论】:

    【解决方案3】:

    “对象引用未设置为对象的实例”究竟在哪里?我怀疑它在这条线上:

    UserId = value.UserId;
    

    当您删除选定的用户时,列表会更新(终于!万岁) - 当这种情况发生时,CurrentSelectedUser 不再存在(它刚刚被删除)所以我怀疑绑定设置为 null。 (未选择任何内容)。

    这会调用 value=null 的 set{} 方法。所以 value.UserId;抛出异常。

    您需要像这样或类似的处理将 CurrentSelectedUser 设置为 null:

    public User CurrentSelectedUser
    {
        get { return _user; }
        set
        {
            if (value != null)
            {
                UserId = value.UserId;
                FirstName = value.FirstName;
                LastName = value.LastName;
                Username = value.Username;
                Password = value.Password;
                UserTypeId = value.UserTypeId;
            }
            else
            {
                 UserId = -1;// or other "NO USER" condition
                 //etc etc
            }
            OnPropertyChanged("CurrentSelectedUser");
        }
    }
    

    【讨论】:

    • 乔非常感谢您的帮助。一切正常。
    • @enzodev 太棒了!没问题,很高兴能帮上忙。我了解了 CollectionViewSource(以前从未遇到过),它非常适合我正在开发的应用程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    相关资源
    最近更新 更多