10 September 2010

OnPropertyChanged со строгими именами

.NET
Меня дико бесит OnPropertyChanged. Он требует передачи ему строки с именем идентификатора… Мало того, что такой код не верифицируется компилятором, так еще и никакого Intellisence — тайпи весь идентификатор от начала до конца… А если опечатаешся — так проглотит и во время выполнения. Вобщем, нехорошая вещь. Но в MVVM без нее никуда, как и в WPF без MVVM.

Последняя проблема худо-бедно решалась вот таким костылем, содранным отсюда, который вызывался из OnPropertyChanged:
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;

if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
}


И вот сегодня я совершенно случайно нашел красивый способ избавится от него.

Решение оказалось красивым и одновременно простым до банальности: использовать Expression, вот так:
this.OnPropertyChanged(() => this.ShowOverrideButton);

Для этого нужно только создать в базовом классе перегрузку:
protected void OnPropertyChanged<T>(Expression<Func<T>> property)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var expression = property.Body as MemberExpression;
if (expression == null)
{
throw new NotSupportedException("Invalid expression passed. Only property member should be selected.");
}

handler(this, new PropertyChangedEventArgs(expression.Member.Name));
}
}


* This source code was highlighted with Source Code Highlighter.

Готово. Можете забыть о строках в OnPropertyChange. Остаются еще нехорошие строки в XAML в Binding — но у меня совершенно нет идей как от них избавится.
Tags:WPFMVVMonpropertychange
Hubs: .NET
+13
3.7k 22
Comments 23
Popular right now