2016-09-09 2 views
0

Я хочу упростить объявления свойств в моих классах. Проблема заключается в определении геттера и сеттера. Я делаю то же самое для сотен свойств. Все свойства создаются именно так, где метод «LogPropertyChanged» также RaisePropertyChange.Упростить объекты mvvm WPF

public class PCS_MA_V1_ALARMSTAT : ViewModelBase 
{ 
    private Boolean _ActionAlarmHighHigh; 
    public Boolean ActionAlarmHighHigh 
    { 
     get 
     { 
      return _ActionAlarmHighHigh; 
     } 
     set 
     { 
      if(value!= _ActionAlarmHighHigh) 
      { 
       _ActionAlarmHighHigh = value; 
       LogpropertyChanged("ActionAlarmHighHigh", oldVal, newVal); 
      } 

     } 
    } 
    private Boolean _ActionAlarmLowLow; 
    public Boolean ActionAlarmLowLow 
    { 
     get 
     { 
      return _ActionAlarmLowLow; 
     } 
     set 
     { 
      if(value!= _ActionAlarmLowLow) 
      { 
       _ActionAlarmLowLow = value; 
       LogpropertyChanged("ActionAlarmLowLow", oldVal, newVal); 
      } 

     } 
    } 
} 

Теперь я думаю, что этот синтаксис очень сложный, и огромный хайл для работы. Есть ли способ, которым я мог бы создать такой класс:

public class PCS_MA_V1_ALARMSTAT: ViewModelBase 
{ 
    public Boolean ActionAlarmHighHigh { get; set; } 
    public Boolean ActionAlarmLowLow { get; set; } 
} 

И затем следить за экземпляром. Если свойство изменилось, я запустил LogPropertyChanged в этом конкретном свойстве. Это возможно?

+2

Ты второй, кто задал этот вопрос сегодня. Ответ «нет» для вас тоже. То, что люди делают * здесь, записывает 'SetProperty (ref T свойствоField, [CallerMemberName] String propName = null)' метод, который устанавливает поле и вызывает значение «PropertyChanged», если значение изменилось, и оно также может регистрироваться. Кстати, я бы, по крайней мере, переименовал 'LogpropertyChanged' в то, что не означает, что он MERELY делает запись. Неплохая идея для метода, но очень вводящее в заблуждение имя. –

+0

И затем [написать фрагмент] (https://swissarmycrowbar.wordpress.com/2016/07/19/viewmodel-property-snippets-c6/), чтобы создать определения свойств, если вы используете Visual Studio. –

+0

@EdPlunkett У меня уже создана программа, которая генерирует эти классы. Он создает тысячи строк. Проблема в том, что теперь я должен также поддерживать это приложение ...;) Если у вас есть время, я бы много ответил на ваш ответ в коде. Я не уверен, как реализовать его с вами. – Snovva1

ответ

0

К сожалению, вы не можете переопределить поведение по умолчанию get и set.

Что вы можете сделать, это написать ViewModelBase вот так. Это обычная идиома. Мой код ниже в основном украден from this answer, а у Призма BindableBase есть a similar SetProperty<T> method, но я не искал их реализации. Там не может быть так много.

using System; 
using System.ComponentModel; 
using System.Runtime.CompilerServices; 

namespace HollowEarth.MVVM 
{ 
    public class ViewModelBase : INotifyPropertyChanged 
    { 
     #region SetProperty 
     protected virtual bool SetProperty<T>(ref T backingField, 
      T newValue, 
      [CallerMemberName] String propName = null) 
     { 
      if (EqualityComparer<T>.Default.Equals(backingField, newValue)) 
      { 
#if DEBUG 
       System.Diagnostics.Trace.WriteLine(
        $"No change in {propName} == {backingField}"); 
#endif 
       return false; 
      } 

#if DEBUG 
      System.Diagnostics.Trace.WriteLine(
       $"Changing {propName} from {backingField} to {newValue}"); 
#endif 

      backingField = newValue; 
      OnPropertyChanged(propName); 

      return true; 
     } 
     #endregion SetProperty 

     #region INotifyPropertyChanged 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(
      [CallerMemberName] String propName = null) 
     { 
      PropertyChanged?.Invoke(this, 
       new PropertyChangedEventArgs(propName)); 
     } 
     #endregion INotifyPropertyChanged 
    } 
} 

И использовать его так:

public class MyViewModel : ViewModelBase 
{ 
    #region Whenever Property 
    private DateTime? _whenever = default(DateTime?); 
    public DateTime? Whenever 
    { 
     get { return _whenever; } 
     set { SetProperty(ref _whenever, value); } 
    } 
    #endregion Whenever Property 
} 

Я пишу Visual Studio snippets для генерации свойств. Вы сказали, что программно генерируете все это, так что фрагменты не являются неотъемлемым требованием, но это нужно иметь в виду.

Другая возможность, если сопровождение сгенерированного кода является проблемой, использовать частичные классы. Поместите сгенерированный код в отдельные файлы, которые никогда не редактируются вручную (так же, как Form1.Designer.cs/Form1.resx в winforms), и сохраняйте файлы , которые используются для создания этих файлов. Настройте свой генератор как действие сборки для любых ваших входных файлов.

Для метауровневой остроты на предмет ремонтопригодности напишите генератор частичного класса в Perl.