Помощь с выражением Linq - INotifyPropertyChanged - PullRequest
0 голосов
/ 13 июня 2010

Я читаю исходный код из последней версии Prism 4 и заинтересован в решении этой проблемы. Существует базовый класс для ViewModels, который реализует INotifyPropertyChanged и INotifyDataErrorInfo и предоставляет некоторое реорганизованное уведомление о внесении изменений

protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
{
    var propertyName = ExtractPropertyName(propertyExpresssion);
    this.RaisePropertyChanged(propertyName);
}



private string ExtractPropertyName<T>(Expression<Func<T>> propertyExpresssion)
{
    if (propertyExpresssion == null)
    {
        throw new ArgumentNullException("propertyExpression");
    }

    var memberExpression = propertyExpresssion.Body as MemberExpression;
    if (memberExpression == null)
    {
        throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
    }

    var property = memberExpression.Member as PropertyInfo;
    if (property == null)
    {
        throw new ArgumentException("The member access expression does not access  property.","propertyExpression");
    }

    if (!property.DeclaringType.IsAssignableFrom(this.GetType()))
    {
       throw new ArgumentException("The referenced property belongs to a different type.", "propertyExpression");
    }

    var getMethod = property.GetGetMethod(true);
    if (getMethod == null)
    {
        // this shouldn't happen - the expression would reject the property before reaching this far
        throw new ArgumentException("The referenced property does not have a get method.", "propertyExpression");
    }

    if (getMethod.IsStatic)
    {
        throw new ArgumentException("The referenced property is a static property.", "propertyExpression");
    }

    return memberExpression.Member.Name;
    }

и как пример его использования

private void RetrieveNewQuestionnaire()
{
    this.Questions.Clear();

    var template = this.questionnaireService.GetQuestionnaireTemplate();
    this.questionnaire = new Questionnaire(template);

    foreach (var question in this.questionnaire.Questions)
    {
      this.Questions.Add(this.CreateQuestionViewModel(question));
    }

    this.RaisePropertyChanged(() => this.Name);
    this.RaisePropertyChanged(() => this.UnansweredQuestions);
    this.RaisePropertyChanged(() => this.TotalQuestions);
    this.RaisePropertyChanged(() => this.CanSubmit);
}

Мой вопрос такой. Что нужно сделать, чтобы передать массив имен свойств перегруженному методу (RaisePropertyChanged) и сжать этот последний бит кода с 4 строк до 1?

Спасибо, Стивен

1 Ответ

5 голосов
/ 13 июня 2010

Рассматривали ли вы изменение:

protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
{
    var propertyName = ExtractPropertyName(propertyExpresssion);
    this.RaisePropertyChanged(propertyName);
}

до:

protected void RaisePropertyChanged<T>(params Expression<Func<T>>[] propertyExpresssion)
{
    foreach (var propertyName in 
         propertyExpresssion.Select(ExtractPropertyName))
    {
        this.RaisePropertyChanged(propertyName);
    }
}

и использование:

private void RetrieveNewQuestionnaire()
{
      //yada yada yada
      this.RaisePropertyChanged(() => this.Name, 
                                () => this.UnansweredQuestions, 
                                () => this.TotalQuestions);
}

Может быть, кто-то считает это плохой практикой, но, по крайней мере, сделайте свое дело. Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...