[英]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.