현재 시각적 또는 논리적 자녀에게 자녀가 추가되었을 때 알림을받을 방법을 찾고 있습니다.시각적/논리적 하위가 추가/제거 될 때 알림을받습니다.
Visual :: OnVisualChildrenChanged 메서드를 알고 있지만이 함수를 상속하거나 재정의 할 수 없기 때문에 나에게 적용되지 않습니다. 나는 사건을 찾고있다.
그래서, 추가 될 때 FrameworkElement/Visual의 소유자에게 알릴 수있는 방법이 있습니까?
현재 시각적 또는 논리적 자녀에게 자녀가 추가되었을 때 알림을받을 방법을 찾고 있습니다.시각적/논리적 하위가 추가/제거 될 때 알림을받습니다.
Visual :: OnVisualChildrenChanged 메서드를 알고 있지만이 함수를 상속하거나 재정의 할 수 없기 때문에 나에게 적용되지 않습니다. 나는 사건을 찾고있다.
그래서, 추가 될 때 FrameworkElement/Visual의 소유자에게 알릴 수있는 방법이 있습니까?
컨트롤이 비주얼 트리에 추가되거나 비주얼 트리에서 제거되면 각각 FrameworkElement.Loaded 및 FrameworkElement.Unloaded이 발생한다고 생각합니다. 그러나 그 (것)들을 가진 무엇이든을하는 것을 시도하고 있던 약간 시간, 나는 그 (것)와하기 위하여 무언가가있을 수 있었다 그래야, 나는 그들을 연속적으로 점화하는 얻을 수 없었다 (나는 종류 사건잡이를 당시에 사용하고 있었다).
부모 필드에 대한 참조를 유지하면서 자식 필드에 추가하고 변경 후 다시 알림을 보내면 어떨까요?
편집 :
방금 생각한 내용입니다. 시각적 트리에 나타나는 각 요소에 Loaded 핸들러를 설정할 수 있다면 아마도 다음과 같은 기술을 사용하여 구현할 수 있습니다 (이는 가능한 해결책으로 시작하는 아주 기본적인 아이디어라고 생각하십시오).
public class ElementChildrenChangedEventArgs
{
public ElementChildrenChangedEventArgs(FrameworkElement parent, FrameworkElement child)
{
Parent = parent;
Child = child;
}
public FrameworkElement Parent { get; private set;}
public FrameworkElement Child { get; private set;}
}
public delegate void ChildrenChanged(ElementChildrenChangedEventArgs args);
public static class ElementLoadedManager
{
private static readonly HashSet<FrameworkElement> elements = new HashSet<FrameworkElement>();
public static void Process_Loaded(FrameworkElement fe)
{
FrameworkElement feParent = VisualTreeHelper.GetParent(fe) as FrameworkElement;
if (feParent != null)
{
if (elements.Contains(feParent))
{
InvokeChildrenChanged(feParent, fe);
}
}
if (!elements.Contains(fe))
{
elements.Add(fe);
}
fe.Unloaded += Element_Unloaded;
}
static void Element_Unloaded(object sender, RoutedEventArgs e)
{
FrameworkElement fe = sender as FrameworkElement;
elements.Remove(fe);
ClearUnloaded(fe);
}
static void ClearUnloaded(FrameworkElement fe)
{
fe.Unloaded -= Element_Unloaded;
}
public static event ChildrenChanged ChildrenChanged;
private static void InvokeChildrenChanged(FrameworkElement parent, FrameworkElement child)
{
ElementChildrenChangedEventArgs args = new ElementChildrenChangedEventArgs(parent, child);
ChildrenChanged changed = ChildrenChanged;
if (changed != null) changed(args);
}
}
아이디어 및 요구 사항은 각 요소의 Loaded 처리기에서 Process_Loaded (FrameworkElement) 메서드를 호출하는 것으로, 일부 스타일/서식 파일 설정으로 수행 할 수 있습니다.
Loaded는 라우트 된 이벤트이므로 상위 창에서만 핸들러를 설정하고 e.OriginalSource를 확인할 수 있습니다.
수정 된 답변입니다. –
MSDN에 따르면 Loaded 이벤트의 라우팅 전략은 거품이 발생하지 않으며 "직접"입니다. 이러한 이유로, 귀하의 솔루션 (위)이 작동하는지 여부에 대한 귀하의 의견을 읽으 려합니다. – Mark
은 쉽게 통지를 할
System.Windows.Controls.UIElementCollection
을 확장하고
protected override UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
사용하지입니까?
자식 요소에서 연결된 이벤트를 발생시키기 위해 자식 요소에 연결된 동작을 사용할 수 있습니다. 또는 자식로드 이벤트에서 단순히 부모를 논리 트리 위로 검색하고 거기에서 메서드를 호출하거나 자식이 있음을 알리기 위해 (예 : 자식 수를 늘리는 것과 같은) 속성을 설정할 수 있습니다. 당신이 부모에게 일어날 일에 따라. 접근 설정 속성을 사용하는 경우 Unloaded도 처리해야합니다.
로드 및 언로드가 항상 예상대로 수행되지는 않습니다. 그러나 DataTemplates를 사용하여 자식 컨트롤을 만드는 경우에는 컨트롤이 만들어지고 소멸 될 때 항상 해고되어야합니다.
글쎄, 그 자체는 FrameworkElement.Loaded를 받는다. 그러나 부모는 그 자식이 실제로 생성되어 그것에 추가되었다는 것을 인식하지 못한다. – decasteljau