=======================================
DEVFORCE MVVM LIGHT DEMO - STEP BY STEP

See the DevForce Resource Center for discussion and original source.

Illustrates
------------
- DevForce and MVVM Light working together
- Repository/DataService pattern
- Design data repository to facilitate view development with design tools
- Building a view in VS "Cider" design tool


=====================================================================

1. File | New | Project |
   C# DevForce 2010 templates | DF Silverlight application template
   Name it "MvvmLightDemo"
   
   Delete the two README__FIRST files

   
   Add DevForce Model
    [This is the simplistic approach that puts mixes the model with the web and application projects
     For long term maintainability we recommend separate .NET and SL model projects
     But that's a lesson for another time.]

    This part is straight out of the Quickie
    Add EF Model to web project with just the Customer entity


------------------------------------------------------------------------------
2. Use Nuget to install MVVM Light in the Silverlight project


------------------------------------------------------------------------------
3. Add repository/DataService to access DF data as a single file, DemoDataService

     IDemoDataService: 
             void LoadCustomers(
                 Action<IEnumerable<Customer>> success = null,
                 Action<Exception> fail = null);
     
     DemoDataService:IDemoDataService
     
       public DemoDataService()
        {
            Manager = new NorthwindIBEntities();
        }

        protected NorthwindIBEntities Manager { get; set; }

        public void LoadCustomers(
            Action<IEnumerable<Customer>> success = null,
            Action<Exception> fail = null)
        {

            Manager.Customers
              .OrderBy(c => c.CompanyName)
              .ExecuteAsync(op =>
              {
                  if (op.CompletedSuccessfully)
                  {
                      if (null != success)
                      {
                          success(op.Results);
                      }
                  }
                  else
                  {
                      if (null != fail)
                      {
                          op.MarkErrorAsHandled();
                          fail(op.Error);
                      }
                  }
              });
        }  
        
     DesignDemoDataService:IDemoDataService
     
        public void LoadCustomers(
              Action<IEnumerable<Customer>> success = null,
              Action<Exception> fail = null)
        {
            if (null != success) success(CreateDesignCustomers());
        }

        /// <summary>Create collection of fake design-time customers</summary>
        private static IEnumerable<Customer> CreateDesignCustomers()
        {
            var custs = new List<Customer>();

            // First customer is for full detail customer design 
            custs.Add(
                new Customer { 
                      CustomerID = Guid.NewGuid(),
                      CompanyName = "The Design Width Company Name", 
                      Address = "123 Main Street",
                      City = "Anytown",
                      ContactName = "Harry Fidurcci",
                      Phone = "(510) 555 1212 x10",
                      Country = "France", }
            );

            // 10 dummy customers for listboxes
            var custCounter = 1;
            while (custCounter <= 10)
            {
                var cust = new Customer
                           {
                               CustomerID = Guid.NewGuid(), 
                               CompanyName = "Customer " + custCounter++, 
                               Country = "USA"
                           };
                custs.Add(cust);
            }

            return custs;
        }
      }


------------------------------------------------------------------------------
4. Modify MainViewModel 

   Add Customers property, ObservableCollection<Customer>
   Add Message property ... using MVVM Light snippet or the old fashioned way
   Add CurrentCustomer property the old fashioned way
        // Critical to help prime the detail grid and to ease binding w/in Cider
        private Customer _currentCustomer;
        public Customer CurrentCustomer
        {
            get { return _currentCustomer; }
            set { _currentCustomer = value; RaisePropertyChanged("CurrentCustomer"); }
        }
   
   Takes IDemoDataService in the ctor
   
      Set _dataService private var
      Don't need the IsInDesignMode logic; delete it
	  Initialize Message = "Loading ... "
	  Initialize Customers = new List<Customer>();
	  
	  Call _dataService.LoadCustomers in the ctor
	  
   Add CustomersLoaded and CustomerLoadFailed methods
	    
	private void CustomersLoaded(IEnumerable<Customer> customers)
	{
	    foreach (var customer in customers)
	    {
	        Customers.Add(customer);
	    }
	    CurrentCustomer = customers.FirstOrDefault();
	    Message = "Customers loaded.";
	}
	
	private void CustomerLoadFailed(Exception except)
	{
	    Message = "Customer Load Failed: " + except.Message;
        }


------------------------------------------------------------------------------
5. Modify ViewModelLocator

     Remove "static" from _main variable (I can't see why it would be static.)
     Add _dataService private var
	 Set appropriately per DesignMode
	 Pass to MainViewModel ctor
	 

------------------------------------------------------------------------------
6. Modify the MainPage.XAML in Cider (rough steps)

   Add DataContext binding to VML in XAML in UserControl  
	   DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
   
   Expand the Layout grid for design time
   
   Divide Layout grid into 3 rows
   Add TextBlock to the top row, give it the MVVM Light Demo title
   Add TextBlock  to the bottom row,  bind its Text property to the Message property (Wahoo! Design time data)

   Add regular Grid to second row of Layout grid, add two cols
     Add ListBox to left col, fill available space; bind its ItemSource to Customers
     Paste in the item DataTemplate to be the ItemTemplate for the ListBox (Xaml view)
     
         <UserControl.Resources>
   	  <ResourceDictionary>            
   	      <DataTemplate x:Key="customerListBoxItemsTemplate">
   		  <Grid>
   		      <TextBlock Text="{Binding CompanyName}"
   		      TextTrimming="WordEllipsis" />
   		  </Grid>
   	      </DataTemplate>
   	  </ResourceDictionary>
         </UserControl.Resources>
         
     Back in DesignView, set the ListBox ItemTemplate to this customerListBoxItemsTemplate
     Bind ListBox.SelectedItem to CurrentCustomer

     Add a 3rd regular grid (the detail grid) to the right col; fill the available space
     Bind the DataContext to the CurrentCustomer
     Add 4 rows, 2 cols
   	Add TextBox Row 0, Colspan2, Bind Text to Company Name
   	Add TextBlock Row 1, Col 0. Set Text to "Id"
   	Add TextBlock Row 2, Col 0. Set Text to "Country"
   	Add TextBox Row 1, Col 1. Bind Text to CompanyID, set ReadOnly = true
   	Add TextBox Row 2, Col 1, Bind Text to Country
   	
    Add GridSplitter to second grid to separate listbox from 3rd detail grid 
   	May be to do easier in XAML:
   	    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
	    ...
	    <sdk:GridSplitter HorizontalAlignment="Left" Width="10" Grid.Column="1" />
   