WPF:设置 属性 不会在文本框值更改时触发
WPF: set property does not trigger on textbox value changed
我有一个绑定用户模型的 EditUserViewModel。在用户模型中,我有 public 属性,例如名字、姓氏、年龄等。
EditUserViewModel
public class EditUserViewModel : BindableBase
{
private User _user;
public EditUserViewModel(User user)
{
SaveCommand = new DelegateCommand(EditUser, CanSaveCommand);
CancelCommand = new DelegateCommand(Cancel);
User = user;
}
public User User
{
get{ return _user; }
set
{
_user = value;
OnPropertyChanged(() => User);
SaveCommand.RaiseCanExecuteChanged();
}
}
public DelegateCommand SaveCommand { get; set; }
public ICommand CancelCommand { get; set; }
public Func<bool> CanSaveCommand { get { return CanEditUser; } }
private void EditUser()
{
Confirmed = true;
FinishInteraction();
}
private bool CanEditUser()
{
if (string.IsNullOrEmpty(_user.Firstname) || _user.Firstname.Length < 3) return false;
if (string.IsNullOrEmpty(_user.Lastname) || _user.Lastname.Length < 3) return false;
return true;
}
}
EditUserView
<UserControl x:Class="UserModule.Views.EditUserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock FontWeight="Bold" Grid.Row="0" Grid.Column="0">First name:</TextBlock>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=User.Firstname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock FontWeight="Bold" Grid.Row="1" Grid.Column="0">First name:</TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=User.Lastname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button x:Name="OkButton" Grid.Row="2" Grid.Column="0" Command="{Binding SaveCommand}" Content="OK"/>
<Button x:Name="CancelButton" Grid.Row="2" Grid.Column="1" Command="{Binding CancelCommand}" Content="Cancel"/>
</Grid>
</UserControl>
用户
public User
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Age { get; set; }
}
但是,当我更改名字或姓氏时,用户 属性 不会触发其 setter。但是,如果我不使用用户 class 属性,而是在 Viewmodel 中使用 Firstname 和 Lastname 字符串属性,那么当我在 GUI 中更改它们的值时,它们的 setters 会被触发。我是否需要做任何特定的事情才能使这个 class 属性 绑定工作?
在 class 中实现 INotifiyPropertyChanged 用户本身应允许通过 ViewModel 进行绑定。
确保用户 Class 实施 INotifyPropertyChanged
public class User : INotifyPropertyChanged
{
private String _firstname;
public String Firstname
{
get
{
return _firstname;
}
set
{
if (_firstname == value)
{
return;
}
_firstname = value;
OnPropertyChanged();
}
}
private String _lastName;
public String LastName
{
get
{
return _lastName;
}
set
{
if (_lastName == value)
{
return;
}
_lastName = value;
OnPropertyChanged();
}
}
public ObservableCollection<DataGridEntry> DataGridEntries { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class User : BindableBase
{
private string _firstName;
private string _lastName;
private string _age;
public string Firstname
{
get{ return _firstName;}
set
{
_firstName = value;
OnPropertyChanged(() => Firstname);
}
}
public string LastName
{
get{ return _lastName;}
set
{
_lastName = value;
OnPropertyChanged(() => LastName);
}
}
public string Age
{
get{ return _age;}
set
{
_age = value;
OnPropertyChanged(() => Age);
}
}
}
我有一个绑定用户模型的 EditUserViewModel。在用户模型中,我有 public 属性,例如名字、姓氏、年龄等。
EditUserViewModel
public class EditUserViewModel : BindableBase
{
private User _user;
public EditUserViewModel(User user)
{
SaveCommand = new DelegateCommand(EditUser, CanSaveCommand);
CancelCommand = new DelegateCommand(Cancel);
User = user;
}
public User User
{
get{ return _user; }
set
{
_user = value;
OnPropertyChanged(() => User);
SaveCommand.RaiseCanExecuteChanged();
}
}
public DelegateCommand SaveCommand { get; set; }
public ICommand CancelCommand { get; set; }
public Func<bool> CanSaveCommand { get { return CanEditUser; } }
private void EditUser()
{
Confirmed = true;
FinishInteraction();
}
private bool CanEditUser()
{
if (string.IsNullOrEmpty(_user.Firstname) || _user.Firstname.Length < 3) return false;
if (string.IsNullOrEmpty(_user.Lastname) || _user.Lastname.Length < 3) return false;
return true;
}
}
EditUserView
<UserControl x:Class="UserModule.Views.EditUserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock FontWeight="Bold" Grid.Row="0" Grid.Column="0">First name:</TextBlock>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=User.Firstname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock FontWeight="Bold" Grid.Row="1" Grid.Column="0">First name:</TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=User.Lastname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button x:Name="OkButton" Grid.Row="2" Grid.Column="0" Command="{Binding SaveCommand}" Content="OK"/>
<Button x:Name="CancelButton" Grid.Row="2" Grid.Column="1" Command="{Binding CancelCommand}" Content="Cancel"/>
</Grid>
</UserControl>
用户
public User
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Age { get; set; }
}
但是,当我更改名字或姓氏时,用户 属性 不会触发其 setter。但是,如果我不使用用户 class 属性,而是在 Viewmodel 中使用 Firstname 和 Lastname 字符串属性,那么当我在 GUI 中更改它们的值时,它们的 setters 会被触发。我是否需要做任何特定的事情才能使这个 class 属性 绑定工作?
在 class 中实现 INotifiyPropertyChanged 用户本身应允许通过 ViewModel 进行绑定。
确保用户 Class 实施 INotifyPropertyChanged
public class User : INotifyPropertyChanged
{
private String _firstname;
public String Firstname
{
get
{
return _firstname;
}
set
{
if (_firstname == value)
{
return;
}
_firstname = value;
OnPropertyChanged();
}
}
private String _lastName;
public String LastName
{
get
{
return _lastName;
}
set
{
if (_lastName == value)
{
return;
}
_lastName = value;
OnPropertyChanged();
}
}
public ObservableCollection<DataGridEntry> DataGridEntries { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class User : BindableBase
{
private string _firstName;
private string _lastName;
private string _age;
public string Firstname
{
get{ return _firstName;}
set
{
_firstName = value;
OnPropertyChanged(() => Firstname);
}
}
public string LastName
{
get{ return _lastName;}
set
{
_lastName = value;
OnPropertyChanged(() => LastName);
}
}
public string Age
{
get{ return _age;}
set
{
_age = value;
OnPropertyChanged(() => Age);
}
}
}