MVVM CallerMemberName и магические строки

В новом выпуске С# 5.0 появилось что-то, чтобы избавиться от «магических строк» ​​в реализации INotifyPropertyChanged, например:

OnPropertyChanged("CustomerName");

Теперь можно написать просто:

OnPropertyChanged();

Это возможно из-за CallerMemberName в определении метода:

protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{ ... }

Это гораздо более удобно для рефакторинга, чем способ «магических строк», и быстрее, чем лямбда-выражения, но мне интересно, как мы можем вызывать OnPropertyChanged несколько раз из одного набора средств доступа. Например, если мы хотим что-то вроде этого:

public int Width
{
    get
    {
        return width;
    }
    set
    {
        width = value;
        OnPropertyChanged("Width");
        OnPropertyChanged("Height");
    }
}

Как мы можем сделать это с помощью CallerMemberName и избежать использования «магических строк» ​​и лямбда-выражений?

Мне также интересно, как мы можем избежать использования «магических строк» ​​в информации IDataError:

public string Error
        {
            get;
            private set;
        }

        public string this[string columnName]
        {
            get
            {
                if (columnName == "Name")
                {
                    if (String.IsNullOrWhiteSpace(Name))
                        Error = "Name cannot be null or empty.";
                    else
                        Error = null;
                }

                return Error;
            }
        }

Я новичок в MVVM, поэтому, возможно, я упустил из виду какой-то умный способ справиться с «магическими строками», однако я провел некоторое исследование и ничего не нашел.


person Overpain    schedule 23.02.2013    source источник
comment
Почему вы хотите сказать, что высота изменилась только потому, что изменилась ширина? Вы действительно имели в виду что-то вроде Размера?   -  person Jon Skeet    schedule 23.02.2013
comment
Это просто пример, но иногда одно свойство может зависеть от другого. Например, если ширина всегда равна высоте*2.   -  person Overpain    schedule 23.02.2013


Ответы (3)


Простой ответ заключается в том, что вы не можете этого сделать. Как видно из имени CallerMemberName, оно будет содержать имя вызывающего абонента.
В случаях, когда вы хотите поднять PropertyChanged для другого, отличного от текущего, вам придется использовать один из "старых" способов.

В IDataErrorInfo вы также должны использовать один из этих способов, альтернативы нет.

person Daniel Hilgarth    schedule 23.02.2013

Я знаю, что этот вопрос касается С# 5.0, но если у людей все еще есть вопросы такого рода, пожалуйста, ознакомьтесь с С# 6.0. В C# 6.0 есть отличный способ решить эту проблему. Проверьте имя ключевого слова. Я написал об этом небольшой пост, если кому-то интересно: c# 6.0 решает проблему магических строк

person Danny van der Kraan    schedule 15.05.2015

Это поможет: "Kind Of Magic" без усилий INotifyPropertyChanged

http://visualstudiogallery.msdn.microsoft.com/d5cd6aa1-57a5-4aaa-a2be-969c6db7f88a

в качестве примера добавления его к одному свойству:

[Magic] 
public string Name { get { return _name; } set { _name = value; } } 
string _name;

Другой пример добавления его ко всем свойствам класса:

[Magic] 
public class MyViewModel: INotifyPropertyChanged 
{ 
  public string Name { get; set; } 
  public string LastName { get; set; } 
  ..... 
}
person Reader Man San    schedule 05.11.2013
comment
-1; это может быть хороший инструмент, но я не думаю, что это решение проблемы OP. Если я ошибаюсь, пожалуйста, улучшите свой ответ с некоторыми пояснениями. - person Philipp M; 05.11.2013