Пример #1
0
        /// <summary>
        /// Tracks a named control relative to another control.
        /// </summary>
        /// <param name="relativeTo">
        /// The control relative from which the other control should be found.
        /// </param>
        /// <param name="name">The name of the control to find.</param>
        public static IObservable <ILogical> Track(ILogical relativeTo, string name)
        {
            var attached = Observable.FromEventPattern <LogicalTreeAttachmentEventArgs>(
                x => relativeTo.AttachedToLogicalTree += x,
                x => relativeTo.AttachedToLogicalTree -= x)
                           .Select(x => ((ILogical)x.Sender).FindNameScope())
                           .StartWith(relativeTo.FindNameScope());

            var detached = Observable.FromEventPattern <LogicalTreeAttachmentEventArgs>(
                x => relativeTo.DetachedFromLogicalTree += x,
                x => relativeTo.DetachedFromLogicalTree -= x)
                           .Select(x => (INameScope)null);

            return(attached.Merge(detached).Select(nameScope =>
            {
                if (nameScope != null)
                {
                    var registered = Observable.FromEventPattern <NameScopeEventArgs>(
                        x => nameScope.Registered += x,
                        x => nameScope.Registered -= x)
                                     .Where(x => x.EventArgs.Name == name)
                                     .Select(x => x.EventArgs.Element)
                                     .OfType <ILogical>();
                    var unregistered = Observable.FromEventPattern <NameScopeEventArgs>(
                        x => nameScope.Unregistered += x,
                        x => nameScope.Unregistered -= x)
                                       .Where(x => x.EventArgs.Name == name)
                                       .Select(_ => (ILogical)null);
                    return registered
                    .StartWith(nameScope.Find <ILogical>(name))
                    .Merge(unregistered);
                }
                else
                {
                    return Observable.Return <ILogical>(null);
                }
            }).Switch());
        }