繁体   English   中英

WPF MVVM 绑定 - 列表不刷新

[英]WPF MVVM binding - list is not refreshing

我正在从数据库中获取一个列表。 我有一个添加新用户的按钮,然后列表应该刷新。 然而,这不会发生。 来人帮帮我?

模型:

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; }

    }
}

视图模型:

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

查看 - 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>

查看 - XAML.cs

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

我刚刚开始学习 WPF 并学习 MVVM 模式。 如果写错了,我为我的英语道歉。 我使用棱镜和实体框架。 添加新用户后,我可以在代码中改进哪些内容以使列表刷新工作? 并且一般代码是好的?

如果要从中添加(或删除)单个项目并希望视图在发生这种情况时更新,则可以使用ObservableCollection 使用ObservableCollection不是强制性的,但如果不这样做,则在添加(或删除)项目时,UI 将需要重新加载整个集合。 由您决定这是否是性能问题。

当前,您在每次访问 Users 属性时都从数据存储重新加载集合。 这是不好的。

选项 1 - 继续使用List<User>

我建议首先更改Users属性以避免在每次 Get 时从数据存储加载:

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

然后在AddUser方法中,将新User添加到列表并引发Users属性的PropertyChanged事件:

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

选项 2 - 使用ObservableCollection<User>

如果您确实想按照评论中的建议使用ObservableCollection ,请进行以下更改:

这一行:

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

变成:

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

Users属性变为:

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

删除OnPropertyChanged(() => Users); 来自AddUser方法(因为ObservableCollection将在您添加到集合时触发它自己的CollectionChanged事件,这将更新视图)。

注意:在上面,我假设dbContext.User实现了IEnumerable<User>所以如果将ToList()传递给ObservableCollection构造函数是不必要的(这样可以避免在该步骤中创建无用的列表)。

暂无
暂无

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

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