2011-09-21 8 views
1

XElementクラスを介してXMLデータにバインドされたWPFでTreeViewが実装されています。初めてXMLファイルを読み込むときに、バインディングは正常に動作します。すべてのデータが期待どおりにツリーに移入します。この問題は、ツリービューで何も起こらないので、要素を追加および削除するときに発生します。今私はこれを前にやったことがあります。そして、私はこの仕事のために特別な作業を正しく行う必要がないことを覚えていると信じています。少なくとも、ツリーから項目を追加したり削除したりする単純なケース。私はこれが余分なコーディング努力なしで機能したことに驚いたことを覚えています私はもうコードにアクセスできないので、私がすでに行ったことを見ることはできません。だから私は今、なぜこれを動作させることができないのか、まったく分かりません。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データからの情報を自動的に取り込みますので、これは動作しているように見えます。背後にあるコード私は要素を追加または削除するに行くとき、私は何で

XElement NewElement = new XElement(XElement.Load(FilePath)); 
List<XElement> TempList = new List<XElement>(); 
TempList.Add(NewElement); 
DataTree.ItemsSource = TempList; 

次のように:

// 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 

を私は前にこれをしたとき、私は実際に持っていなかったことを、この強い気持ちを持っています何か特別なことをする。 .Remove()および.Add()ルーチンは、何らかの形で、.Elements()内の項目が変更され、画面が自動的に更新されることをバインディングに通知しました。どのような場合でも、その周りにこの時間は動作しません。なぜ誰が知っていますか?

+1

リストの代わりにObservableCollection を試しましたか mbursill

+0

私は試していませんでしたが、やっただけで何も変わりませんでした。私はそれが動作するとは思わなかった。そのコレクションは非常に最上位レベルにすぎません。最初の要素の後で、.Elements()によって返されるコレクションは、ツリーを埋めるものであり、バインディングとのインターフェイスになります。 – Ultratrunks

答えて

0

私は自分の問題を解決しています。私はなぜこれがもともと特別なことをすることなく動作すると思ったのか分かりませんが、それはそうではないようです。

もう少し問題を明確にするために、私はXElementオブジェクトをそのまま使用していませんでした。別のクラスでラップしていましたので、いくつかの機能を追加できました。 INotifyPropertyChangedインターフェイスが必要で、必要な動作を得るためにいくつかのメソッドをオーバーライドする必要があることが判明したので、これは良いことでした。実際のクラスヘッダーは次のようになります。

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

TreeViewがXElement.Elements()ルーチンでバインドされていたため、要素を追加または削除したときに通知が受信されませんでした。その理由は、XElement.Elements()が依存関係プロパティではないためです。そのルーチン。私はこれを前もって知っていましたが、何らかの理由で私は頑固で、まだそれがうまくいくと思っていました。だから私が追加する必要があったのは、INotifyPropertyChangedインターフェイスであり、XElement.Elements()からのデータが変更されるような操作が発生するたびにNotifyPropertyChanged()ルーチンを呼び出します。つまり、XElement.Add()とXElement.Remove()ルーチンです。もっといくつかありますが、私はこれらの2つについてちょうど話します。

これらのルーチンは上書きできませんが、「新しい」キーワードを使用して非表示にすることができます。これらのルーチンの新しい実装がここにあります。 .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()を使って更新すると、ツリーの自動更新が行われます。

関連する問題