/// <summary> /// Reconfigure components that enter and leave. /// </summary> /// <param name="sender"></param> /// <param name="nccea"></param> void Components_CollectionChanged(object sender, NotifyCollectionChangedEventArgs nccea) { var celc = new DefaultEnterLeaveContext(Surface, Components, Layers, DataContext); try { if (nccea.OldItems != null) { foreach (ChartComponent cc in nccea.OldItems) { _trace.Verbose($"leave '{cc.Name}' {cc}"); cc.RefreshRequest -= ChartComponent_RefreshRequest; ComponentLeave(celc, cc); } } if (nccea.NewItems != null) { foreach (ChartComponent cc in nccea.NewItems) { _trace.Verbose($"enter '{cc.Name}' {cc}"); cc.RefreshRequest -= ChartComponent_RefreshRequest; cc.RefreshRequest += ChartComponent_RefreshRequest; cc.DataContext = DataContext; if (Surface != null) { ComponentEnter(celc, cc); } else { DeferredEnter.Add(cc); } } } } catch (Exception ex) { _trace.Error($"{Name} Components_CollectionChanged.unhandled: {ex}"); } if (celc.Errors.Count > 0) { Report(celc.Errors.ToArray()); } if (Surface != null) { InvalidateArrange(); } }
/// <summary> /// Obtain UI elements from the control template. /// Happens Before Chart_LayoutUpdated. /// </summary> protected override void OnApplyTemplate() { try { Surface = GetTemplateChild(PART_Canvas) as Canvas; _trace.Verbose($"OnApplyTemplate ({Width}x{Height}) {Surface} d:{DeferredEnter.Count} composition:{UniversalApiContract.v3.CompositionSupport.IsSupported}"); var celc = new DefaultEnterLeaveContext(Surface, Components, Layers, DataContext); foreach (var cc in DeferredEnter) { ComponentEnter(celc, cc); } DeferredEnter.Clear(); if (celc.Errors.Count > 0) { Report(celc.Errors.ToArray()); } } finally { base.OnApplyTemplate(); } }