protected override void OnWriteEndObject() { InitializeObjectIfRequired(false, true); // this is required for such case that there was no StartMember call. var state = object_states.Pop(); var obj = state.Value; if (state.Type.IsImmutable) { obj = state.Type.Invoker.ToImmutable(obj); } if (state.Type.IsMarkupExtension) { // validate that the provided value is a markup extension, throws InvalidCastException if not var markupExtension = (MarkupExtension)obj; try { obj = markupExtension.ProvideValue(service_provider); } catch (XamlObjectWriterException) { throw; } catch (Exception ex) { throw WithLineInfo(new XamlObjectWriterException("An error occured getting provided value", ex)); } } // call this (possibly) before the object is added to parent collection. (bug #3003 also expects this) if (obj != null && state.IsXamlWriterCreated) { source.OnAfterProperties(obj); } var nfr = obj as NameFixupRequired; if (nfr != null && object_states.Count > 0) { // IF the root object to be written is x:Reference, then the Result property will become the NameFixupRequired. That's what .NET also does. // actually .NET seems to seek "parent" object in its own IXamlNameResolver implementation. nfr.State = object_states.Peek(); nfr.MemberState = nfr.State.CurrentMemberState; if (nfr.Type.IsCollection && !nfr.Type.IsDictionary && nfr.Value is IList) { // ensure the collection is in the same order as in xaml, so add a null in place // and we will replace it later var list = (IList)nfr.Value; nfr.ListIndex = list.Count; list.Add(null); } if (nfr.Type.IsImmutable && object_states.Count > 0) { // if it's immutable, we need to set the parent member after getting the real value object_states.Pop(); nfr.ParentState = object_states.Peek(); nfr.ParentMemberState = nfr.ParentState.CurrentMemberState; object_states.Push(nfr.State); } pending_name_references.Add((NameFixupRequired)obj); } else { // UsableDuringInitialization type may have already been attached to its parent in OnWriteStartMember. if (!(state.Type.IsUsableDuringInitialization && state.WrittenProperties.Count > 0 && CurrentMemberState?.IsAlreadySet == true)) { StoreAppropriatelyTypedValue(obj, state.KeyValue); } } HandleEndInit(obj); object_states.Push(state); if (object_states.Count == 1) { Result = obj; ResolvePendingReferences(); } }