returneventsaver.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / AppModel / returneventsaver.cs / 1 / returneventsaver.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//             This class provides a convenient way to persist/depersist the events on a PageFunction 
//
//              By calling the _Detach() method on a pagefunction, 
//               this class will build a list of the class & methods on that Pagefunction,
//               as well as removing the current listener on the class when it's done.
//
//               By passing in a pagefunction on the _Attach method, the class will reattach the 
//               saved list to the calling pagefunction
// 
// History: 
//  06/11/03:      [....]     created
// 
//---------------------------------------------------------------------------

using System;
using System.Windows.Navigation; 
using System.Windows;
using System.Diagnostics; 
using System.Collections; 
using System.Reflection;
using System.IO; 
using System.Security.Permissions;
using System.Security;

namespace MS.Internal.AppModel 
{
    [Serializable] 
    internal struct ReturnEventSaverInfo 
    {
        internal ReturnEventSaverInfo(string delegateTypeName, string targetTypeName, string delegateMethodName, bool fSamePf) 
        {
            _delegateTypeName = delegateTypeName;
            _targetTypeName = targetTypeName;
            _delegateMethodName = delegateMethodName; 
            _delegateInSamePF = fSamePf;
        } 
 
        internal String _delegateTypeName;
        internal String _targetTypeName; 
        internal String _delegateMethodName;
        internal bool _delegateInSamePF;   // Return Event handler comes from the same pagefunction, this is for non-generic workaround.
    }
 
    [Serializable]
    internal class ReturnEventSaver 
    { 
        internal ReturnEventSaver()
        { 

        }

 
        /// 
        /// Critical - sets the critical _returnList. 
        /// TreatAsSafe - _returnList is not exposed in any way. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void _Detach(PageFunctionBase pf)
        {
            if (pf._Return != null && pf._Saver == null)
            { 
                ReturnEventSaverInfo[] list = null;
 
                Delegate[] delegates = null; 

                delegates = (pf._Return).GetInvocationList(); 
                list = _returnList = new ReturnEventSaverInfo[delegates.Length];

                for (int i = 0; i < delegates.Length; i++)
                { 
                    Delegate returnDelegate = delegates[i];
                    bool bSamePf = false; 
 
                    if (returnDelegate.Target == pf)
                    { 
                        // This is the Event Handler implemented by the same PF, use for NonGeneric handling.
                        bSamePf = true;
                    }
 
                    MethodInfo m = returnDelegate.Method;
                    ReturnEventSaverInfo info = new ReturnEventSaverInfo( 
                        returnDelegate.GetType().AssemblyQualifiedName, 
                        returnDelegate.Target.GetType().AssemblyQualifiedName,
                        m.Name, bSamePf); 

                    list[i] = info;
                }
 
                //
                // only save if there were delegates already attached. 
                // note that there will be cases where the Saver has already been pre-populated from a Load 
                // but no delegates have been created yet ( as the PF hasn`t called finish as yet)
                // 
                // By only storing the saver once there are delegates - we avoid the problem of
                // wiping out any newly restored saver
                pf._Saver = this;
            } 

            pf._DetachEvents(); 
        } 

 
        //
        // Attach the stored events to the supplied pagefunction.
        //
        // caller  - the Calling Page's root element. We will reattach events *from* this page root element *to* the child 
        //
        // child   - the child PageFunction. Caller was originally attached to child, we're now reattaching *to* the child 
        // 
        /// 
        /// Critical - Asserts ReflectionPermission to be able re-create delegate to private method. 
        /// TreatAsSafe - The delegate created is identical to the one that _Detach() received from
        ///     the application and saved. This is ensured by matching the type of the original target
        ///     object against the type of the new target. Thus we know that the application was able
        ///     to create a delegate over the exact method, and even if that method had a LinkDemand, 
        ///     it was satisfied by the application.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void _Attach(Object caller, PageFunctionBase child)
        { 
            ReturnEventSaverInfo[] list = null;

            list = _returnList;
 
            if (list != null)
            { 
                Debug.Assert(caller != null, "Caller should not be null"); 
                for (int i = 0; i < list.Length; i++)
                { 
                    //
                    //

 

                    Invariant.Assert(string.Compare(_returnList[i]._targetTypeName, caller.GetType().AssemblyQualifiedName, StringComparison.Ordinal) == 0, 
                        "The type of the PageFunction's invoking page unexpectedly changed. Expected: " + 
                        _returnList[i]._targetTypeName);
 
                    Delegate d;
                    try
                    {
                        new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert(); // BlessedAssert 

                        d = Delegate.CreateDelegate( 
                                                                Type.GetType(_returnList[i]._delegateTypeName), 
                                                                caller,
                                                                _returnList[i]._delegateMethodName); 
                    }
                    catch (Exception ex)
                    {
                        throw new NotSupportedException(SR.Get(SRID.ReturnEventHandlerMustBeOnParentPage), ex); 
                    }
                    finally 
                    { 
                        ReflectionPermission.RevertAssert();
                    } 

                    child._AddEventHandler(d);
                }
            } 
        }
 
        ///  
        /// Critical: contains metadata for delegates created under elevation.
        ///  
        [SecurityCritical]
        private ReturnEventSaverInfo[] _returnList;     // The list of delegates we want to persist and return later
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK