参考问题:(Is there a pattern for subscribing to hierarchical property changes with Reactive UI?)
我目前在我的父级反应对象中有一个反应对象。
public class Child : ReactiveObject
{
private string propertyX
public string PropertyX
{
get { return this.propertyX; }
set { this.RaiseAndSetIfChanged(x => x.PropertyX, ref this.propertyX, value); }
}
private string propertyY
public string PropertyY
{
get { return this.propertyY; }
set { this.RaiseAndSetIfChanged(x => x.PropertyY, ref this.propertyY, value); }
}
}
public class Parent: ReactiveObject
{
public Parent(Child child)
{
Child = child;
this.WhenAny(x => x.Child.PropertyX, x => x.Value).Subscribe(x => raisePropertyChanged("Child"));
}
private Child child
public Child Child
{
get { return this.child; }
set { this.RaiseAndSetIfChanged(x => x.Child, ref this.child, value); }
}
}
我的问题是我必须写:
this.WhenAny(x => x.Child.PropertyX, x => x.Value).Subscribe(x => raisePropertyChanged("Child"));
每个儿童财产?
我需要这样做的原因是因为嵌套属性绑定我的DevExpress网格不会更新。
<dxg:GridColumn x:Key="PropertyX" Header="PropertyX" FieldName="Child.PropertyX" />
答案 0 :(得分:1)
所以,这有点像黑客,但你可以随时“转发”一个属性:
this.WhenAny(x => x.Child.PropertyX, x => x.Value).ToProperty(this, x => x.PropertyXFromChild, out propertyXFromChild);
答案 1 :(得分:0)
您可以尝试使用表达式树。这对我有用,直到(我认为)最近RxUI6发生了变化。目前它适用于某些房产类型。
void Main()
{
var o1 = new ReactivePerson();
foreach (var element in Functions.GetProperties<ReactivePerson>())
{
o1.ObservableForProperty(element).Subscribe(x=>string.Format("property: {0} is changing to {1}", x.GetPropertyName(), x.Value).Dump()); // note that the Dump() method is for LinqPad (http://www.linqpad.net/). Use console.log or similar if needed.
}
// Both properties registered
o1.FirstName = "Jenny";
o1.FirstName = "Peter";
o1.FirstName = "Dave";
o1.LastName = "Peterson";
o1.LastName = "Jones";
o1.LastName = "Smith";
}
public static class Functions{
public static IList<Expression<Func<T,object>>> GetProperties<T>()
{
var result = new List<Expression<Func<T,object>>>();
var properties = typeof(T).GetProperties().Where(pi => pi.GetCustomAttributes(typeof(DataMemberAttribute), false).Any());
foreach (var property in properties)
{
var p = Expression.Parameter(typeof(T), "p");
//var prop = Expression.Convert(Expression.Property(p, property), typeof(Object));
// Note I think that you should use the expression.convert line, which allows you to handle Int32s etc. However, I 'think' that there's a but in RxUI6 which is blocking it. https://github.com/reactiveui/ReactiveUI/issues/659
var prop = Expression.Property(p, property); // try this instead
var keySelector = Expression.Lambda<Func<T, object>>(prop, p);
result.Add(keySelector);
}
return result;
}
}
public class ReactivePerson : ReactiveObject
{
[IgnoreDataMember]
string _firstName;
[DataMember]
public string FirstName{
get { return _firstName; }
set { this.RaiseAndSetIfChanged(ref _firstName, value); }
}
[IgnoreDataMember]
string _lastName;
[DataMember]
public string LastName{
get { return _lastName; }
set { this.RaiseAndSetIfChanged(ref _lastName, value); }
}
// int not working, see comment in Functions.GetProperties.
// [IgnoreDataMember]
// int _age;
// [DataMember]
// public int Age{
// get { return _age; }
// set { this.RaiseAndSetIfChanged(ref _age, value); }
// }
}