2011-09-21 1 views
1

XElement 클래스를 통해 일부 XML 데이터에 바인딩 된 WPF로 구현 된 TreeView가 있습니다. 처음 XML 파일을로드 할 때 바인딩이 정상적으로 작동합니다. 모든 데이터가 트리를 예상대로 채 웁니다. 이 문제는 TreeView에서 아무 일도 발생하지 않기 때문에 요소를 추가하거나 제거 할 때 발생합니다. 지금 나는 이것을 해 봤습니다. '그리고 저는이 일을 위해 여분의 일을 올바르게 할 필요가 없다는 것을 기억합니다. 적어도 트리에서 항목을 추가하고 제거하는 간단한 경우. 나는 이것이 여분의 코딩 노력 없이도 작동한다는 사실에 놀랐다. 나는 그 코드에 더 이상 접근 할 수 없어 이미 내가 한 것을 볼 수 없다. 그래서 나는 왜 내가이 일을 지금 당장 할 수 없는지에 대해 다소 혼란 스럽다.XElement를 통해 데이터 바인딩 된 XML 데이터가있는 TreeView의 업데이트에 문제가 발생했습니다.

내 WPF 코드는 다음과 같습니다.

<Window.Resources> 
    <HierarchicalDataTemplate ItemsSource="{Binding Path=Elements}" x:Key="ViewEditTreeTemplate"> 
     <StackPanel Orientation="Horizontal" Margin="2"> 
      <Label x:Name="ElementHeaderLabel" Padding="1" VerticalContentAlignment="Center" FontSize="16" Content="{Binding Path=DisplayName}" /> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
</Window.Resources> 


<Grid> 
    <TreeView Name="DataTree" ItemTemplate ="{Binding Source={StaticResource ViewEditTreeTemplate}}" Margin="0,0,0,53" /> 
</Grid> 

다음과 같이 코드에 XML 문서를 첨부합니다. 트리가 자동으로 XML 데이터의 정보로 채워지기 때문에 이것이 작동하는 것처럼 보입니다.

// When removing an element 
Element.Remove();   //Element is of type XElement 

// When adding an element 
ParentElement.Add(NewElement); //ParentElement and NewElement are of type XElement 

나는 한번도 이런 짓을 할 때, 나는 실제로하지 않았다이 강한 느낌이 다음과 같이 I 추가하거나 요소를 제거하기 위해 갈 때 뒤에있는 코드에서
XElement NewElement = new XElement(XElement.Load(FilePath)); 
List<XElement> TempList = new List<XElement>(); 
TempList.Add(NewElement); 
DataTree.ItemsSource = TempList; 

내가 할 특별한 일을하십시오. .Remove() 및 .Add() 루틴은 .Elements()의 항목이 변경되고 화면이 자동으로 업데이트된다는 바인딩에 어떻게 든 통보했습니다. 어쨌든 이번에는 이번에는 작동하지 않습니다. 아무도 이유를 아나요?

+1

목록 대신 ObservableCollection 을 사용해 보셨습니까? mbursill

+0

시도하지 않았지만 방금 변경 한 사항이 없습니다. 나는 그것이 작동한다고 기대하지 않았다. 그 컬렉션은 최상위 레벨에만 해당 될 것입니다.첫 번째 요소 뒤에 .Elements()가 반환하는 컬렉션이 트리를 채우고 바인딩과 연결됩니다. – Ultratrunks

답변

0

좋아, 내 문제에 대한 해결책이 있습니다. 나는 왜 이것이 원래 특별한 일을하지 않고도 원래 일할 것이라고 생각하는지 확신 할 수는 없지만 그렇게 생각하지는 않습니다.

문제를 좀 더 명확히하기 위해 XElement 객체를 그대로 사용하지 않았으므로 다른 클래스로 래핑 한 후 몇 가지 기능을 추가 할 수있었습니다. INotifyPropertyChanged 인터페이스가 필요하고 원하는 동작을 얻기 위해 몇 가지 메서드를 재정의했기 때문에 이것은 좋았습니다. 내 실제 클래스 헤더는 다음과 같습니다. 내 트 리뷰가 XElement.Elements 구속 된 이후 나는 추가하거나 제거 할 요소 때

public class TreeElement : XElement, INotifyPropertyChanged 
{ 
    ... 
} 

(루틴, 그것은 통지를) 수신되지 않았습니다. 이유는 XElement.Elements()가 종속성 속성이 아니기 때문입니다. 그것의 일상. 나는 이것을 미리 알고 있었지만 어떤 이유로 나는 고집 스러웠고 아직도 그것이 작동 할 것이라고 생각했다. 그래서 내가 추가해야 할 것은 INotifyPropertyChanged 인터페이스이며, XElement.Elements()의 데이터가 변경되도록하는 연산이 발생할 때마다 NotifyPropertyChanged() 루틴을 호출합니다. 즉, XElement.Add() 및 XElement.Remove() 루틴입니다. 몇 가지가 더 있습니다.하지만이 두 가지에 대해서만 이야기하겠습니다.

이 루틴은 무시할 수 없지만 "새"키워드를 사용하여 숨길 수 있습니다. 다음은 이러한 루틴에 대한 새로운 구현입니다. .Elements은() 속성 NotifyPropertyChanged ("요소") 메소드가 아니더라도

public new void Remove() 
{ 
    XElement parent = this.Parent; 
    base.Remove(); 

    if ((parent != null) && (parent.GetType() == typeof(TreeElement))) 
    { 
    //need to tell parent that they are losing an element 
    ((TreeElement)parent).NotifyPropertyChanged("Elements"); 
    } 
} 


public new void Add(object Content) 
{ 
    base.Add(Content); 
    NotifyPropertyChanged("Elements"); 
} 

당신이 볼 수 있듯이

내 바인딩 'ItemsSource = "{바인딩 경로 = 요소}' '을 알리는에서 잘 작동합니다. 그래서 지금은 .Add() 또는 .Remove() 트리 자동 업데이트를 사용하여 코드를 업데이트 할 때.

관련 문제