6 Replies Latest reply on Sep 27, 2010 1:51 PM by Muaddib2004

    custom datagrid headerRenderer keeps redrawing

    Muaddib2004 Level 1

      I have two DataGrids.  One that uses default headerRenderers, and one that uses custom 'filterable' headerRenders for 5 of the column headers.

       

      Basically, the custom filterable headerRenderer is a VBox that holds a Label and a TextInput.  Typing in the textInput will hide items in that column that don't match the filter value entered.

       

      This issue is that each time I update these DataGrids' dataProvider, the DataGrid that employs the custom headerRenders flashes multiple times (redraws) which is very noticable -- it makes the page a little laggy.  If I override the 'data' setter and place a breakpoint in the custom headerRenderer, I see it is getting hit a ton of times! (even if there is only like 1 item in the data grid!) why is that?

       

      How can I stop this redraw from occuring?  Can I stop the custom headerRenderer from calling the data setter? I tried overriding the data setter, placing only a return in the method --- that didn't seem to help.

       

       

      Any suggestions?

       

      thanks,

      Muad'Dib

        • 1. Re: custom datagrid headerRenderer keeps redrawing
          Muaddib2004 Level 1

          just to give a little more insight....

           

          in my troubleshooting efforts I commented out all code in the custom headerRenderer class.  The code for the customer headerRenderer is effectively this:

           

           

          <?xml version="1.0" encoding="utf-8"?>
          <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
              width="100%"
              paddingTop="5"
              paddingBottom="5"
              paddingLeft="5"
              paddingRight="5"
              horizontalAlign="center"
              verticalGap="0">
              <mx:Script>
                  <![CDATA[
                      import mx.core.UITextField;
                  ]]>
              </mx:Script>
                  <mx:Label id="headerValueLabel"
                      height="20"
                      horizontalCenter="true"/>
                  <mx:TextInput id="textInputCtrl" width="90%"/>
          </mx:VBox>

           

          Even with this minimal code, the TextInput and Label get redrawn with each update to the dataProvider of the parent DataGrid.  How do I stop this redraw?  it is really obvious that each column header is being redrawn ....

           

          Thanks,

          Muad'Dib

          • 2. Re: custom datagrid headerRenderer keeps redrawing
            Flex harUI Adobe Employee

            I thought we added code to cache headers in 3.5 and 4.0

            • 3. Re: custom datagrid headerRenderer keeps redrawing
              Muaddib2004 Level 1

              I am constrained to version 3.0

              • 4. Re: custom datagrid headerRenderer keeps redrawing
                Muaddib2004 Level 1

                sorry.... make that v3.2.0

                 

                • 5. Re: custom datagrid headerRenderer keeps redrawing
                  pml984

                  I am having this same problem.  Were you ever able to figure out this problem?

                  • 6. Re: custom datagrid headerRenderer keeps redrawing
                    Muaddib2004 Level 1
                    sorry for the late response pml...
                    Yes, I did get this fixed. I wish I could say it was an easy fix to find! but it wasn't!
                    Basically, I had to keep the 'state' (data members I wanted displayed by the headerRenderer) of the renderer within the parent DataGrid component. I did this by:
                    1) Creating necessary headerRenderers using the ClassFactory (instead of inline MXML -- you can make the call to create the headers on the DataGrid's creationComplete event).
                    2) setting ClassFactory 'property' to an array of objects that map the headerRenderer to the Object that hold's it's 'State'.
                    3) overrode initializationComplete() method of headerRender and placed any initialization code here (in lieu of the 'data' setter).  This was where the implementation that actually does the mapping to the Object that holds this render's 'State' is done, based on the data that was placed into the 'properties' field from step 2.
                    here's a brief example:
                    DataGrid
                    ========
                       
                    <mx:Box styleName="BoxContent" width="100%" height="100%">
                        <mx:Script>
                            <![CDATA[
                                    public var greeting:String = "hello";
                                   public function createCustomHeaders():void {
                                         // create a factory that can produce your custom header
                                         var customRendererFactory:ClassFactory = new ClassFactory(MyCustomRendererClass);
                                         // set the properties of the factory to hold a reference to data
                                         // in THIS class (Box)
                                         customRendererFactory.properties = {stateHost: this, stateProperty: "greeting"};
                                   
                                         // set the data grid columns renderer now...
                                         dgc1.headerRenderer = customRendererFactory;
                                }]]>
                         </mx:Script>
                         <mx:DataGrid id="dg" dataProvider="{_myData}" creationComplete="createCustomHeaders()">
                            <mx:columns>
                                    <mx:DataGridColumn id="dgc1"
                                        textAlign="center"/>
                            </mx:columns>
                         </mx:DataGrid>
                    </mx:Box>
                    Renderer
                    ========
                    <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%">
                    <mx:Script>
                    <![CDATA[
                       
                        // reference to object that will hold any necessary state information
                        public var stateHost:Object;
                        public var stateProperty:String;
                                private var _greeting:String;
                                private var _greetingUpdated:Boolean;
                    override protected function initializationComplete():void {
                    if(_greeting != stateHost[stateProperty]){
                                        _greeting == stateHost[stateProperty]);
                                        _greetingUpdated = true;
                                        invalidateProperties();
                                    }
                    }
                               
                    override protected function commitProperties():void {
                                    super.commitProperties();
                    if(_greetingUpdated){
                    myLabel.text = (null != _greeting) ? _greeting : "";
                    }
                    }
                    ]]>
                    </mx:Script>
                        <mx:Label id="myLabel" width="100%"/>
                    </mx:VBox>