Я пытаюсь понять, как обновить пользовательский интерфейс, если у меня есть свойство только для чтения, которое зависит от другого свойства, так что изменения к одному свойству обновите оба элемента пользовательского интерфейса (в данном случае текстовое поле и текстовое поле только для чтения. Например:
public class raz : INotifyPropertyChanged
{
int _foo;
public int foo
{
get
{
return _foo;
}
set
{
_foo = value;
onPropertyChanged(this, "foo");
}
}
public int bar
{
get
{
return foo*foo;
}
}
public raz()
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void onPropertyChanged(object sender, string propertyName)
{
if(this.PropertyChanged != null)
{
PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
}
}
}
Насколько я понимаю, панель не будет автоматически обновлять пользовательский интерфейс при изменении foo. Как правильно это сделать?
Один из способов указать, что bar изменился, это добавить вызов onPropertyChanged(this, "bar")
в установщике foo. Чертовски уродливо, я знаю, но вот оно.
Если foo определен в классе-предке или у вас нет доступа к реализации установщика, я полагаю, вы могли бы подписаться на событие PropertyChanged, чтобы, когда вы видите изменение «foo», вы также могли активировать уведомление об изменении «бара». Подписка на события в вашем собственном экземпляре объекта столь же уродлива, но выполнит свою работу.
Вы можете просто позвонить
OnPropertyChanged(this, "bar");
из любого места в этом классе... Вы можете даже так:
public raz()
{
this.PropertyChanged += new PropertyChangedEventHandler(raz_PropertyChanged);
}
void raz_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "foo")
{
onPropertyChanged(this, "bar");
}
}
Если вы используете полосу только для пользовательского интерфейса, вы можете полностью удалить ее из своей модели. Вы можете привязать элемент пользовательского интерфейса к свойству foo и использовать специальный преобразователь значений, чтобы изменить результат с foo на foo*foo.
В WPF часто есть много способов сделать одно и то же. Часто нет правильного пути, просто личное предпочтение.
В зависимости от стоимости расчета и частоты ожидать, что он будет использоваться, может быть полезно сделать его частным набором свойств и вычислять значение, когда установлено foo
, а не вычислять на лету, когда вызывается bar
get . Это в основном решение для кэширования, а затем вы можете сделать уведомление об изменении свойства как часть частного сеттера bar
. Обычно я предпочитаю этот подход, главным образом потому, что я использую АОП (через Postsharp) для реализации фактического шаблона INotifyPropertyChanged
.
-Дэн