Bryan Sampica

Freakyuno's wanderings in the .NET world.

  • Global BusyIndicator for DomainContext

    Just a short post to help out some poor soul dealing with some of the same issues I did before it hit me like a cream pie (right in the face).

    The Scenario:

    I’ve got a Silverlight 4 LOB Application, that will need to heavily use a BusyIndicator during loading operations (when I cant do them in the background) to keep users from clicking things and getting confused.

    When I fired up the application months and months ago, I had the foresight to include the busy indicator in a global accessible place to use it as part of the main application framework.

    If you have not done this before, you can implement it as follows:

    Open your App.xaml.cs file inside your project.  The overall idea is pretty simple.  Rather than loading a “Grid” into the Silverlight object container, we are going to load a Busy Indicator, and then put our main loading page inside that.  Here’s how:

    First, lets wire up an BusyIndicator

    public partial class App : Application
        {
            private BusyIndicator progressIndicator;

     

    There are several ways you could do this, this is just the way I chose to.  You’ll need to make sure you have a reference to, and a using statement to the following assembly

    using System.Windows.Controls;

    Once we have our indicator wired up, it’s pretty easy to shift things around a little, and load that into a reserved property setup for us by the nice Silverlight Developers, called the “RootVisual”

    public App()
    {
          this.Startup += this.Application_Startup;
               
          InitializeComponent();
    }
    private void Application_Startup(object sender, StartupEventArgs e)
    {
            InitializeRootVisual();            
    }
     protected virtual void InitializeRootVisual(bool isStartup)
    {
                this.progressIndicator = new BusyIndicator();
                
                this.Resources.Add("MainProgress", this.progressIndicator);
                this.progressIndicator.HorizontalAlignment = HorizontalAlignment.Stretch;
                this.progressIndicator.VerticalAlignment = VerticalAlignment.Stretch;
    
                //Replace new MainPage() with the name of your starting xaml page;
                this.progressIndicator.Content = new MainPage();
            
    
                this.RootVisual = this.progressIndicator;
     }

    Ok, so now that we have this wired up to use, you can test its working by setting the progressIndicator.IsBusy property to either “true” or “false” to toggle it, and see it running in application. 

    At this point though, it’s far from useful, we need it to be semi aware of what’s going on, when it needs to show, and when it should go away.

    Wiring it to your domain context:

    If your application is like mine, I’m not using any fancy context managers, or factory context handlers giving me an operating instance.  Rather I instantiate a context in a page when I need to do something, and terminate and dispose it when I’m done.  To keep hold of what’s going on with my context on the client side, I monitor calls coming into the server and make sure none of them go errant, but thats another post, and that does not help a client side progress bar.  So what do we do?  Good question:

    The "reference” that we get through generated code, is lucky made partial so we are able to get our fingers into it on the client side.  We can’t do a whole lot, but we can do what we need to do:

    So here’s how I got started.  In my Client Side (Silverlight) project, I create a new class with the same name as my server side context.  In this case we’ll refer to it as “MyDomainContext”

    using System;
    using System.Windows.Controls;
    using IQ.Client;
    
    namespace My.ServerProject.Services
    {
        public partial class MyDomainContext
        {
            BusyIndicator busy = (BusyIndicator)App.Current.RootVisual;
            public override System.ServiceModel.DomainServices.Client.LoadOperation Load(System.ServiceModel.DomainServices.Client.EntityQuery query, System.ServiceModel.DomainServices.Client.LoadBehavior loadBehavior, Action<System.ServiceModel.DomainServices.Client.LoadOperation> callback, object userState)
            {
                this.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(MyDomainContext_PropertyChanged);
                this.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(MyDomainContext_PropertyChanged);
                  
                return base.Load(query, loadBehavior, callback, userState);
            }
    
            void MyDomainContext_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                if (e.PropertyName == "IsLoading" && this.IsLoading == true)
                {
                    busy.IsBusy = true;
                }
                else if (e.PropertyName == "IsLoading" && this.IsLoading == false)
                {
                    busy.IsBusy = false;
                }
            }
        }
    }

    Keep in mind, this is ALL on the client side.  Dont forget to change your namespace to the server side namespace.  If you’re a little confused as to what’s going on, don’t feel bad.  It took me a minute to wrap my head around it too.  You are NOT sharing a partial class across a service boundary. 

    This works because of the Proxy class generated code that having a RIA services project throws into the Silverlight application.  The partial class gets generated in a hidden file, and we are going to extend the partial.

    You can see by the class extension, that we are waiting for a load operation to be called, and then tapping into the PropertyChanged Callback.  We remove an existing reference of the callback and wire up a new one so we don’t keep adding callbacks on each subsequent call.

    Note:

    This is just a quick example external to my actual running project, I am well aware that adding and removing event handlers like that will not work when there is more than one calling thread…etc.  Use this to create your own implementation that works in your scenario.

    Good Luck!

    Bryan Sampica

    Read more...

  • Twtpoll auto voter

    Just a short entry today on a fun little project I came across.  I had a friend that for “educational purposes” wanted to know how to write a little WPF program that would Auto Vote on a twtpoll poll that was enabled for a 24 hour period.

    Read more...

  • Silverlight 4

    So the Silverlight platform has been quite interesting for some time in concept, and had some niche abilities that made it perfect for streaming media, or writing simple rich applications.  Around the time of Silverlight 3 things started to get interesting;  as the tools developed, and the platform matured!

    Enter, Silverlight 4!

    For those of you that have been waiting to adopt this technology into your own development lifecycle, I truly believe your wait is over.  Difficult or downright impossible things inside Silverlight applications have now been overcome.  Limitations such as Printing, Local File Access, mouse scroll wheel support, and out of browser experiences.

    There has been a huge stir of Silverlight 4 activity at PDC09 this year (where they handed out free multi-touch windows 7 laptops to every attendee!!!) - yea, I know.  And some very cool demo's being displayed.  Watching the live stream (http://microsoftpdc.com/) during conference hours, left me intrigued enough to want to fire up and start to prototype some applications on the Silverlight 4 platform.

    As I went looking, it took me a little longer than I would have liked to find all the things I needed to get started and give it an accurate test drive, so below is the link (link aggregation) on how to get started.

    http://silverlight.net/getstarted/silverlight-4-beta/#tools

    I know...the silverlight site.  Unfortunatly as a developer and MVP I'm used to finding what I need published under the MSDN downloads section, linear thinking FTW.

    Dont forget as you get started to pop over to the videos located here:  All VERY good information

    http://silverlight.net/learn/videos/silverlight-4-beta-videos/

    I'm in process of wiring up an artist (photo) gallery currently, using Silverlight 4, RIA Services, and the new Toolkit, using Visual Studio 2010 of course.  So far I'm VERY impressed with the platform and where it's gone - it's finally at the point where I just dont feel like there's anything missing as previously.

     Good luck!

    Read more...