csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.4 KiB
102 lines
2.4 KiB
// Copyright (c) The Perspex Project. All rights reserved.
|
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|
|
|
using System;
|
|
using System.Reactive.Subjects;
|
|
|
|
namespace Perspex.Markup.Binding
|
|
{
|
|
internal abstract class ExpressionNode : IObservable<ExpressionValue>
|
|
{
|
|
private object _target;
|
|
|
|
private Subject<ExpressionValue> _subject;
|
|
|
|
private ExpressionValue _value = ExpressionValue.None;
|
|
|
|
public ExpressionNode Next
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public object Target
|
|
{
|
|
get { return _target; }
|
|
set
|
|
{
|
|
if (_target != null)
|
|
{
|
|
Unsubscribe(_target);
|
|
}
|
|
|
|
_target = value;
|
|
|
|
if (_target != null)
|
|
{
|
|
SubscribeAndUpdate(_target);
|
|
}
|
|
else
|
|
{
|
|
CurrentValue = ExpressionValue.None;
|
|
}
|
|
|
|
if (Next != null)
|
|
{
|
|
Next.Target = CurrentValue.Value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public ExpressionValue CurrentValue
|
|
{
|
|
get
|
|
{
|
|
return _value;
|
|
}
|
|
|
|
set
|
|
{
|
|
_value = value;
|
|
|
|
if (Next != null)
|
|
{
|
|
Next.Target = value.Value;
|
|
}
|
|
|
|
if (_subject != null)
|
|
{
|
|
_subject.OnNext(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual bool SetValue(object value)
|
|
{
|
|
return Next?.SetValue(value) ?? false;
|
|
}
|
|
|
|
public IDisposable Subscribe(IObserver<ExpressionValue> observer)
|
|
{
|
|
if (Next != null)
|
|
{
|
|
return Next.Subscribe(observer);
|
|
}
|
|
else
|
|
{
|
|
if (_subject == null)
|
|
{
|
|
_subject = new Subject<ExpressionValue>();
|
|
}
|
|
|
|
observer.OnNext(CurrentValue);
|
|
return _subject.Subscribe(observer);
|
|
}
|
|
}
|
|
|
|
protected abstract void SubscribeAndUpdate(object target);
|
|
|
|
protected abstract void Unsubscribe(object target);
|
|
|
|
}
|
|
}
|
|
|