[英]WPF MVVM: ItemTemplate for binding a list of ICommands to a ListBox
[英]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.