C# 为了实现CanExecute,我如何使用和EF6生成的类识别对对象的更改?

C# 为了实现CanExecute,我如何使用和EF6生成的类识别对对象的更改?,c#,entity-framework,mvvm,mvvm-light,C#,Entity Framework,Mvvm,Mvvm Light,我正在绑定XAML中的按钮以更新数据库中的用户。我想利用CanExecute仅在对ViewModel上的属性进行更改后启用按钮 我正在使用实体框架和WCF数据服务来执行CRUD操作 模范班 公共虚拟数据库集用户{get;set;} ... 名称空间pk.Data { 使用制度; 使用System.Collections.Generic; 公共部分类用户 { 公共用户() { this.private_account=new HashSet(); } 公共int id{get;set;} 公共字

我正在绑定XAML中的按钮以更新数据库中的用户。我想利用CanExecute仅在对ViewModel上的属性进行更改后启用按钮

我正在使用实体框架和WCF数据服务来执行CRUD操作

模范班
公共虚拟数据库集用户{get;set;}
... 
名称空间pk.Data
{
使用制度;
使用System.Collections.Generic;
公共部分类用户
{
公共用户()
{
this.private_account=new HashSet();
}
公共int id{get;set;}
公共字符串用户名{get;set;}
公共int超级用户{get;set;}
启用公共int的{get;set;}
公共虚拟ICollection私有_帐户{get;set;}
}
}
WCF服务
公共类pkService
{
//getUsers()
//从数据库中获取所有用户
[经营合同]
公共IEnumerable getUsers()
{
使用(var context=new pkEntities())
{
//需要使用哈希处理EF对象
context.Configuration.ProxyCreationEnabled=false;
//从数据库中提取实体对象
var results=context.users.ToList();
//从实体模型中删除
ForEach(e=>context.Entry(e).State=EntityState.Detached);
//返回分离对象
返回结果;
}
}
//updateUser(用户)-
//更新数据库中的用户
[经营合同]
public void updateUser(用户){
使用(var context=new pkEntities())
{
context.Configuration.ProxyCreationEnabled=false;
context.Entry(user.State=EntityState.Modified;
SaveChanges();
}
}
}
视图模型#
公共类HomeViewModel:ViewModelBase
{
//HomeViewModel()
//类构造函数
公共HomeViewModel()
{
这是RefreshUsers();
userListClick=新建RelayCommand(\u userListClick);
saveUser=新的RelayCommand(saveUser);
}
//使用者
//系统中所有用户的列表
私人IEnumerable用户;
公共IEnumerable用户
{
获取{返回此。\u用户;}
设置
{
这是.\u users=值;
本.RaisePropertyChanged(“用户”);
}
}
//选定用户
//当前选定的用户
私人用户_selectedUser;
公共用户选择用户
{
获取{返回此。\u selectedUser;}
设置
{
如果(此.\u selectedUser!=值)
{
这是。\ u selectedUser=value;
此.RaisePropertyChanged(“selectedUser”);
}
}
}
//刷新用户()
//从数据库检索用户的方法
私有用户()
{
此.pkServiceClient.getUsersCompleted+=(s,e)=>
{
该用户=e.结果;
};
这是.pkServiceClient.getUsersAsync();
}
//服务器列表单击
公共ICommand userListClick{get;private set;}
私有无效\u用户列表单击(选择ChangedEventArgs e)
{
ListView用户列表=(ListView)e.Source;
_selectedUser=(用户)userList.SelectedItem;
this.setUserDetailsVisible(Visibility.Visible);
此.RaisePropertyChanged(“selectedUser”);
}        
公共ICommand存储用户{get;private set;}
私有void_saveUser()
{
此.\u pkServiceClient.updateUser(\u selectedUser);
}
}
}
我相信可以绑定RelayCommand(saveUser,someCommand)并让someCommand返回一个值,我可以在XAML中绑定该值以控制按钮的启用状态


我似乎找不到使用实体生成的类来处理这个问题的方法。任何帮助都会很好。

如果我理解正确,您希望在对所选用户进行更改后尽快启用连接到saveUser命令的按钮吗

我相信可以绑定RelayCommand(saveUser,someCommand)并让someCommand返回一个值,我可以在XAML中绑定该值以控制按钮的启用状态

这在CompositeCommands()中是可能的。在这里,您可以调用方法“RegisterCommand”,并传递第二个命令,该命令会影响连接到CompositeCommand的按钮的行为。因此,如果注册的按钮返回CanExecute==false,则该按钮将被禁用

但是您也可以将CanExecute方法添加到RelayCommand中,并在那里检查实体是否具有正确的值。 例如,CanExecute方法可以检查用户名:

public HomeViewModel()
{
    this.RefreshUsers();
    userListClick = new RelayCommand<SelectionChangedEventArgs>(_userListClick);
    saveUser = new RelayCommand(saveUser, CanExecuteSaveUser);
}

private bool CanExecuteSaveUser()
    {
        if (selectedUser.username == "foo")
        {
            return true;
        }

        return false;
    }
公共HomeViewModel()
{
这是RefreshUsers();
userListClick=新建RelayCommand(\u userListClick);
saveUser=newrelaycommand(saveUser,CanExecuteSaveUser);
}
私有布尔CanExecuteSaveUser()
{
如果(selectedUser.username==“foo”)
{
返回true;
}
返回false;
}
我不会将此直接连接到您的模型。您的模型不应该被验证UI所需的逻辑所困扰。因此,您可能应该在ViewModel和WCF服务之间添加一个附加层,类似于UserViewModel,您可以在其中直接处理对用户属性所做的所有更改。这些属性的更改可能会触发RelayCommand的RaiseCanExecuteChanged方法

我希望这有帮助,如果我误解了你,请提供进一步的解释问题

编辑:

public class pkService
{

    // getUsers() - 
    //  Get all users from the database
    [OperationContract]
    public IEnumerable<user> getUsers()
    {
        using (var  context = new pkEntities())
        {
            // Needed in order to handle EF objects with Hashes 
            context.Configuration.ProxyCreationEnabled = false;
            // Pull entity object fom DB
            var results = context.users.ToList();
            // Detatch from Entity Model
            results.ForEach(e => context.Entry(e).State = EntityState.Detached);
            //Return detached object 
            return results;
        }
    }

    // updateUser(user) -
    //  Update user in the DB
    [OperationContract]
    public void updateUser(user user){
        using (var context = new pkEntities())
        {
            context.Configuration.ProxyCreationEnabled = false;
            context.Entry(user).State = EntityState.Modified;
            context.SaveChanges();
        }
    }
}
 public class HomeViewModel: ViewModelBase
    {
        // HomeViewModel()
        //  Class Constructor
        public HomeViewModel()
        {
            this.RefreshUsers();
            userListClick = new RelayCommand<SelectionChangedEventArgs>(_userListClick);
            saveUser = new RelayCommand(saveUser);
        }

        // users 
        //  list of all users in the system
        private IEnumerable<user> _users;
        public IEnumerable<user> users
        {
            get { return this._users; }
            set
            {
                this._users = value;
                this.RaisePropertyChanged("users");
            }

        }

        // selected user
        //  currently selected user
        private user _selectedUser;
        public user selectedUser
        {
            get { return this._selectedUser; }
            set
            {
                if (this._selectedUser != value)
                {
                    this._selectedUser = value;
                    this.RaisePropertyChanged("selectedUser");
                }
            }
        }

        // RefreshUsers() 
        //  Method for retrieving users from DB
        private void RefreshUsers()
        {
            this._pkServiceClient.getUsersCompleted += (s, e) =>
                {
                    this.users = e.Result;
                };
            this._pkServiceClient.getUsersAsync();

        }

        // serverListClick
        public ICommand userListClick { get; private set; }
        private void _userListClick(SelectionChangedEventArgs e)
        {
            ListView userList = (ListView)e.Source;
            _selectedUser = (user)userList.SelectedItem;
            this.setUserDetailsVisible(Visibility.Visible);
            this.RaisePropertyChanged("selectedUser");
        }        

        public ICommand saveUser { get; private set; }
        private void _saveUser()
        {
            this._pkServiceClient.updateUser(_selectedUser);
        }
    }
}
public HomeViewModel()
{
    this.RefreshUsers();
    userListClick = new RelayCommand<SelectionChangedEventArgs>(_userListClick);
    saveUser = new RelayCommand(saveUser, CanExecuteSaveUser);
}

private bool CanExecuteSaveUser()
    {
        if (selectedUser.username == "foo")
        {
            return true;
        }

        return false;
    }
public HomeViewModel()
{
    this.RefreshUsers();
    userListClick = new RelayCommand<SelectionChangedEventArgs>(_userListClick);
    saveUser = new RelayCommand(saveUser, CanExecuteSaveUser);
    selectedUserViewModel.PropertyChanged += SelectedUserOnPropertyChanged;
}

private void SelectedUserOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
    if (propertyChangedEventArgs.PropertyName.Equals(nameof(UserViewModel.username)))
    {
        (saveUser as RelayCommand)?.RaiseCanExecuteChanged();
    }
}