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();
}
}