void RegisterBinding(VisualElement content, bool foundRoot = false) { if (content is CustomInspectorElement && content != this) { return; } if (content is PropertyElement) { return; } var bindable = false; if (content is IBindable b && !string.IsNullOrEmpty(b.bindingPath)) { bindable = true; if (!foundRoot) { foundRoot = true; switch (m_Inspector.Part.Type) { case PropertyPath.PartType.Name: m_RelativePath.PushName(b.bindingPath); break; case PropertyPath.PartType.Index: m_RelativePath.PushIndex(int.Parse(b.bindingPath.Substring(1, b.bindingPath.Length - 2))); break; case PropertyPath.PartType.Key: break; default: throw new ArgumentOutOfRangeException(); } } else { m_RelativePath.PushName(b.bindingPath); } if (m_Inspector.IsPathValid(m_RelativePath)) { var path = new PropertyPath(); path.PushPath(m_Inspector.PropertyPath); if (path.PartsCount > 0) { path.Pop(); } path.PushPath(m_RelativePath); m_Inspector.RegisterBindings(path, content); } if (content == m_Content) { switch (m_Inspector.Part.Type) { case PropertyPath.PartType.Name: m_AbsolutePath.PushName(b.bindingPath); break; case PropertyPath.PartType.Index: m_RelativePath.PushIndex(int.Parse(b.bindingPath.Substring(1, b.bindingPath.Length - 2))); break; case PropertyPath.PartType.Key: break; default: throw new ArgumentOutOfRangeException(); } } else { m_AbsolutePath.PushName(b.bindingPath); } if (m_Inspector.IsPathValid(m_AbsolutePath) && m_RelativePath.ToString() != b.bindingPath) { var path = new PropertyPath(); path.PushPath(m_Inspector.PropertyPath); path.Pop(); path.PushPath(m_AbsolutePath); m_Inspector.RegisterBindings(path, content); } m_AbsolutePath.Clear(); } foreach (var child in content.Children()) { RegisterBinding(child.contentContainer, foundRoot); } if (bindable) { m_RelativePath.Pop(); } }