Ejemplo n.º 1
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        internal void AddApplicationEvent(MarkupEventInfo mei)
        {
            // validate the event handler name per C# grammar for identifiers
            ValidateEventHandlerName(mei.eventName, mei.eventHandler);

            // this.FooEvent += new FooEventHandlerDelegate(this.OnFoo);
            CodeThisReferenceExpression ctre = new CodeThisReferenceExpression();
            CodeStatement csEvent = AddCLREvent(_ccRoot, ctre, mei);

            Debug.Assert(_ccRoot == (_codeContexts.Peek() as CodeContextRoot));
            _ccRoot.EnsureInitializeComponentFn.Statements.Add(csEvent);
        }
Ejemplo n.º 3
0
        private CodeStatement AddCLREvent(Type eventTarget, CodeContext cc, CodeExpression ce, MarkupEventInfo mei)
        {

            bool subClassed = _ccRoot.SubClass.Length > 0;
            CodeStatement csEvent = null;
            // param2: <FooEventHandler>
            CodeExpression cDelExp = GetEventDelegate(cc, mei.mi, mei.eventName, mei.eventHandler);

            if (mei.mi.DeclaringType.IsAssignableFrom(eventTarget))
            {
                // _element.FooEvent += new FooEventHandlerDelegate(OnFoo);
                csEvent = new CodeAttachEventStatement(ce, mei.eventName, cDelExp);
            }
            else if (eventTarget == null || // for known attached events on unknown local tags
                     KnownTypes.Types[(int)KnownElements.UIElement].IsAssignableFrom(eventTarget) ||
                     KnownTypes.Types[(int)KnownElements.ContentElement].IsAssignableFrom(eventTarget))
            {
                // _element.AddHandler(FooEvent, new FooEventHandlerDelegate(OnFoo));
                CodeFieldReferenceExpression cfreEvent = GetEvent(mei.mi, mei.eventName, mei.eventHandler);
                CodeMethodInvokeExpression cmieAddHandler = new CodeMethodInvokeExpression(ce, ADDHANDLER, cfreEvent, cDelExp);
                csEvent = new CodeExpressionStatement(cmieAddHandler);
            }
            else
            {
                string eventTargetName = eventTarget != null ? eventTarget.FullName : cc.LocalElementFullName;
                ThrowCompilerException(SRID.UnknownEventAttribute, mei.eventName, mei.eventHandler, eventTargetName);
            }

            // When x:SubClass is used, event handlers can be specified in a code-behind file, under this sub class.
            // But these handler methods need to be accessible from the intermediary generated sub class. So an empty
            // internal virtual method with the same signature as the handler method is generated in this intermediary
            // sub class (in the generated file):
            //
            //      internal virtual void OnFooEvent(object sender, FooEventArgs ea)
            //      {
            //      }
            //
            // Since a delegate cannot take the address of a virtual function, a non-virtual helper function
            // with the same signature as the above function & which calls the above function is also generated:
            //
            //      private void OnFooEventHelper(object sender, FooEventArgs ea)
            //      {
            //          OnFooEvent(sender, ea);
            //      }
            //
            // All this is done only if x:Subclass is specified, since this means that this sub class would need to be
            // defined in a code-behind file. This also means that inline events (in <x:Code>) will not be supported.

            if (subClassed)
            {
                GenerateProtectedEventHandlerMethod(mei);
            }

            AddLinePragma(csEvent, mei.lineNumber);
            return csEvent;
        }
Ejemplo n.º 4
0
        private void GenerateProtectedEventHandlerMethod(MarkupEventInfo mei)
        {
            Debug.Assert(_ccRoot != null && _ccRoot.SubClass.Length > 0);

            // Fetch the EventHandlerType from either the EventInfo or the MethodInfo
            // for the Add{Propertyname}Handler method's MethodInfo
            Type eventHandlerType = GetEventHandlerType(mei.mi);

            MethodInfo methodInvoke = eventHandlerType.GetMethod("Invoke");
            ParameterInfo[] pars = methodInvoke.GetParameters();

            CodeMemberMethod cmmEventHandler = new CodeMemberMethod();
            CodeMemberMethod cmmEventHandlerHelper = new CodeMemberMethod();

            AddDebuggerNonUserCodeAttribute(cmmEventHandlerHelper);
            AddGeneratedCodeAttribute(cmmEventHandlerHelper);

            cmmEventHandler.Attributes = MemberAttributes.Assembly | MemberAttributes.Overloaded;
            cmmEventHandler.ReturnType = new CodeTypeReference(typeof(void));
            cmmEventHandler.Name = mei.eventHandler.Trim();

            CodeMethodInvokeExpression cmieOnEvent = new CodeMethodInvokeExpression(null, cmmEventHandler.Name);

            for (int i = 0; i < pars.Length; i++)
            {
                CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(pars[i].ParameterType, pars[i].Name);
                cmmEventHandler.Parameters.Add(param);
                cmmEventHandlerHelper.Parameters.Add(param);
                cmieOnEvent.Parameters.Add(new CodeArgumentReferenceExpression(pars[i].Name));
            }

            //
            // internal virtual void OnFooEvent(object sender, FooEventArgs ea)
            // {
            // }
            //
            _ccRoot.CodeClass.Members.Add(cmmEventHandler);

            cmmEventHandlerHelper.Name = cmmEventHandler.Name + HELPER;
            cmmEventHandlerHelper.ReturnType = new CodeTypeReference(typeof(void));
            cmmEventHandlerHelper.Statements.Add(new CodeExpressionStatement(cmieOnEvent));

            //
            // private void OnFooEventHelper(object sender, FooEventArgs ea)
            // {
            //     OnFooEvent(sender, ea);
            // }
            //
            _ccRoot.CodeClass.Members.Add(cmmEventHandlerHelper);
        }
Ejemplo n.º 5
0
 private CodeStatement AddCLREvent(CodeContext cc, CodeExpression ce, MarkupEventInfo mei)
 {
     // Infer the event target's (aka the listener) type from the current code context
     return AddCLREvent( cc.ElementType, cc, ce, mei );
 }