NEW FEATURE: Wait Indicator Control

87 views
Skip to first unread message

Rishi Oberoi

unread,
Jan 11, 2011, 6:44:00 AM1/11/11
to nro...@googlegroups.com
One of the new controls I've added is the WaitIndicator Control - it's basically a control that can block the screen and shows a visual indicator to indicate it's working. Further, it supports two properties, one a bool IsWorking property and another a Title property to show a message. So it is nothing special, except it implements an IIndicatorViewService interface that looks like:

    public interface IIndicatorViewService
    {
        IDisposable RegisterIndicator();

        IDisposable RegisterIndicator(TimeSpan timeout);
    }

What this interface allows us to do is to get a IDisposable token that would indicate that we are doing some work, and so the control would keep showing that it is working until we dispose the token. Not only that, but it also supports that multiple such tokens can be take-out at the same time, so imagine two (or more) ViewModels can take such tokens and until both of them dispose off the indicator would keep indicating it's working. And as you can see above, one of the options allows you to also specify a timeout - so in-case you don't dispose within the specified time, the control would automatically time it out for you if you specified a timeout. 

My idea with this control and supporting interface is to have one such control at the shell-level and so when-ever I'm doing some work I can block off the entire UI or part of UI input. And the tokens design would ensure that there is no contention between various consumers. Further, to ensure we don't start leaking memory, all issued tokens are weakly-referenced, this ensures the token subscribers don't inevitably outlive their lifetimes. 

Another idea with this is to ensure it is MVVM friendly, as so you really you can use it as so in your ViewModel:
        [ResolveConstructor]
        public TestViewModel(IIndicatorViewService indicatorViewService)
        {
            if (indicatorViewService == nullthrow new ArgumentNullException("indicatorViewService");
            _indicatorViewService = indicatorViewService;
            _indicatorToken = _indicatorViewService.RegisterIndicator();
        }
This should disconnect you from the View-specifics, and really you are just using it as any other ViewService (see http://www.orktane.com/Blog/post/2009/10/23/Web-Xcel-Demo-View-Services-in-nRoute.aspx). However, if you know ViewServices, it is a must that we should register it. And to enable registering a visual-tree/live instance I've create a specific behavior - it's use is something like:

    	<nControls:WorkIndicator IsWorking="True">
     <i:Interaction.Behaviors>
     <nBehaviors:IndicatorViewServiceBehavior ViewServiceName="DefaultIndicator" IsDefault="True"/>
     </i:Interaction.Behaviors>
     </nControls:WorkIndicator>
 
Now, you could get the instance either by a specific name or if like above it is registered as being the default instance you don't need to specify a name. Note, to get any name-specific resource in nRoute, use the ResolveResource attribute as such:

        [ResolveConstructor]
        public TestViewModel([ResolveResource("DefaultIndicator")]IIndicatorViewService indicatorViewService)
        {
            ...
        }

Further, the control is fully re-templatable - so you can change its visuals entirely as you like. Though note for WP7, I've used the special dot like progress-bar like animation which has performance implications (see http://www.codeproject.com/KB/showcase/WP7-Performance.aspx). Also, you could choose to implement the indicator totally differently, as you could provide your own implementation of IIndicatorService and register the same. Lastly, if you choose, you can make the waiting-indicator non-blocking by setting its background to be null and/or setting it as being not hit test visible. 

This is not 100% finalized, but I hope you get the idea/need for such a control.
Cheers,

Rishi

Gerhard Kreuzer

unread,
Jan 11, 2011, 7:57:46 AM1/11/11
to nro...@googlegroups.com
Hi Rishi,
 
that's a fine thing.
 
You talk about blocking only parts of the UI, but can't see, where the parameters go, and which parameter values needed to do that. Hope, there will be some documentation and/or sample for that.
If I am able to block parts of the UI, it's not longer a working indicator anymore, it's also a control unit, which allows to block parts on some conditions like state of UI or data content, mode, access rules or something like this.
 
With best regards
 
Gerhard
 


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Rishi Oberoi
Gesendet: Dienstag, 11. Jänner 2011 12:44
An: nro...@googlegroups.com
Betreff: [nRoute] NEW FEATURE: Wait Indicator Control

John Thiriet

unread,
Jan 11, 2011, 8:06:52 AM1/11/11
to nro...@googlegroups.com
Hi,

From what I understand this control enables to block a navigation container. Therefore the parameter needed to block only a part of the UI is the navigation container's name.
If I understood it correctly I'll add that I think it's pretty restrictive to be able to use it only with a navigation container.

Am I wrong ?

2011/1/11 Gerhard Kreuzer <gerhard...@liftoff.at>



--
------------------------
John Thiriet
Ingénieur d'étude
Pôle DotNET
MCNext
+33629141455

Adrian Hara

unread,
Jan 11, 2011, 8:12:16 AM1/11/11
to nro...@googlegroups.com

Looks cool, but I’ve one question about it. My use-case is that besides a “global” wait indicator I also need “local” indicators, for example a view could be made up of several containers each navigated to its own mini-view which loads and waits independently of the “big picture”. So I guess for this case I would resolve a named indicator specific to that view, using the approach you proposed so far. While this works I don’t like it a bit because the view-model would know a bit too much about the view, e.g. which named resource to get. My approach has been to just have a IsBusy property on the viewmodel and then have a waitindicator that toggles itself based on a binding to that property. Indeed for the global wait state I had a service that could be called, since the other approach doesn’t work.

 

So I guess the question is if this would be also the way to go with your proposed solution: for the global indicator use the behavior to register a service that can be called to trigger global waiting, while for local waiting just bind the IsWorking property and not use a service/behavior at all?

 

Thanks!

 

Freundliche Grüsse / Best regards

Adrian Hara
Cloud Developer
LinkedIn 


coresystems ag
Villa im Park | Dorfstrasse 69
5210 Windisch | Switzerland


Phone +41 56 500 22 22
Fax +41 56 444 20 50
Infoline +41 848 088 088
www.coresystems.ch
www.coresuite.com
follow us on
twitter

SAP Gold Partner (SSP)
Deutsche Telekom Audience Innovation Prize 2010
Best of Swiss Silverlight 2010 Gold Winner
Announced by Gartner as a Cool Vendor 2010

The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and / or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Rishi Oberoi

unread,
Jan 11, 2011, 8:30:46 AM1/11/11
to nRoute
@Gerhard this control is generic and doesn't "block" any control per
se it just blocks the airspace really. And all you need to do is put
this control above (in terms of the airspace) any one or more
controls, and it would block access to it. Now, I could further and do
other tricks to "really" block the controls, but for now this just
blocks the airspace above any control. Alternatively, you can choose
to not block the airspace, and just show an indicator. Also, samples
will come later :)

@John, no this doesn't pertain to a navigation control only, it's
generic just like any other progress/work indicators out there. The
main idea is that it can be used from VMs, and one or more consumers
can work together to block UI till they are all done. Note I say
consumers, because you could take two tokens in the same VM - say for
example if you are loading a customers list and products list - and by
taking two tokens until both of them are disposed the UI will be
blocked.

Hope this clears the intent,
Rishi


On Jan 11, 4:06 pm, John Thiriet <gro...@gmail.com> wrote:
> Hi,
>
> From what I understand this control enables to block a navigation container.
> Therefore the parameter needed to block only a part of the UI is the
> navigation container's name.
> If I understood it correctly I'll add that I think it's pretty restrictive
> to be able to use it only with a navigation container.
>
> Am I wrong ?
>
> 2011/1/11 Gerhard Kreuzer <gerhard.kreu...@liftoff.at>
>
>
>
>
>
>
>
>
>
> >  Hi Rishi,
>
> > that's a fine thing.
>
> > You talk about blocking only parts of the UI, but can't see, where the
> > parameters go, and which parameter values needed to do that. Hope, there
> > will be some documentation and/or sample for that.
> > If I am able to block parts of the UI, it's not longer a working indicator
> > anymore, it's also a control unit, which allows to block parts on some
> > conditions like state of UI or data content, mode, access rules or something
> > like this.
>
> > With best regards
>
> > Gerhard
>
> >  ------------------------------
> > *Von:* nro...@googlegroups.com [mailto:nro...@googlegroups.com] *Im
> > Auftrag von *Rishi Oberoi
> > *Gesendet:* Dienstag, 11. Jänner 2011 12:44
> > *An:* nro...@googlegroups.com
> > *Betreff:* [nRoute] NEW FEATURE: Wait Indicator Control
> >http://www.orktane.com/Blog/post/2009/10/23/Web-Xcel-Demo-View-Servic...).

Rishi Oberoi

unread,
Jan 11, 2011, 8:44:11 AM1/11/11
to nRoute
Yes, this can be used "directly" by toggling (via binding) the
IsWorking property. However, I'm looking into ways so that we can get
hold of the wait-indicator control as IIndicatorViewService from your
VM's View - this would allow you to use the indicator as
IIndicatorViewService rather than exposing an IsBusy property. I think
the token is a superior model, as it easily allows you to coordinate
one or more tasks. However, you have both the options, if you so
choose.

Lastly, the issue regarding TMI about the View is questionable, as
really the names (if used) are relegated to meta-data and your VM gets
to deal with a much more purposeful IIndicatorViewService interface.

Cheers,
Rishi


On Jan 11, 4:12 pm, Adrian Hara <Adrian.H...@coresystems.ch> wrote:
> Looks cool, but I've one question about it. My use-case is that besides a "global" wait indicator I also need "local" indicators, for example a view could be made up of several containers each navigated to its own mini-view which loads and waits independently of the "big picture". So I guess for this case I would resolve a named indicator specific to that view, using the approach you proposed so far. While this works I don't like it a bit because the view-model would know a bit too much about the view, e.g. which named resource to get. My approach has been to just have a IsBusy property on the viewmodel and then have a waitindicator that toggles itself based on a binding to that property. Indeed for the global wait state I had a service that could be called, since the other approach doesn't work.
>
> So I guess the question is if this would be also the way to go with your proposed solution: for the global indicator use the behavior to register a service that can be called to trigger global waiting, while for local waiting just bind the IsWorking property and not use a service/behavior at all?
>
> Thanks!
>
> Freundliche Grüsse / Best regards
> Adrian Hara
> Cloud Developer
> LinkedIn<http://www.linkedin.com/profile?viewProfile=&key=17921793&locale=en_U...>
> ________________________________
> coresystems ag
> Villa im Park | Dorfstrasse 69
> 5210 Windisch | Switzerland
>
> Phone +41 56 500 22 22
> Fax +41 56 444 20 50
> Infoline +41 848 088 088www.coresystems.ch<http://www.coresystems.ch/>www.coresuite.com<http://www.coresuite.com/>
> follow us on twitter<http://twitter.com/coresuite>
>
> SAP Gold Partner (SSP)
> Deutsche Telekom Audience Innovation Prize 2010
> Best of Swiss Silverlight 2010 Gold Winner
> Announced by Gartner as a Cool Vendor 2010<http://www.gartner.com/technology/research/offer/cool-vendors.jsp>
> The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and / or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.
> From: nro...@googlegroups.com [mailto:nro...@googlegroups.com] On Behalf Of Rishi Oberoi
> Sent: Tuesday, January 11, 2011 1:44 PM
> To: nro...@googlegroups.com
> Subject: [nRoute] NEW FEATURE: Wait Indicator Control
>
> One of the new controls I've added is the WaitIndicator Control - it's basically a control that can block the screen and shows a visual indicator to indicate it's working. Further, it supports two properties, one a bool IsWorking property and another a Title property to show a message. So it is nothing special, except it implements an IIndicatorViewService interface that looks like:
>
>     public interface IIndicatorViewService
>     {
>         IDisposable RegisterIndicator();
>
>         IDisposable RegisterIndicator(TimeSpan timeout);
>     }
>
> What this interface allows us to do is to get a IDisposable token that would indicate that we are doing some work, and so the control would keep showing that it is working until we dispose the token. Not only that, but it also supports that multiple such tokens can be take-out at the same time, so imagine two (or more) ViewModels can take such tokens and until both of them dispose off the indicator would keep indicating it's working. And as you can see above, one of the options allows you to also specify a timeout - so in-case you don't dispose within the specified time, the control would automatically time it out for you if you specified a timeout.
>
> My idea with this control and supporting interface is to have one such control at the shell-level and so when-ever I'm doing some work I can block off the entire UI or part of UI input. And the tokens design would ensure that there is no contention between various consumers. Further, to ensure we don't start leaking memory, all issued tokens are weakly-referenced, this ensures the token subscribers don't inevitably outlive their lifetimes.
>
> Another idea with this is to ensure it is MVVM friendly, as so you really you can use it as so in your ViewModel:
>
>         [ResolveConstructor]
>
>         public TestViewModel(IIndicatorViewService indicatorViewService)
>         {
>             if (indicatorViewService == null) throw new ArgumentNullException("indicatorViewService");
>
>             _indicatorViewService = indicatorViewService;
>
>             _indicatorToken = _indicatorViewService.RegisterIndicator();
>
>         }
> This should disconnect you from the View-specifics, and really you are just using it as any other ViewService (seehttp://www.orktane.com/Blog/post/2009/10/23/Web-Xcel-Demo-View-Servic...). However, if you know ViewServices, it is a must that we should register it. And to enable registering a visual-tree/live instance I've create a specific behavior - it's use is something like:
>
>          <nControls:WorkIndicator IsWorking="True">
>
>                  <i:Interaction.Behaviors>
>
>                           <nBehaviors:IndicatorViewServiceBehavior ViewServiceName="DefaultIndicator" IsDefault="True"/>
>
>                  </i:Interaction.Behaviors>
>
>          </nControls:WorkIndicator>
>
> Now, you could get the instance either by a specific name or if like above it is registered as being the default instance you don't need to specify a name. Note, to get any name-specific resource in nRoute, use the ResolveResource attribute as such:
>
>         [ResolveConstructor]
>         public TestViewModel([ResolveResource("DefaultIndicator")]IIndicatorViewService indicatorViewService)
>
>         {
>             ...
>         }
>
> Further, the control is fully re-templatable - so you can change its visuals entirely as you like. Though note for WP7, I've used the special dot like progress-bar like animation which has performance implications (seehttp://www.codeproject.com/KB/showcase/WP7-Performance.aspx). Also, you could choose to implement the indicator totally differently, as you could provide your own implementation of IIndicatorService and register the same. Lastly, if you choose, you can make the waiting-indicator non-blocking by setting its background to be null and/or setting it as being not hit test visible.

Gerhard Kreuzer

unread,
Jan 11, 2011, 9:09:38 AM1/11/11
to nro...@googlegroups.com
Hi Rishi,

Thanks. I think it must be some different to the .Enabled property of
controls, my WPF still isn't so good, sorry.
But blocking the airspace or showing some message when the user went into
that area is really cool.

With best regards

Gerhard

-----Ursprüngliche Nachricht-----


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von
Rishi Oberoi

Gesendet: Dienstag, 11. Jänner 2011 14:31
An: nRoute
Betreff: [nRoute] Re: NEW FEATURE: Wait Indicator Control

Rishi Oberoi

unread,
Jan 11, 2011, 10:52:31 AM1/11/11
to nro...@googlegroups.com
Well, actually a content-control type wait indicator control might not be a bad idea - however, if I remember correctly there might be issues with Silverlight, as it shuts down visual-tree processing when something isn't enabled or something like that but I have to double check. 

What do other guys, should I turn this into a wrapper-kind of control - that would essentially set the content to be disabled when waiting/working? In this case it won't be the airspace that would block content, but rather the pre-defined child content that would be blocked. 

Rishi

Rishi Oberoi

unread,
Jan 18, 2011, 5:59:58 AM1/18/11
to nro...@googlegroups.com
As a follow-up, I've updated the control to support the follow ViewService contract:

    public interface IShowIndicatorViewService
    {
        IDisposable ShowIndicator();

        IDisposable ShowIndicator(TimeSpan timeout);

        IDisposable ShowIndicator(string title);

        IDisposable ShowIndicator(string title, TimeSpan timeout);
    }

The updated contract allows one to specify a title to go with the working indication - the idea being if you are doing multiple things you can keep the user informed. Further, you can now toggle as to if the title will be shown via the ShowTitle property. Also, I've also updated the internal workings of the control to make the indicator calls to be queued to allow multiple concurrent users, which works quite like the StatusViewer control  (see https://groups.google.com/forum/?fromgroups#!topic/nroute/6UYn1vkB0io) - however, unlike the StatusViewer control the timeout starts once an indicator call is queued and not when it is shown.

Cheer,
Rishi

Reply all
Reply to author
Forward
0 new messages