Добрый день, пользовался VS2016. Сейчас решил перейти на версию 2013, открыл проект на 2013 версии, мне начало выдавать ошибки при работе с INotifyPropertyChanged:
PropertyChanged(this, new PropertyChangedEventArgs(nameof(SelectedItemInListView)));
Ругается на nameof:
Error 1 The name 'nameof' does not exist in the current context D:\WpfApplication7\WpfApplication7\CreateGroup.xaml.cs 47 68 WpfApplication7
В чем может быть проблема? Версию .NET установил так же как и на прошлой студии (4.6.1)
Свойство целиком:
public Item SelectedItemInListBox
{
get { return _SelectedItemInListBox; }
set
{
_SelectedItemInListBox = value;
//сообщаем о том, что элемент изменился
PropertyChanged(this, new PropertyChangedEventArgs(nameof(SelectedItemInListBox)));
}
}
nameof
это фича C#6. Visual Studio 2013 поддерживает версии до C#5 включительно. Компилятор просто не понимает, что это за слово.
В дополнение к ответу @Ruslan Artamonov, в C# 5 имеет смысл использовать такую магию:
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
Имея этот метод в вашем классе (или его базовом классе), вы можете писать просто
public Item SelectedItemInListBox
{
get { return _SelectedItemInListBox; }
set { _SelectedItemInListBox = value; RaisePropertyChanged(); }
}
или лучше
public Item SelectedItemInListBox
{
get { return _SelectedItemInListBox; }
set
{
if (_SelectedItemInListBox == value)
return;
_SelectedItemInListBox = value;
RaisePropertyChanged();
}
}
Таким образом вам не нужно упоминать точное имя свойства вовсе, оно установится самостоятельно через магию [CallerMemberName]
.
Возможно, имеет смысл ещё сократить ваш код, и создать общий базовый класс для всех VM-классов:
class VM : INotifyPropertyChanged
{
protected bool Set<T>(ref T field, T value,
[CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;
field = value;
RaisePropertyChanged(propertyName);
return true;
}
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Имея такой базовый класс, вы можете писать так:
class MyListVM : VM
{
Item _SelectedItemInListBox;
public Item SelectedItemInListBox
{
get { return _SelectedItemInListBox; }
set { Set(ref _SelectedItemInListBox, value); }
}
}
Кстати, для C# 6 (Visual Studio 2015 и старше) можно использовать тот же трюк с более компактной записью:
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Начиная с 3 версии C# можно использовать также и Expressions
protected void OnPropertyChanged<T>(Expression<Func<T>> expr)
{
var member = (MemberExpression)expr.Body;
var handler = Volatile.Read(ref PropertyChanged);
if (handler != null)
handler(this, new PropertyChangedEventArgs(member.Member.Name));
}
Добрый день, подскажите как обновить табличку по клику на кнопку:
Здравствуйте, только начала изучать C#, столкнулся с такой проблемой