public static void OnControlTemplateChanged(BindableObject bindable, object oldValue, object newValue) { var self = (IControlTemplated)bindable; // First make sure any old ContentPresenters are no longer bound up. This MUST be // done before we attempt to make the new template. if (oldValue != null) { var queue = new FormsQueue <Element>(16); queue.Enqueue((Element)self); while (queue.Count > 0) { ReadOnlyCollection <Element> children = queue.Dequeue().LogicalChildrenInternal; for (var i = 0; i < children.Count; i++) { Element child = children[i]; var controlTemplated = child as IControlTemplated; var presenter = child as ContentPresenter; if (presenter != null) { presenter.Clear(); } else if (controlTemplated == null || controlTemplated.ControlTemplate == null) { queue.Enqueue(child); } } } } // Now remove all remnants of any other children just to be sure while (self.InternalChildren.Count > 0) { self.InternalChildren.RemoveAt(self.InternalChildren.Count - 1); } ControlTemplate template = self.ControlTemplate; if (template == null) { // do nothing for now } else { var content = template.CreateContent() as View; if (content == null) { throw new NotSupportedException("ControlTemplate must return a type derived from View."); } self.InternalChildren.Add(content); var controlTemplated = (IControlTemplated)bindable; controlTemplated.OnControlTemplateChanged((ControlTemplate)oldValue, (ControlTemplate)newValue); controlTemplated.TemplateRoot = content; controlTemplated.OnApplyTemplate(); } }
public Task WaitAsync(CancellationToken token) { lock (_waiters) { if (_currentCount > 0) { --_currentCount; return(Completed); } var waiter = new TaskCompletionSource <bool>(); _waiters.Enqueue(waiter); token.Register(() => waiter.TrySetCanceled()); return(waiter.Task); } }