WPF MVVM 绑定 - 列表不刷新



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

型:

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

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

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

最新更新