我正在开发一个C# WPF项目。在View端,名为NewBook的属性绑定到ViewModel端的文本框。但是,我在这个属性的setter中所做的更改并没有反映在视图端。当文本框失去键盘焦点时,我想用ConverToTitle方法将字符串表达式大写。但我想通过NewBook来实现这一点,而不是通过定义单个属性。我的错误在哪里,我如何才能做到这一点?谢谢.
internal class NewBookViewModel : ObservableObject
{
LibraryDataContext Db;
public RelayCommand SaveCommand { get; private set; }
public RelayCommand CloseWindowCommand { get; }
private Book _newBook;
public Book NewBook
{
get { return _newBook; }
set
{
SetProperty(ref _newBook, value);
NewBook.ConvertToTitle();
}
}
private int _demirbasNo;
public int DemirbasNo
{
get { return _demirbasNo; }
set
{
SetProperty(ref _demirbasNo, value);
NewBook.Barkod = Barcode.GenerateEAN13BarcodeNumber(_demirbasNo);
NewBook.DemirbasNo = _demirbasNo;
}
}
private Author Author;
private Yayinevi publisher;
public ObservableCollection<Book> BooklarCollection { get; set; }
public NewBookViewModel()
{
SaveCommand = new RelayCommand(SaveExecute, CanExecuteSaveCommand);
CloseWindowCommand = new RelayCommand(CloseExecute);
Db = new LibraryDataContext();
NewBook = new Book();
DemirbasNo= BookService.NextDemirbaşNo();
NewBook.Barkod = Barcode.GenerateEAN13BarcodeNumber(_demirbasNo);
}
private bool CanExecuteSaveCommand() => true;
private void SaveExecute()
{
BookValidator validator= new BookValidator();
ValidationHelper<Book> validationHelper = new ValidationHelper<Book>(validator);
MessagePublisher.SendMessage(validationHelper.ErrorMessage(NewBook),MessageType.Error);
/* AuthorCheck(newBook.Authori.AdiSoyadi);
PublisherCheck(newBook.Yayinevi.Adi);
BookService<Book> BookService = new BookService<Book>();
BookService.Add(newBook);
BookService.SaveChanges();
CloseExecute(); */
}
private void CloseExecute()
{
var activeWindow = Application.Current.Windows.OfType<BaseWindow>().SingleOrDefault(w => w.IsActive);
if (activeWindow != null)
{
activeWindow.Close();
}
}
}
public static void ConvertToTitle<t>(this t obj)
{
PropertyInfo[] propertyInfo = typeof(t).GetProperties();
foreach (var property in propertyInfo)
{
if (property.PropertyType == typeof(string))
{
string value = (string)property.GetValue(obj);
if (!string.IsNullOrEmpty(value))
{
property.SetValue(obj, CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value));
}
}
}
}
}
internal class NewBookViewModel : ObservableObject
{
LibraryDataContext Db;
public RelayCommand SaveCommand { get; private set; }
public RelayCommand CloseWindowCommand { get; }
private Book _newBook;
public Book NewBook
{
get { return _newBook; }
set
{
SetProperty(ref _newBook, value);
NewBook.ConvertToTitle();
}
}
private int _demirbasNo;
public int DemirbasNo
{
get { return _demirbasNo; }
set
{
SetProperty(ref _demirbasNo, value);
NewBook.Barkod = Barcode.GenerateEAN13BarcodeNumber(_demirbasNo);
NewBook.DemirbasNo = _demirbasNo;
}
}
private Author Author;
private Yayinevi publisher;
public ObservableCollection<Book> BooklarCollection { get; set; }
public NewBookViewModel()
{
SaveCommand = new RelayCommand(SaveExecute, CanExecuteSaveCommand);
CloseWindowCommand = new RelayCommand(CloseExecute);
Db = new LibraryDataContext();
NewBook = new Book();
DemirbasNo= BookService.NextDemirbaşNo();
NewBook.Barkod = Barcode.GenerateEAN13BarcodeNumber(_demirbasNo);
}
private bool CanExecuteSaveCommand() => true;
private void SaveExecute()
{
BookValidator validator= new BookValidator();
ValidationHelper<Book> validationHelper = new ValidationHelper<Book>(validator);
MessagePublisher.SendMessage(validationHelper.ErrorMessage(NewBook),MessageType.Error);
/* AuthorCheck(newBook.Authori.AdiSoyadi);
PublisherCheck(newBook.Yayinevi.Adi);
BookService<Book> BookService = new BookService<Book>();
BookService.Add(newBook);
BookService.SaveChanges();
CloseExecute(); */
}
private voidCloseExecute()
{
var activeWindow = Application.Current.Windows.OfType<BaseWindow>().SingleOrDefault(w => w.IsActive);
if (activeWindow != null)
{
activeWindow.Close();
}
}
}
public static void ConvertToTitle<t>(this t obj)
{
PropertyInfo[] propertyInfo = typeof(t).GetProperties();
foreach (var property in propertyInfo)
{
if (property.PropertyType == typeof(string))
{
string value = (string)property.GetValue(obj);
if (!string.IsNullOrEmpty(value))
{
property.SetValue(obj, CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value));
}
}
}
}
}
2条答案
按热度按时间jutyujz01#
你需要你的类继承
INotifyPropertyChanged
并在setter中调用PropertyChanged
事件。类似下面的东西:enxuqcxy2#
必须为已更改的属性引发
INotifyPropertyChanged.PropertyChanged
事件,才能更新数据绑定。首先,确保您的数据源(在本例中为
Book
)实现了INotifyPropertyChanged
。第二,在修改属性后立即引发事件:
备注
object
类型编写扩展方法,因为这会使API和代码建议列表变得混乱。因为 * 每个 * .NET类型都继承自object
,所以所有对象都可以访问它,即使它没有意义。在此上下文中,泛型类型参数也是多余的,因此此方法不能是泛型方法。考虑使用更严格的类型,例如以
INotifyPropertyChanged
开头。因为我们需要引发INotifyPropertyChanged.PropertyChanged
事件,所以INotifyPropertyChanged
是使代码工作所需的最小类型约束: