diff --git a/Datra.Editor/Models/FieldCreationContext.cs b/Datra.Editor/Models/FieldCreationContext.cs
index 360425b..009ed35 100644
--- a/Datra.Editor/Models/FieldCreationContext.cs
+++ b/Datra.Editor/Models/FieldCreationContext.cs
@@ -50,11 +50,27 @@ public class FieldCreationContext
/// 루트 데이터 객체
public object? RootDataObject { get; set; }
+ ///
+ /// 현재 필드가 파생된 원본 멤버.
+ /// 배열/리스트/dictionary 요소처럼 Property/Member가 없는 파생 필드에서도
+ /// attribute 기반 핸들러가 원래 선언부의 메타데이터를 볼 수 있게 한다.
+ ///
+ public MemberInfo? SourceMember { get; set; }
+
+ /// 루트 편집 객체 기준의 사람이 읽을 수 있는 필드 경로.
+ public string? FieldPath { get; set; }
+
+ /// 컬렉션 요소 키 (dictionary 요소인 경우)
+ public object? CollectionElementKey { get; set; }
+
/// 중첩 멤버인지 여부
public bool IsNestedMember => Member != null && Property == null;
- /// 배열 요소인지 여부
- public bool IsArrayElement => Property == null && Member == null && CollectionElementIndex.HasValue;
+ /// 배열/리스트 요소인지 여부
+ public bool IsArrayElement => Property == null && Member == null && CollectionElementIndex.HasValue && CollectionElementKey == null;
+
+ /// 배열/리스트/dictionary 요소인지 여부
+ public bool IsCollectionElement => CollectionElementIndex.HasValue || CollectionElementKey != null;
///
/// 프로퍼티 기반 필드 생성용 생성자
@@ -76,6 +92,8 @@ public FieldCreationContext(
OnValueChanged = onValueChanged;
LocaleService = localeService;
IsReadOnly = isReadOnly || !property.CanWrite;
+ SourceMember = property;
+ FieldPath = property.Name;
}
///
@@ -100,6 +118,8 @@ public FieldCreationContext(
OnValueChanged = onValueChanged;
LocaleService = localeService;
IsReadOnly = isReadOnly;
+ SourceMember = member;
+ FieldPath = member.Name;
}
///
@@ -112,7 +132,9 @@ public FieldCreationContext(
FieldLayoutMode layoutMode,
Action