Автоматическое уведомление об изменении свойства с INotifyPropertyChanged? - PullRequest
1 голос
/ 02 ноября 2011

Я работал над LOB-приложением silverlight,

В моих моделях представлений у меня есть до 30 свойств, которые должны уведомлять пользовательский интерфейс при их изменении.

Моя база ViewModelкласс реализует INotifyPropertyChanged и имеет метод-оболочку с именем OnPropertyChanged(string propName)

Это все еще невероятно утомительно, так как во всех моих сеттерах я должен вызывать это.

Я бы хотел иметь возможность его иметьавтоматически срабатывать по определенным свойствам / всем членам украшенного класса.

Возможно ли это?


Спасибо за решения для всех .. Я думаю, что аспектная ориентация может быть наиболее кратким решениемдля этой проблемы .. Я думаю, что это приведет к большому исходу от нормы Silverlight / RIA / EF / MVVM к гораздо более простому, более лаконичному подходу ..


Да, чтобы сделать этоВопрос, максимально полезный для других, для которого я собираюсь использовать AOP-фреймворк: PostSharp , и у них есть руководство по достижению именно этого:

http://www.sharpcrafters.com/solutions/notifypropertychanged

Ответы [ 3 ]

1 голос
/ 02 ноября 2011

Нет хорошего способа уменьшить количество необходимого кода. Однако единственное, что изменяется в каждой конструкции свойства, это ее имя и тип. Следовательно, это хороший кандидат на фрагмент. Вот пример фрагмента: -

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Notify Property</Title>
      <Shortcut>np</Shortcut>
      <Description>Code snippet for a property that calls the INotifyPropertyChange event</Description>
      <Author>Coding Bloke</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>property</ID>
          <ToolTip>Property name</ToolTip>
          <Default>MyProperty</Default>
        </Literal>
        <Literal>
          <ID>type</ID>
          <ToolTip>Property type</ToolTip>
          <Default>string</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[private $type$ _$property$;
        public $type$ $property$
        {
            get { return _$property$; }
            set
            {
                _$property$ = value;
                OnPropertyChanged("$property$");
            }
        }
]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Сохранить выше как

"Мои документы \ Visual Studio 2010 \ Фрагменты кода \ Visual C # \ Фрагменты моего кода \ np.snippet"

Теперь вы можете просто набрать "np" в редакторе кода, дважды нажать клавишу tab, и появится этот фрагмент. Введите имя типа, дважды нажмите вкладку, введите имя свойства, нажмите ввод, и все готово.

0 голосов
/ 04 ноября 2011

Обычно я пишу свой собственный вспомогательный метод, чтобы в моих свойствах могли быть однострочные геттеры и сеттеры.Это устраняет большую часть боли:

public string Name {
    get { return _name; }
    set { SetProperty(ref _name, value, () => Name); }
}
public int Value {
    get { return _value; }
    set { SetProperty(ref _value, value, () => Value); }
}

Реализация моего метода SetProperty будет варьироваться в зависимости от того, использую ли я фреймворк, такой как Prism или Caliburn.Micro, нужно ли какой-либо из моих моделей представления делать дополнительныепользовательская работа при изменении свойства и т. д. Вот простая реализация, использующая PropertyChangedBase Caliburn.Micro:

public class Observable : PropertyChangedBase
{
    protected void SetProperty<T>(ref T backingField, T newValue,
        Expression<Func<T>> property)
    {
        if (Equals(backingField, newValue))
            return;
        backingField = newValue;
        NotifyOfPropertyChange(property);
    }
}
0 голосов
/ 03 ноября 2011

Конечно, это возможно с АОП.

что-то вроде

[Notify]
public string PropertyName{get; set;} 

можно преобразовать в желаемый результат с помощью инструмента АОП

Вы также можете применить атрибут типа Notify ко всему классу viewmodel и сделать каждый вызов общего свойства NotifyPropertyChanged

В Google есть много результатов по "AOP and NotifyPropertyChanged", но я укажу первую статью, которую я нашел по этой теме: http://sachabarber.net/?p=849

...