所以这是一个使我陷入困境的问题。我正在使用一个嵌入式类结构,该结构需要保持其子对象私有,但应该能够从这些子对象中的数据向上传递某些NotifyOfPropertyChange事件。做这个的最好方式是什么。
[我当前的方法是下面的代码,其中我的SystemViewModel(SystemView)视图具有绑定到CommunicationStatus
属性的元素,并且我有一个父类SystemViewModel,它的子类CommunicationManager带有子类Communicator,如下所示。
困难的事情:
1]在这种情况下,必须假定Communicator没有SystemViewModel的可见性,因此不应将Communicator的NotifyOfPropertyChanged(() => CommunicationStatus)
属性的set
方法中放置Connected
作为选择...除非我缺少某些内容很明显。
2)SystemViewModel应该不能直接访问Communicator,因此无法完成从SystemView.xaml
到Connected
的绑定。
[在我看来,由于在所有类中都实现了Connected
,因此PropertyChangedBase
中的NotifyOfPropertyChanged事件应该冒充父级,但这并没有发生。希望有帮助!
public class SystemViewModel : PropertyChangedBase
{
private CommunicationManager CommunicationManager;
public string CommunicationStatus
{
get
{
if (CommunicationManager.YepConnected)
{
return "Green";
}
else
{
return "Red";
}
}
}
}
public class CommunicationManager : PropertyChangedBase
{
private Communicator Communicator;
public bool YepConnected { get { return Communicator.Connected; } }
}
public class Communicator: PropertyChangedBase
{
private bool _connected;
public bool Connected
{
get { return _connected; }
set
{
_connected = value;
NotifyOfPropertyChange(() => Connected);
}
}
}
这是一个如何使用ReactiveUI进行操作的示例
public class SystemViewModel : ReactiveObject
{
private readonly CommunicationManager communicationManager;
private readonly ObservableAsPropertyHelper<string> connectionStatus;
public SystemViewModel( CommunicationManager communicationManager )
{
this.communicationManager = communicationManager ?? throw new ArgumentNullException(nameof(communicationManager));
this.communicationManager
.WhenAnyValue( e => e.YepConnected, state => state ? "Green" : "Red" )
.ToProperty( this, e => e.ConnectionStatus, out connectionStatus );
}
public string ConnectionStatus => connectionStatus.Value;
}
public class CommunicationManager : ReactiveObject
{
private readonly Communicator communicator;
private readonly ObservableAsPropertyHelper<bool> yepConnected;
public CommunicationManager(Communicator communicator)
{
this.communicator = communicator ?? throw new ArgumentNullException(nameof(communicator));
this.communicator
.WhenAnyValue( e => e.Connected )
.ToProperty( this, e => e.YepConnected, out yepConnected );
}
public bool YepConnected => yepConnected.Value;
}
public class Communicator : ReactiveObject
{
private bool _connected;
public bool Connected
{
get { return _connected; }
set { this.RaiseAndSetIfChanged( ref _connected, value); }
}
}
简单测试
var communicator = new Communicator();
var manager = new CommunicationManager(communicator);
var vm = new SystemViewModel( manager );
vm.PropertyChanged += (s,e) => Console.WriteLine( "SystemViewModel.{0} changed", e.PropertyName );
communicator.Connected = true;
communicator.Connected = false;
生成的输出
SystemViewModel.ConnectionStatus已更改SystemViewModel.ConnectionStatus已更改