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
<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
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. 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. 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). 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. This is not good.
Option 1 - Keep using List<User>
:
I suggest first changing the Users
property to avoid loading from the data store on every 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:
...
dbContext.User.Add(user);
dbContext.SaveChanges();
_Users.Add(user);
OnPropertyChanged(() => Users);
Option 2 - Use ObservableCollection<User>
:
If you do want to use ObservableCollection
as suggested in comments, make the following changes:
This line:
private List<User> _Users { get; set; }
Becomes:
private ObservableCollection<User> _Users { get; set; }
The Users
property becomes:
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);
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).
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).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.