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.
56 lines
2.0 KiB
56 lines
2.0 KiB
using System;
|
|
using System.Reactive.Disposables;
|
|
using Avalonia.Utilities;
|
|
|
|
namespace Avalonia.Controls
|
|
{
|
|
public class NameScopeLocator
|
|
{
|
|
/// <summary>
|
|
/// Tracks a named control relative to another control.
|
|
/// </summary>
|
|
/// <param name="scope">The scope relative from which the object should be resolved.</param>
|
|
/// <param name="name">The name of the object to find.</param>
|
|
public static IObservable<object> Track(INameScope scope, string name)
|
|
{
|
|
return new NeverEndingSynchronousCompletionAsyncResultObservable<object>(scope.FindAsync(name));
|
|
}
|
|
|
|
// This class is implemented in such weird way because for some reason
|
|
// our binding system doesn't expect OnCompleted to be ever called and
|
|
// seems to treat it as binding cancellation or something
|
|
|
|
private class NeverEndingSynchronousCompletionAsyncResultObservable<T> : IObservable<T>
|
|
{
|
|
private T _value;
|
|
private SynchronousCompletionAsyncResult<T>? _asyncResult;
|
|
|
|
public NeverEndingSynchronousCompletionAsyncResultObservable(SynchronousCompletionAsyncResult<T> task)
|
|
{
|
|
if (task.IsCompleted)
|
|
_value = task.GetResult();
|
|
else
|
|
_asyncResult = task;
|
|
}
|
|
|
|
public IDisposable Subscribe(IObserver<T> observer)
|
|
{
|
|
if (_asyncResult?.IsCompleted == true)
|
|
{
|
|
_value = _asyncResult.Value.GetResult();
|
|
_asyncResult = null;
|
|
}
|
|
|
|
if (_asyncResult != null)
|
|
_asyncResult.Value.OnCompleted(() =>
|
|
{
|
|
observer.OnNext(_asyncResult.Value.GetResult());
|
|
});
|
|
else
|
|
observer.OnNext(_value);
|
|
|
|
return Disposable.Empty;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|