Пример #1
0
        /// <summary>
        /// override of WriteDynamicEvent
        /// </summary>
        public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode)
        {
            bool isStyleEvent = (xamlClrEventNode.IsStyleSetterEvent || xamlClrEventNode.IsTemplateEvent);
            bool localEvent   = _compiler.LocalAssembly == xamlClrEventNode.EventMember.ReflectedType.Assembly;

            if (isStyleEvent)
            {
                if (localEvent)
                {
                    // validate the event handler name per CLS grammar for identifiers
                    _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value);
                    xamlClrEventNode.LocalAssemblyName = _compiler.AssemblyName;
                    // Pass2 should always be true here as otherwise localEvent will be false, but just being paranoid here.
                    if (_pass2)
                    {
                        XamlTypeMapper.HasInternals = true;
                    }
                }
                else
                {
                    if (!xamlClrEventNode.IsSameScope)
                    {
                        _connectionId++;
                    }

                    xamlClrEventNode.ConnectionId = _connectionId;

                    if (!_pass2)
                    {
                        _compiler.ConnectStyleEvent(xamlClrEventNode);
                    }
                }

                return;
            }

            bool appEvent = KnownTypes.Types[(int)KnownElements.Application].IsAssignableFrom(xamlClrEventNode.EventMember.DeclaringType);

            if (!appEvent)
            {
                if (!_pass2)
                {
                    // validate the event handler name per CLS grammar for identifiers
                    _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value);

                    if (_events == null)
                    {
                        _events = new ArrayList();
                    }

                    _events.Add(new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value,
                                                                   xamlClrEventNode.EventName,
                                                                   xamlClrEventNode.EventMember,
                                                                   xamlClrEventNode.LineNumber));
                }

                // if not local event ...
                if (!localEvent)
                {
                    WriteConnectionId();
                }
            }
            else if (!_pass2)
            {
                // Since Application is not an Element it doesn't implement IComponentConnector and
                // so needs to add events directly.
                MarkupCompiler.MarkupEventInfo mei = new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value,
                                                                                        xamlClrEventNode.EventName,
                                                                                        xamlClrEventNode.EventMember,
                                                                                        xamlClrEventNode.LineNumber);
                _compiler.AddApplicationEvent(mei);
            }

            if (_pass2)
            {
                // if local event, add Baml Attribute Record for local event
                if (localEvent)
                {
                    // validate the event handler name per C# grammar for identifiers
                    _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value);

                    XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber,
                                                                             xamlClrEventNode.LinePosition,
                                                                             xamlClrEventNode.Depth,
                                                                             xamlClrEventNode.EventMember,
                                                                             _compiler.AssemblyName,
                                                                             xamlClrEventNode.EventMember.ReflectedType.FullName,
                                                                             xamlClrEventNode.EventName,
                                                                             xamlClrEventNode.Value,
                                                                             BamlAttributeUsage.Default,
                                                                             false);

                    XamlTypeMapper.HasInternals = true;

                    base.WriteProperty(xamlPropertyNode);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Write an Event Connector and call the controlling compiler parser to generate event hookup code. 
        /// </summary> 
        public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode)
        { 
            if (_previousXamlParser != null)
            {
                Debug.Assert(_styleModeStack.Mode == StyleMode.VisualTree);
 
                // if this event token is not owned by this TemplateXamlParser, then just chain
                // the WriteClrEvent call to the controlling parser. Ulimately, this will 
                // reach the markup compiler that will deal with this info as appropriate. 

                bool isOriginatingEvent = xamlClrEventNode.IsOriginatingEvent; 
                if (isOriginatingEvent)
                {
                    // set up additional state on event node for the markup compiler to use.
                    Debug.Assert(!xamlClrEventNode.IsStyleSetterEvent); 
                    xamlClrEventNode.IsTemplateEvent = true;
                    xamlClrEventNode.IsSameScope = _isSameScope; 
 
                    // any intermediary controlling parsers need to get out of the way so that
                    // the markup compiler can ultimately do its thing. 
                    xamlClrEventNode.IsOriginatingEvent = false;

                    // Store away the type of the element we're currently in.  E.g.
                    // in <Button Click="OnClicked"/>, this will be typeof(Button). 
                    // In the case of regular CLR events, this type is the same as that
                    // which can be found in xamlClrEventNode.EventMember.  But in the 
                    // case of attached events, EventMember is the class that holds 
                    // the attached event, and the compiler needs to know the type of
                    // the listener. 

                    xamlClrEventNode.ListenerType = (Type) _elementTypeStack.Peek();
                }
 
                _previousXamlParser.WriteClrEvent(xamlClrEventNode);
 
                if (isOriginatingEvent) 
                {
                    if (!String.IsNullOrEmpty(xamlClrEventNode.LocalAssemblyName)) 
                    {
                        // if this event is a local event need to generate baml for it now

                        XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber, 
                                                                                 xamlClrEventNode.LinePosition,
                                                                                 xamlClrEventNode.Depth, 
                                                                                 null, 
                                                                                 xamlClrEventNode.LocalAssemblyName,
                                                                                 xamlClrEventNode.EventMember.ReflectedType.FullName, 
                                                                                 xamlClrEventNode.EventName,
                                                                                 xamlClrEventNode.Value,
                                                                                 BamlAttributeUsage.Default,
                                                                                 false); 
                        base.WriteProperty(xamlPropertyNode);
                    } 
                    else 
                    {
                        // write out a connectionId to the baml stream only if a 
                        // new event scope was encountered
                        if (!_isSameScope)
                        {
                            base.WriteConnectionId(xamlClrEventNode.ConnectionId); 
                        }
 
                        // We have just finished processing the start of a new event scope. 
                        // So specifiy start of this new scope.
                        _isSameScope = true; 
                    }
                }
            }
        } 
        internal void ConnectStyleEvent(XamlClrEventNode xamlClrEventNode)
        {
            CodeConditionStatement ccsConnector = null;

            // validate the event handler name per C# grammar for identifiers
            ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value);

            EnsureStyleConnector();

            if (!xamlClrEventNode.IsSameScope)
            {
                int connectionId = xamlClrEventNode.ConnectionId;
                if (SwitchStatementSupported())
                {
                    // break any previous case staements as we are starting a new connection scope.
                    if (_ccRoot.StyleConnectorFn.Statements.Count > 1)
                    {
                        CodeSnippetStatement cssBreak = new CodeSnippetStatement(BREAK_STATEMENT);
                        _ccRoot.StyleConnectorFn.Statements.Add(cssBreak);
                    }

                    // case 1:
                    //
                    CodeSnippetStatement cssCase = new CodeSnippetStatement(CASE_STATEMENT + connectionId + COLON);
                    _ccRoot.StyleConnectorFn.Statements.Add(cssCase);
                }
                else
                {
                    // if (connectionId == 1)
                    //
                    ccsConnector = new CodeConditionStatement();
                    ccsConnector.Condition = new CodeBinaryOperatorExpression(new CodeArgumentReferenceExpression(CONNECTIONID),
                                                                              CodeBinaryOperatorType.ValueEquality,
                                                                              new CodePrimitiveExpression(connectionId));
                }
            }
            else if (!SwitchStatementSupported())
            {
                // if in the same scope then use the if statement that was last generated
                // at the start of the scope
                Debug.Assert(_ccRoot.StyleConnectorFn.Statements.Count > 0);
                ccsConnector = _ccRoot.StyleConnectorFn.Statements[_ccRoot.StyleConnectorFn.Statements.Count - 1] as CodeConditionStatement;
                Debug.Assert(ccsConnector != null);
            }

            CodeArgumentReferenceExpression careTarget = new CodeArgumentReferenceExpression(TARGET);

            if (xamlClrEventNode.IsStyleSetterEvent)
            {
                // EventSetter declaration only once to avoid warning!
                if (!_hasEmittedEventSetterDeclaration)
                {
                    _hasEmittedEventSetterDeclaration = true;
                    
                    // EventSetter eventSetter;
                    //
                    CodeVariableDeclarationStatement cvdsES = new CodeVariableDeclarationStatement(KnownTypes.Types[(int)KnownElements.EventSetter], EVENTSETTER);
                    _ccRoot.StyleConnectorFn.Statements.Insert(0, cvdsES);
                }


                // eventSetter = new EventSetter();
                //
                CodeExpression[] esParams = {};
                CodeVariableReferenceExpression cvreES = new CodeVariableReferenceExpression(EVENTSETTER);
                CodeAssignStatement casES = new CodeAssignStatement(cvreES,
                                                                    new CodeObjectCreateExpression(KnownTypes.Types[(int)KnownElements.EventSetter],
                                                                                                   esParams));

                // eventSetter.Event = Button.ClickEvent;
                //
                CodePropertyReferenceExpression cpreEvent = new CodePropertyReferenceExpression(cvreES, EVENT);
                CodeAssignStatement casEvent = new CodeAssignStatement(cpreEvent,
                                                                       GetEvent(xamlClrEventNode.EventMember,
                                                                                xamlClrEventNode.EventName,
                                                                                xamlClrEventNode.Value));

                // eventSetter.Handler = new RoutedEventHandler(OnClick);
                //
                CodePropertyReferenceExpression cpreHandler = new CodePropertyReferenceExpression(cvreES, HANDLER);
                CodeAssignStatement casHandler = new CodeAssignStatement(cpreHandler,
                                                                         GetEventDelegate(null,
                                                                                          xamlClrEventNode.EventMember,
                                                                                          xamlClrEventNode.EventName,
                                                                                          xamlClrEventNode.Value));

                AddLinePragma(casHandler, xamlClrEventNode.LineNumber);

                // ((Style)target).Setters.Add(eventSetter);
                //
                CodeCastExpression cceTarget = new CodeCastExpression(KnownTypes.Types[(int)KnownElements.Style], careTarget);
                CodePropertyReferenceExpression cpreSetters = new CodePropertyReferenceExpression(cceTarget, SETTERS);
                CodeMethodInvokeExpression cmieAdd = new CodeMethodInvokeExpression(cpreSetters, ADD, cvreES);

                if (SwitchStatementSupported())
                {
                    _ccRoot.StyleConnectorFn.Statements.Add(casES);
                    _ccRoot.StyleConnectorFn.Statements.Add(casEvent);
                    _ccRoot.StyleConnectorFn.Statements.Add(casHandler);
                    _ccRoot.StyleConnectorFn.Statements.Add(new CodeExpressionStatement(cmieAdd));
                }
                else
                {
                    ccsConnector.TrueStatements.Add(casES);
                    ccsConnector.TrueStatements.Add(casEvent);
                    ccsConnector.TrueStatements.Add(casHandler);
                    ccsConnector.TrueStatements.Add(new CodeExpressionStatement(cmieAdd));
                    // Only add if statement at start of new scope
                    if (!xamlClrEventNode.IsSameScope)
                    {
                        _ccRoot.StyleConnectorFn.Statements.Add(ccsConnector);
                    }
                }
            }
            else
            {

                //
                // ((Foo)target).Bar += new BarEventHandler(OnBar);
                //
                // *or*
                //
                // ((Foo)target).AddHandler( Baz.BarEvent, new BarEventHandler(OnBar));
                //

                CodeCastExpression cceTarget;
                Type eventTarget;


                // Create the markup event information

                MarkupEventInfo mei = new MarkupEventInfo( xamlClrEventNode.Value,          // Event handler string
                                                           xamlClrEventNode.EventName,      // Event name string
                                                           xamlClrEventNode.EventMember,    // MemberInfo
                                                           xamlClrEventNode.LineNumber);    // LineNumber


                // Get the type that defines the event (e.g. typeof(Button) for Button.Clicked or typeof(Mouse) for Mouse.MouseMove)

                eventTarget = xamlClrEventNode.ListenerType;


                // Create the type cast expression "(Foo)target"

                cceTarget = new CodeCastExpression( eventTarget, careTarget);


                // Create the whole code statement (either in += form or in AddHandler form)

                CodeStatement csAddCLREvent = AddCLREvent( eventTarget, null, cceTarget, mei );

                if (SwitchStatementSupported())
                {
                    _ccRoot.StyleConnectorFn.Statements.Add( csAddCLREvent );
                }
                else
                {
                    ccsConnector.TrueStatements.Add( csAddCLREvent );

                    // Only add if statement at start of new scope
                    if (!xamlClrEventNode.IsSameScope)
                    {
                        _ccRoot.StyleConnectorFn.Statements.Add(ccsConnector);
                    }
                }
            }
        }
        /// <summary>
        /// override of WriteDynamicEvent
        /// </summary>
        public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode)
        {
            bool isStyleEvent = (xamlClrEventNode.IsStyleSetterEvent || xamlClrEventNode.IsTemplateEvent);
            bool localEvent = _compiler.LocalAssembly == xamlClrEventNode.EventMember.ReflectedType.Assembly;

            if (isStyleEvent)
            {
                if (localEvent)
                {
                    // validate the event handler name per CLS grammar for identifiers
                    _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value);
                    xamlClrEventNode.LocalAssemblyName = _compiler.AssemblyName;
                    // Pass2 should always be true here as otherwise localEvent will be false, but just being paranoid here.
                    if (_pass2)
                    {
                        XamlTypeMapper.HasInternals = true;
                    }
                }
                else
                {
                    if (!xamlClrEventNode.IsSameScope)
                    {
                        _connectionId++;
                    }

                    xamlClrEventNode.ConnectionId = _connectionId;

                    if (!_pass2)
                    {
                        _compiler.ConnectStyleEvent(xamlClrEventNode);
                    }
                }

                return;
            }

            bool appEvent = KnownTypes.Types[(int)KnownElements.Application].IsAssignableFrom(xamlClrEventNode.EventMember.DeclaringType);

            if (!appEvent)
            {
                if (!_pass2)
                {
                    // validate the event handler name per CLS grammar for identifiers
                    _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value);

                    if (_events == null)
                        _events = new ArrayList();

                    _events.Add(new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value,
                                                                   xamlClrEventNode.EventName,
                                                                   xamlClrEventNode.EventMember,
                                                                   xamlClrEventNode.LineNumber));
                }

                // if not local event ...
                if (!localEvent)
                {
                    WriteConnectionId();
                }
            }
            else if (!_pass2)
            {
                // Since Application is not an Element it doesn't implement IComponentConnector and
                // so needs to add events directly.
                MarkupCompiler.MarkupEventInfo mei = new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value,
                                                                                        xamlClrEventNode.EventName,
                                                                                        xamlClrEventNode.EventMember,
                                                                                        xamlClrEventNode.LineNumber);
                _compiler.AddApplicationEvent(mei);
            }

            if (_pass2)
            {
                // if local event, add Baml Attribute Record for local event
                if (localEvent)
                {
                    // validate the event handler name per C# grammar for identifiers
                    _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value);

                    XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber,
                                                                             xamlClrEventNode.LinePosition,
                                                                             xamlClrEventNode.Depth,
                                                                             xamlClrEventNode.EventMember,
                                                                             _compiler.AssemblyName,
                                                                             xamlClrEventNode.EventMember.ReflectedType.FullName,
                                                                             xamlClrEventNode.EventName,
                                                                             xamlClrEventNode.Value,
                                                                             BamlAttributeUsage.Default,
                                                                             false);

                    XamlTypeMapper.HasInternals = true;

                    base.WriteProperty(xamlPropertyNode);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Write out the Clr event.
        /// </summary>
        public virtual void WriteClrEvent(XamlClrEventNode xamlClrEventNode)
        {
            // Parser currently doesn't support hooking up Events directly from
            // XAML so throw an exception. In the compile case this method
            // is overriden.

            if (null == ParserHooks)
            {
                ThrowException(SRID.ParserNoEvents,
                    xamlClrEventNode.LineNumber,
                    xamlClrEventNode.LinePosition);
            }
            else if (BamlRecordWriter != null)
            {
                BamlRecordWriter.WriteClrEvent(xamlClrEventNode);
            }
        }
 internal void WriteClrEvent(XamlClrEventNode xamlClrEventNode)
 {
     // This should have been overridden by AC to catch the CLR event case before
     // this point is reached.  If not it means we have a designer which
     // should have been given the pertinent information, so keep this as a placeholder,
     // but don't do anything now.
 }
Пример #7
0
        private void ProcessEventSetterNode(XamlEndAttributesNode xamlEndAttributesNode) 
        {
            // Check for EventSetter properties. These aren't really stored as properties but 
            // resolved at the EventSetter end tag as events by the compiler 
            Debug.Assert(_inEventSetter);
 
            string member = _event;
            MemberInfo memberInfo = GetPropertyOrEventInfo(xamlEndAttributesNode, ref member);
            // If we have an event setter on a locally defined component, write it out
            // as a property instead of an event so that it will be resolved at runtime. 
            if (null != memberInfo)
            { 
                XamlClrEventNode eventNode = new XamlClrEventNode( 
                    xamlEndAttributesNode.LineNumber,
                    xamlEndAttributesNode.LinePosition, 
                    xamlEndAttributesNode.Depth,
                    member,
                    memberInfo,
                    _handler); 
#if HANDLEDEVENTSTOO
                eventNode.HandledEventsToo = _handledEventsToo; 
#endif 
                WriteClrEvent(eventNode);
            } 

            _event = null;
            _handler = null;
#if HANDLEDEVENTSTOO 
            _handledEventsToo = false;
#endif 
        } 
Пример #8
0
        /// <summary> 
        /// Write an Event Connector and call the controlling compiler parser to generate event hookup code.
        /// </summary> 
        public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode)
        {
            if (_previousXamlParser != null)
            { 
                if (_styleModeStack.Mode != StyleMode.Setters)
                { 
                    ThrowException(SRID.StyleTargetNoEvents, 
                        xamlClrEventNode.EventName,
                        xamlClrEventNode.LineNumber, 
                        xamlClrEventNode.LinePosition);
                }

                // if this event token is not owned by this StyleXamlParser, then just chain 
                // the WriteClrEvent call to the controlling parser. Ulimately, this will
                // reach the markup compiler that will deal with this info as appropriate. 
 
                bool isOriginatingEvent = xamlClrEventNode.IsOriginatingEvent;
                if (isOriginatingEvent) 
                {
                    // set up additional state on event node for the markup compiler to use.
                    Debug.Assert(!xamlClrEventNode.IsTemplateEvent && _inEventSetter);
                    xamlClrEventNode.IsStyleSetterEvent = _inEventSetter; 
                    xamlClrEventNode.IsSameScope = _isSameScope;
 
                    // any intermediary controlling parsers need to get out of the way so that 
                    // the markup compiler can ultimately do its thing.
                    xamlClrEventNode.IsOriginatingEvent = false; 
                }

                _previousXamlParser.WriteClrEvent(xamlClrEventNode);
 
                if (isOriginatingEvent)
                { 
                    if (!String.IsNullOrEmpty(xamlClrEventNode.LocalAssemblyName)) 
                    {
                        // if this event is a local event need to generate baml for it now 

                        string assemblyName = KnownTypes.Types[(int)KnownElements.EventSetter].Assembly.FullName;

                        base.WriteElementStart(new XamlElementStartNode(XamlNodeType.ElementStart, 
                                                                        xamlClrEventNode.LineNumber,
                                                                        xamlClrEventNode.LinePosition, 
                                                                        xamlClrEventNode.Depth, 
                                                                        assemblyName,
                                                                        KnownTypes.Types[(int)KnownElements.EventSetter].FullName, 
                                                                        KnownTypes.Types[(int)KnownElements.EventSetter],
                                                                        null /*serializerType*/,
                                                                        false /*isEmptyElement*/,
                                                                        false /*needsDictionaryKey*/, 
                                                                        false /*isInjected*/));
 
                        XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber, 
                                                                                 xamlClrEventNode.LinePosition,
                                                                                 xamlClrEventNode.Depth, 
                                                                                 null,
                                                                                 xamlClrEventNode.LocalAssemblyName,
                                                                                 xamlClrEventNode.EventMember.ReflectedType.FullName,
                                                                                 xamlClrEventNode.EventName, 
                                                                                 xamlClrEventNode.Value,
                                                                                 BamlAttributeUsage.Default, 
                                                                                 false); 
                        base.WriteProperty(xamlPropertyNode);
 
                        base.WriteElementEnd(new XamlElementEndNode(xamlClrEventNode.LineNumber,
                                                                    xamlClrEventNode.LinePosition,
                                                                    xamlClrEventNode.Depth));
                    } 
                    else
                    { 
                        // write out a connectionId to the baml stream only if a 
                        // new event scope was encountered
                        if (!_isSameScope) 
                        {
                            base.WriteConnectionId(xamlClrEventNode.ConnectionId);
                        }
 
                        // We have just finished processing the start of a new event scope.
                        // So specifiy start of this new scope. 
                        _isSameScope = true; 
                    }
                } 
            }
        }