XObject.Changed 事件

定义

在此 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 树,而不是包含正在接收事件的节点的 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.

适用于

另请参阅