Ticket B220604
Visible to All Users
Duplicate

We have closed this ticket because another page addresses its subject:

How to automatically refresh data in a View after a certain period of time on the Web

How to implement auto refresh functionality on the Web

created 13 years ago

I migrated my application to v2011 vol 2 and it seems the auto refresh doesn't work anymore, whereas the exact same code in vol 1 did (and still does).
This is the code I'm using:
    public partial class ViewControllerAutoRefresh : ViewController
    {
        public ViewControllerAutoRefresh()
        {
            InitializeComponent();
            RegisterActions(components);
        }
        protected override void OnActivated()
        {
            base.OnActivated();
            if (View is ListView && View.IsRoot)
                Frame.TemplateChanged += Frame_TemplateChanged;
        }
        void Frame_TemplateChanged(object sender, EventArgs e)
        {
            if (Frame.Template == null)
                return;
            var page = (Page)Frame.Template;
            page.Init += page_Init;
        }
        void page_Init(object sender, EventArgs e)
        {
            if (View is ListView)
            {
                try
                {
                    const string timerID = "RefreshTimer";
                    var page = sender as Page;
                    if (page.FindControl(timerID) != null)
                        return;
                    var timer = new ASPxTimer
                    {
                        ID = timerID,
                        Interval = 10000,
                        Enabled = true
                    };
                    timer.Tick += timer_Tick;
                    if (page.Form != null)
                        page.Form.Controls.Add(timer);
                }
                catch
                {
                }
            }
        }
        void timer_Tick(object sender, EventArgs e)
        {
            if (View is ListView)
                ((ListView)View).CollectionSource.ObjectSpace.Refresh();
        }
    }

Show previous comments (5)

    Hi Konstantin,
    Thanks… Yes, this solution performs a refresh. However, it is still not clear to me how to cope with this issue.
    In the sample attached, the PagePreRender event is trapped, resulting in rendering the complete page (the timer_Tick event on the other hand is never fired).
    Basically, what I'm trying to achieve is the same behavior as when clicking the Refresh button (updating the GridView).
    The question is, how can I force the GridView (or more precisely, the panel containing teh GridView) to refresh on a timely basis???
    Thanks, Ad.

    Dennis Garavsky (DevExpress) 13 years ago

      Hi Ad,
      Thank you for the feedback. I should apologize for the inconvenience because my previous project was not fully functional.
      Please modify my previous controller as follows:

      C#
      public class MyViewController : ViewController<ListView> { protected override void OnFrameAssigned() { base.OnFrameAssigned(); if(Frame != null) { if(Frame.Template != null) { ((Page)Frame.Template).Load += new EventHandler(MyViewController_Load); } else { Frame.TemplateChanged += new EventHandler(Frame_TemplateChanged); } } } void Frame_TemplateChanged(object sender, EventArgs e) { if(Frame.Template != null) { ((Page)Frame.Template).Load += new EventHandler(MyViewController_Load); } } protected override void OnActivated() { base.OnActivated(); timer.Enabled = true; } protected override void OnDeactivated() { timer.Enabled = false; base.OnDeactivated(); } ASPxTimer timer; void MyViewController_Load(object sender, EventArgs e) { IMyCustomUpdatePanelHolder holder = Frame.Template as IMyCustomUpdatePanelHolder; if(holder != null) { timer = new ASPxTimer(); timer.Interval = 1000; timer.ID = "timer"; timer.Enabled = false; timer.Tick += new EventHandler(timer_Tick); holder.UpdataPanel.Controls.Add(timer); } } private void timer_Tick(object sender, EventArgs e) { } public MyViewController() : base() { TargetViewNesting = Nesting.Root; } }

      It seems to work fine in my tests. I look forward to hearing from you.
      Thanks,
      Konstantin M.

        Hi Konstantin,
        Based on your example I tried to make it work with the XafCallbackManager so the whole page wouldn’t reload, but just the gridview and actions (via ajax). I got this all to work using the following code.

        C#
        public partial class MyViewController : ViewController<ListView>, IXafCallbackHandler { ASPxTimer _timer; XafCallbackManager _callbackManager; public MyViewController() : base() { TargetViewNesting = Nesting.Root; TargetViewType = ViewType.ListView; } protected override void OnFrameAssigned() { base.OnFrameAssigned(); if (Frame != null) { if (Frame.Template != null) ((Page)Frame.Template).Load += new EventHandler(MyViewController_Load); else Frame.TemplateChanged += new EventHandler(Frame_TemplateChanged); } } void Frame_TemplateChanged(object sender, EventArgs e) { if (Frame.Template != null) ((Page)Frame.Template).Load += new EventHandler(MyViewController_Load); } protected override void OnActivated() { base.OnActivated(); if (View is ListView && View.IsRoot) { _callbackManager = GetCallbackManager(); _callbackManager.RegisterHandler("callbackHandler", this); IMyCustomUpdatePanelHolder holder = Frame.Template as IMyCustomUpdatePanelHolder; if (holder != null) { _timer = new ASPxTimer(); _timer.Interval = 1000; _timer.ID = "timer"; _timer.Enabled = true; _timer.ClientSideEvents.Tick = "function(f, e) { " + _callbackManager.GetScript("callbackHandler", "") + "}"; holder.UpdataPanel.Controls.Add(_timer); } } } protected override void OnDeactivated() { if (_timer != null) _timer.Enabled = false; base.OnDeactivated(); } void MyViewController_Load(object sender, EventArgs e) { _callbackManager = GetCallbackManager(); _callbackManager.RegisterHandler("callbackHandler", this); } public void ProcessAction(string parameter) { if (View is ListView) { ((ListView)View).CollectionSource.Reload(); ObjectSpace.Refresh(); } } private XafCallbackManager GetCallbackManager() { XafCallbackManager manager = null; if (Frame != null && Frame.Template != null) { ICallbackManagerHolder holder = Frame.Template as ICallbackManagerHolder; if (holder != null) { manager = holder.CallbackManager; } } return manager; } }

        While this works when entering the ListView page, when I navigate to a detailView page, after I visited the ListView page the refresh ASPxTimer control is still executing. Can tell me how I can disable the ASPxTimer when I leave the page, or is this approach completely off ??
        Thanks

        Answers approved by DevExpress Support

        created 13 years ago (modified 11 years ago)

        Hi Ad,
        To accomplish this task, I suggest that you try the following controller:

        C#
        public class MyController : ViewController<ListView> { const int Interval = 10000; private void grid_Load(object sender, EventArgs e) { ASPxGridView grid = (ASPxGridView)sender; grid.Load -= grid_Load; grid.ClientSideEvents.Init = string.Format("function(s,e){{ {0} }}", GetRefreshOnTimerFunctionBody(grid.ClientID, Interval)); } private string GetRefreshOnTimerFunctionBody(string gridId, int interval) { return string.Format("if(!window.{0}_timerIsSet) {{window.{0}_timerIsSet=true; window.setTimeout(function(){{ window.{0}_timerIsSet = false; if({0}) {{ {0}.PerformCallback('MyCallback');}} }}, {1});}}", gridId, Interval); } private void grid_CustomCallback(object sender, ASPxGridViewCustomCallbackEventArgs e) { if(e.Parameters == "MyCallback") { View.ObjectSpace.Refresh(); ASPxGridView grid = (ASPxGridView)sender; grid.JSProperties["cpEndCallbackHandlerRefreshOnTimer"] = GetRefreshOnTimerFunctionBody(grid.ClientID, Interval); grid.JSProperties[ASPxGridListEditor.EndCallbackHandlers] = "cpEndCallbackHandlerRefreshOnTimer;" + grid.JSProperties[ASPxGridListEditor.EndCallbackHandlers]; } } protected override void OnViewControlsCreated() { base.OnViewControlsCreated(); ASPxGridListEditor editor = View.Editor as ASPxGridListEditor; if(editor != null) { ASPxGridView grid = editor.Grid; grid.CustomCallback += grid_CustomCallback; grid.Load += grid_Load; } } }

        Hope this will help you.
        Thanks,
        Konstantin M
        UPDATE:
        This solution may cause the popup window to be unexpectedly closed under certain circumstances. Refer to the Auto-Refresh ListView without closing current popup thread to learn more on how to avoid this.

          Comments (2)

            In some cases it's possible that the user is dealing with an opened popup window. The above code causes this popup window to be closed. How can I check if there is any open popup window, ignore the refresh or refresh without closing the open popup windows (if any)?

            Dennis Garavsky (DevExpress) 11 years ago

              @Sina: We discussed how to solve this problem in the Auto-Refresh ListView without closing current popup ticket. I hope this helps. Otherwise, please create a separate ticket in the Support Center and attach your current implementation so we can assist you further.

              Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

              Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.