次の方法で共有


XObject.Changed イベント

定義

この XObject またはその子孫が変更されたときに発生します。

public:
 event EventHandler<System::Xml::Linq::XObjectChangeEventArgs ^> ^ Changed;
public event EventHandler<System.Xml.Linq.XObjectChangeEventArgs> Changed;
member this.Changed : EventHandler<System.Xml.Linq.XObjectChangeEventArgs> 
Public Custom Event Changed As EventHandler(Of XObjectChangeEventArgs) 

イベントの種類

次の例では、XML ツリーのルート要素にイベント ハンドラーを追加します。 その後、ツリーが変更され、LINQ to XMLによっていくつかのイベントが発生します。

XElement root = new XElement("Root", "content");  
root.Changing += new EventHandler<XObjectChangeEventArgs>(  
    (sender, cea) =>  
    {  
        Console.WriteLine("Changing event raised");  
        XElement xSender = (XElement)sender;  
        Console.WriteLine("  Sender: {0}", xSender.Name);  
        Console.WriteLine("  ObjectChange: {0}", cea.ObjectChange);  
    }  
);  
root.Changed += new EventHandler<XObjectChangeEventArgs>(  
    (sender, cea) =>  
    {  
        Console.WriteLine("Changed event raised");  
        XElement xSender = (XElement)sender;  
        Console.WriteLine("  Sender: {0}", xSender.Name);  
        Console.WriteLine("  ObjectChange: {0}", cea.ObjectChange);  
    }  
);  
root.Add(new XElement("Child", "child content"));  
Module Module1  
    WithEvents root As XElement = <Root>content</Root>  

    Sub Main()  
        root.Add(<Child>child content</Child>)  
    End Sub  

    Private Sub root_Changing( _  
            ByVal sender As Object, _  
            ByVal e As XObjectChangeEventArgs) _  
            Handles root.Changing  
        Dim xSender As XElement = DirectCast(sender, XElement)  
        Console.WriteLine("Changing event raised")  
        Console.WriteLine("  Sender: {0}", xSender.Name)  
        Console.WriteLine("  ObjectChange: {0}", e.ObjectChange)  
    End Sub  

    Private Sub root_Changed( _  
            ByVal sender As Object, _  
            ByVal e As XObjectChangeEventArgs) _  
            Handles root.Changed  
        Dim xSender As XElement = DirectCast(sender, XElement)  
        Console.WriteLine("Changed event raised")  
        Console.WriteLine("  Sender: {0}", xSender.Name)  
        Console.WriteLine("  ObjectChange: {0}", e.ObjectChange)  
    End Sub  
End Module  

この例を実行すると、次の出力が生成されます。

Changing event raised  
  Sender: Child  
  ObjectChange: Add  
Changed event raised  
  Sender: Child  
  ObjectChange: Add  

XML ツリー内の集計情報を維持する場合に、イベントは便利です。 たとえば、請求書の品目の合計である請求合計を維持する場合があります。 この例では、イベントを使用して、複合要素の Items の下にあるすべての子要素の合計を維持します。

XElement root = new XElement("Root",  
    new XElement("Total", 0),  
    new XElement("Items")  
);  
XElement total = root.Element("Total");  
XElement items = root.Element("Items");  
items.Changed += (object sender, XObjectChangeEventArgs cea) =>  
{  
    switch (cea.ObjectChange)  
    {  
        case XObjectChange.Add:  
            if (sender is XElement)  
                total.Value = ((int)total + (int)(XElement)sender).ToString();  
            if (sender is XText)  
                total.Value = ((int)total + (int)((XText)sender).Parent).ToString();  
            break;  
        case XObjectChange.Remove:  
            if (sender is XElement)  
                total.Value = ((int)total - (int)(XElement)sender).ToString();  
            if (sender is XText)  
                total.Value = ((int)total - Int32.Parse(((XText)sender).Value)).ToString();  
            break;  
    }  
    Console.WriteLine("Changed {0} {1}", sender.GetType().ToString(), cea.ObjectChange.ToString());  
};  
items.SetElementValue("Item1", 25);  
items.SetElementValue("Item2", 50);  
items.SetElementValue("Item2", 75);  
items.SetElementValue("Item3", 133);  
items.SetElementValue("Item1", null);  
items.SetElementValue("Item4", 100);  
Console.WriteLine("Total:{0}", (int)total);  
Console.WriteLine(root);  
Module Module1  
    Private total As XElement = Nothing  
    Private WithEvents items As XElement = Nothing  
    Private root As XElement = _  
            <Root>  
                <Total>0</Total>  
                <Items></Items>  
            </Root>  

    Sub Main()  
        total = root.<Total>(0)  
        items = root.<Items>(0)  
        items.SetElementValue("Item1", 25)  
        items.SetElementValue("Item2", 50)  
        items.SetElementValue("Item2", 75)  
        items.SetElementValue("Item3", 133)  
        items.SetElementValue("Item1", Nothing)  
        items.SetElementValue("Item4", 100)  
        Console.WriteLine("Total:{0}", CInt(total))  
        Console.WriteLine(root)  
    End Sub  

    Private Sub XObjectChanged( _  
            ByVal sender As Object, _  
            ByVal cea As XObjectChangeEventArgs) _  
            Handles items.Changed  
        Select Case cea.ObjectChange  
            Case XObjectChange.Add  
                If sender.GetType() Is GetType(XElement) Then  
                    total.Value = CStr(CInt(total.Value) + _  
                            CInt((DirectCast(sender, XElement)).Value))  
                End If  
                If sender.GetType() Is GetType(XText) Then  
                    total.Value = CStr(CInt(total.Value) + _  
                            CInt((DirectCast(sender, XText)).Value))  
                End If  
            Case XObjectChange.Remove  
                If sender.GetType() Is GetType(XElement) Then  
                    total.Value = CStr(CInt(total.Value) - _  
                            CInt((DirectCast(sender, XElement)).Value))  
                End If  
                If sender.GetType() Is GetType(XText) Then  
                    total.Value = CStr(CInt(total.Value) - _  
                            CInt((DirectCast(sender, XText)).Value))  
                End If  
        End Select  
        Console.WriteLine("Changed {0} {1}", _  
                            sender.GetType().ToString(), _  
                            cea.ObjectChange.ToString())  
    End Sub  
End Module  

このコードを実行すると、次の出力が生成されます。

Changed System.Xml.Linq.XElement Add  
Changed System.Xml.Linq.XElement Add  
Changed System.Xml.Linq.XText Remove  
Changed System.Xml.Linq.XText Add  
Changed System.Xml.Linq.XElement Add  
Changed System.Xml.Linq.XElement Remove  
Changed System.Xml.Linq.XElement Add  
Total:308  
<Root>  
  <Total>308</Total>  
  <Items>  
    <Item2>75</Item2>  
    <Item3>133</Item3>  
    <Item4>100</Item4>  
  </Items>  
</Root>  

注釈

イベントは、XML ツリーが変更された場合にのみ発生し、構築時には発生しません。 これは、イベントを受信する前にイベント ハンドラーをイベントに追加する必要があり、 への XObject参照を取得する前にイベント ハンドラーを追加できないためです。 XML ツリーが構築される前に、 への XObject 参照を取得することはできません。 これは、XML ツリーの機能構築中にイベントを受信しないことを意味します。

この操作を行うと予期しない結果が発生する可能性があるため、これらのイベントの 1 つ内で XML ツリーを変更する場合は注意が必要です。 たとえば、イベントを Changing 受け取り、イベントの処理中にツリーからノードを削除すると、イベントが Changed 発生しない可能性があります。 イベントが処理されている場合、イベントを受信しているノードを含む XML ツリー以外の XML ツリーを変更することは有効です。変更がイベントが発生した特定のノードに影響を与えない場合は、同じツリーを変更しても有効です。 ただし、イベントを受信するノードを含むツリーの領域を変更した場合、受け取るイベントとツリーへの影響は未定義です。

適用対象

こちらもご覧ください