XObject.Changed XObject.Changed XObject.Changed XObject.Changed Event

定義

この XObject またはその子孫が変更されたときに発生します。Raised when this XObject or any of its descendants have changed.

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 ツリーのルート要素にイベントハンドラーを追加します。The following example adds an event handler to the root element of an XML tree. 次に、ツリーを変更し、LINQ to XML によっていくつかのイベントが発生するようにします。It then modifies the tree, causing LINQ to XML to raise some events.

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  

この例を実行すると、次の出力が生成されます。This example produces the following output:

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

XML ツリー内の集計情報を維持する場合に、イベントは便利です。Events are useful when you want to maintain some aggregate information in an XML tree. たとえば、請求書の品目の合計である請求合計を維持する場合があります。For example, you may want maintain an invoice total that is the sum of the line items of the invoice. この例では、イベントを使用して、複合要素の Items の下にあるすべての子要素の合計を維持します。This example uses events to maintain the total of all of the child elements under the complex element 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  

このコードを実行すると、次の出力が生成されます。This code produces the following output:

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 ツリーが変更されたときにのみ発生し、構築時には生成されません。Events are raised only when an XML tree is modified, not when it is constructed. これは、イベントを受け取る前にイベントにイベントハンドラーを追加する必要があるためです。への参照を行う前に、 XObjectイベントハンドラーを追加することはできません。This is because you have to add an event handler to an event before you can receive events, and you cannot add an event handler before you have a reference to an XObject. XML ツリーを構築する前にXObject 、への参照を取得することはできません。You cannot get a reference to an XObject before the XML tree is constructed. つまり、XML ツリーの関数型構築中にイベントを受け取ることはありません。This means that during functional construction of an XML tree, you will not receive events.

これらのイベントのいずれかで XML ツリーを変更する場合は注意が必要です。これを行うと、予期しない結果が生じる可能性があります。You should be careful when modifying an XML tree within one of these events, because doing this might lead to unexpected results. たとえば、イベントを受信Changingしたときにイベントが処理されている間に、ツリーからノードを削除すると、そのChangedイベントを受信できない可能性があります。For example, if you receive a Changing event, and while the event is being processed you remove the node from the tree, you might not receive the Changed event. イベントが処理されるときに、イベントを受け取るノードを含む XML ツリーを変更することが有効です。同じツリーを変更しても、イベントが発生した特定のノードに変更が影響しないようにすることもできます。When an event is being processed, it is valid to modify an XML tree other than the one that contains the node that is receiving the event; it is even valid to modify the same tree provided the modifications do not affect the specific nodes on which the event was raised. ただし、イベントを受信するノードを含むツリーの領域を変更すると、受信したイベントとツリーへの影響が未定義になります。However, if you modify the area of the tree that contains the node receiving the event, the events that you receive and the impact to the tree are undefined.

適用対象

こちらもご覧ください