简体   繁体   English

WPF MVVM 绑定 - 列表不刷新

[英]WPF MVVM binding - list is not refreshing

I'm getting a list from the database.我正在从数据库中获取一个列表。 I have a button that adds a new user and then the list should refresh.我有一个添加新用户的按钮,然后列表应该刷新。 However, this does not happen.然而,这不会发生。 Somebody help me?来人帮帮我?

Model:模型:

namespace ManagementProjectSystem.Model
{
    public class User
    {
        [Key]
        public int UserID { get; set; }
        public int UserRoleID { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }
        public string Login { get; set; }
        public string Password { get; set; }
        public DateTime DateCreateAccount { get; set; }

        public virtual ICollection<UserContact> UserContacts { get; set; }
        public virtual UserRole UserRole { get; set; }

    }
}

ViewModel:视图模型:

using ManagementProjectSystem.DAL;
using ManagementProjectSystem.Model;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace ManagementProjectSystem.ViewModel
{
    class AdminViewModel : BindableBase
    {
        private readonly ManagementProjectSystemContext dbContext = new ManagementProjectSystemContext();

        private List<User> _Users { get; set; }
        private string _UserRole { get; set; }
        private string _Name { get; set; }
        private string _Surname { get; set; }
        private string _Login { get; set; }
        private string _Password { get; set; }

        [Obsolete]
        public List<User> Users
        {
            get
            {
                return _Users = dbContext.User.ToList();
            }
            set
            {
                _Users = value;
                OnPropertyChanged(() => Users);
            }
        }

        public List<UserRole> UsersRole
        {
            get
            {
                return dbContext.UserRole.ToList();
            }
        }

        public string UserRole
        {
            get
            {
                return _UserRole;
            }
            set
            {
                _UserRole = value;
                RaisePropertyChanged(UserRole); //OnPropertyChanged(() => UserRole);
            }
        }

        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name = value;
                RaisePropertyChanged(Name); //OnPropertyChanged(() => UserRole);
            }
        }

        public string Surname
        {
            get
            {
                return _Surname;
            }
            set
            {
                _Surname = value;
                RaisePropertyChanged(Surname); //OnPropertyChanged(() => UserRole);
            }
        }

        public string Login
        {
            get
            {
                return _Login;
            }
            set
            {
                _Login = value;
                RaisePropertyChanged(Login); //OnPropertyChanged(() => UserRole);
            }
        }

        public string Password
        {
            get
            {
                return _Password;
            }
            set
            {
                _Password = value;
                RaisePropertyChanged(Password); //OnPropertyChanged(() => UserRole);
            }
        }

        public ICommand AddUserButton { get; set; }

        public AdminViewModel()
        {
            AddUserButton = new DelegateCommand(AddUser);
        }

        private void AddUser()
        {
            MessageBox.Show(_UserRole + " " + _Name + " " + _Surname + " " + _Login + " " + _Password);
            var userRole = dbContext.UserRole.Where(n => n.Nazwa.ToString().Equals(_UserRole)).SingleOrDefault();
            int userRoleID = userRole.UserRoleID;

            User user = new User() {Name = _Name, Surname = _Surname, Login = _Login, Password = _Password, DateCreateAccount = DateTime.Now, UserRoleID = userRoleID };

            dbContext.User.Add(user);
            dbContext.SaveChanges();

            //_Users = dbContext.User.ToList();
        }
    }
}

View - XAML查看 - XAML

<Window x:Class="ManagementProjectSystem.Admin"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ManagementProjectSystem"
        mc:Ignorable="d"
        Title="Admin" Height="450" Width="800">

    <Window.Resources>
        <Style x:Key="ListViewStyle" TargetType="{x:Type GridViewColumnHeader}">
            <Setter Property="HorizontalContentAlignment" Value="Left" />
        </Style>
    </Window.Resources>

    <Grid>
        <TabControl>
            <TabItem Header="Users">
                <Grid Background="RosyBrown">

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="396*"/>
                        <ColumnDefinition Width="396*"/>
                    </Grid.ColumnDefinitions>

                    <ListView Grid.Column="0" Grid.Row="0" Margin="10" ItemsSource="{Binding Users}" HorizontalContentAlignment="Left">
                        <ListView.View>
                            <GridView>
                                <GridViewColumn HeaderContainerStyle="{StaticResource ListViewStyle}" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                <GridViewColumn HeaderContainerStyle="{StaticResource ListViewStyle}" Header="Surname"  DisplayMemberBinding="{Binding Surname}" />
                            </GridView>
                        </ListView.View>
                    </ListView>

                    <Grid Margin="10" Grid.Column="1" Grid.Row="0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <Label>Name:</Label>
                        <TextBox Grid.Column="1" Margin="10" Text="{Binding Path = Name}"/>
                        <Label Grid.Row="1">Surname</Label>
                        <TextBox Grid.Row="1" Grid.Column="1" Margin="10" Text="{Binding Path = Surname}"/>
                        <Label Grid.Row="2">Login:</Label>
                        <TextBox Grid.Row="2" Grid.Column="1" Margin="10" Text="{Binding Path = Login}"/>
                        <Label Grid.Row="3">Password:</Label>
                        <TextBox Grid.Row="3" Grid.Column="1" Margin="10" Text="{Binding Path = Password}"/>
                        <Label Grid.Row="4">User role:</Label>
                        <ComboBox Grid.Row="4" Grid.Column="1" Margin="10" ItemsSource="{Binding Path = UsersRole}" DisplayMemberPath="Nazwa"
                                  SelectedValuePath="Nazwa" SelectedValue="{Binding UserRole}">

                        </ComboBox>

                        <Button Grid.Row="5" Grid.Column="1" Command="{Binding AddUserButton}">Add user</Button>
                    </Grid>
                </Grid>

            </TabItem>
            <TabItem Header="TabItem">
                <Grid Background="#FFE5E5E5"/>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

View - XAML.cs查看 - XAML.cs

namespace ManagementProjectSystem
{
    public partial class Admin : Window
    {
        public Admin()
        {
            InitializeComponent();
            AdminViewModel vm = new AdminViewModel();
            this.DataContext = vm;
        }
    }
}

I'm just starting to learn WPF and learn the MVVM pattern.我刚刚开始学习 WPF 并学习 MVVM 模式。 I apologize for my English if there is something wrong written.如果写错了,我为我的英语道歉。 I use Prism and Entity Framework.我使用棱镜和实体框架。 What can I improve in the code to make the list refresh work after adding a new user?添加新用户后,我可以在代码中改进哪些内容以使列表刷新工作? And generally the code is good?并且一般代码是好的?

You can use ObservableCollection if you are going to add (or remove) individual items from it and want the View to update when that happens.如果要从中添加(或删除)单个项目并希望视图在发生这种情况时更新,则可以使用ObservableCollection It's not mandatory to use ObservableCollection , but if you don't, then the UI will need to reload the entire collection when items are added (or removed).使用ObservableCollection不是强制性的,但如果不这样做,则在添加(或删除)项目时,UI 将需要重新加载整个集合。 It's up to you to decide whether that's a performance concern.由您决定这是否是性能问题。

Currently, you are reloading the collection from the data store on every access of the Users property.当前,您在每次访问 Users 属性时都从数据存储重新加载集合。 This is not good.这是不好的。

Option 1 - Keep using List<User> :选项 1 - 继续使用List<User>

I suggest first changing the Users property to avoid loading from the data store on every Get:我建议首先更改Users属性以避免在每次 Get 时从数据存储加载:

public List<User> Users
{
    get
    {
        if (_Users == null)
        {
            _Users = dbContext.User.ToList();
        }
        return _Users;
    }
    set
    {
        _Users = value;
        OnPropertyChanged(() => Users);
    }
}

Then in the AddUser method, add the new User to the list and raise the PropertyChanged event for the Users property:然后在AddUser方法中,将新User添加到列表并引发Users属性的PropertyChanged事件:

...
dbContext.User.Add(user);
dbContext.SaveChanges();
_Users.Add(user);
OnPropertyChanged(() => Users);

Option 2 - Use ObservableCollection<User> :选项 2 - 使用ObservableCollection<User>

If you do want to use ObservableCollection as suggested in comments, make the following changes:如果您确实想按照评论中的建议使用ObservableCollection ,请进行以下更改:

This line:这一行:

private List<User> _Users { get; set; }

Becomes:变成:

private ObservableCollection<User> _Users { get; set; }

The Users property becomes: Users属性变为:

public List<User> Users
{
    get
    {
        if (_Users == null)
        {
            _Users = new ObservableCollection<User>(dbContext.User);
        }
        return _Users;
    }
    set
    {
        _Users = value;
        OnPropertyChanged(() => Users);
    }
}

And remove the OnPropertyChanged(() => Users);删除OnPropertyChanged(() => Users); from the AddUser method (because the ObservableCollection will fire its own CollectionChanged event instead when you add to the collection, which will update the View).来自AddUser方法(因为ObservableCollection将在您添加到集合时触发它自己的CollectionChanged事件,这将更新视图)。

Note: in the above, I am assuming dbContext.User implements IEnumerable<User> so a ToList() is unnecessary if passing it to the ObservableCollection constructor (this avoids creating a useless list during that step).注意:在上面,我假设dbContext.User实现了IEnumerable<User>所以如果将ToList()传递给ObservableCollection构造函数是不必要的(这样可以避免在该步骤中创建无用的列表)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM