0 Comments

It took me WAY to long to find this out, so I am hoping this post helps Google/Bing provide the answer to others.

If you are used to using the following command to dispatch to the UI thread in Silverlight:

Deployment.Current.Dispatcher.BeginInvoke(action);

You are going to have to learn to love the new method:

Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(action));

 

 

0 Comments

I am looking into writing a sales order imported form scratch for Interprise and wanted to see how it works from a fundamentals point of view.  The following describes how to programmatically read data from a remote Interprise server using just DLLs and code. 

This does not require the SDK or Interprise Plug-In Guidance module.  

Creating the console project

I am using Visual Studio 2010, go File –> New Project

image

Right-click on the project, select Properties and change the Target Framework from “.NET Framework 4 Client Profile” to “.NET Framework 4” and close the window.

image

Adding References

Add the following references to the project.  I am not sure they are all required, but I needed each of them at some point during my troubleshooting, so why not.

  • From the GAC (I.E. just in the list)
    • System.Configuration
  • From C:\Program Files (x86)\Interprise Solutions\Interprise Suite 6.0
    • Interprise.Business.Base
    • Interprise.Business.Customer
    • Interprise.Connectivity.Database.Configuration.Design
    • Interprise.Extendable.Base
    • Interprise.Extendable.Customer
    • Interprise.Facade.Base
    • Interprise.Facade.Customer
    • Interprise.Facade.Utility
    • Interprise.Framework.Base
    • Interprise.Framework.Customer
    • Interprise.Licensing.Base
    • Microsoft.Practices.EnterpriseLibrary.Caching
    • Microsoft.Practices.EnterpriseLibrary.Common
    • Microsoft.Practices.EnterpriseLibrary.Data
    • Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
    • Microsoft.Practices.EnterpriseLibrary.Logging
    • Microsoft.Web.Services3

Finally, Add the following to the top of your Program.cs:

using Interprise.Facade.Base;
using Interprise.Facade.Customer;
using Interprise.Framework.Base.Shared;
using Interprise.Framework.Customer.DatasetGateway;

 

Configuration and Sign-in

In Program.cs, replace the Main method with the following:

static void Main(string[] args) {
    try {
        SimpleFacade.Instance.SignIn();
        //Run();
    }
    finally {
        SimpleFacade.Instance.SignOut();
    }
}

This logic signs into Interprise using the information in your project’s app.config file.  The process looks like this (as far as I can tell):

  1. Look for a cached executible config
  2. If that is not found, copy the current config file to the cache directory
  3. Load the values
  4. Sign-in

I want to call out a note on the cache.  The directory where the cache happens is : C:\ProgramData\Interprise Suite\1.0.0.0\Debug (with the version being your application’s version).  It is important to note that if you make changes to your app.config, you must delete the cached version of the file.

As for what to put in your app.config file, you can use the AppConfig tool included with Interprise.  Or you can steal it out of the current cached copy (C:\ProgramData\Interprise Suite\6.0.6.10\Interprise Suite 6.0\InterpriseSuite.exe.config) and paste it into your app.config.

Troubleshooting: Add the following line of code before the sign-in:

var MyConfig = InterpriseConfiguration.Instance;

using a breakpoint, inspect the values in MyConfig for sanity.  If they are not what you would expect, something is wrong with your config file.

Getting Some Data

Now for the big moment, getting some data.  Add the following method to Program.cs:

static void Run()
{
    using (var MyShipToDataset = new ShipToDatasetGateway())
    {
        using (var MyShipToFacade = new ShipToFacade(MyShipToDataset))
        {
            var Commands = new[] {
                new[] { MyShipToDataset.CustomerShipToView.TableName
                    , StoredProcedures.READCUSTOMERSHIPTO }
            };
                    var Params = new[] {                    
                new [] {"@CustomerCode", "CUST-000001"},
                new [] {"@ShipToCode", "SHIP-000002"}
            };

            var Result = MyShipToFacade.LoadDataSet(Commands, Params
                , Interprise.Framework.Base.Shared.Enum.ClearType.None);

            var MyShipTo = MyShipToDataset.CustomerShipToView[0];
        }
    }
}

So the first step, loading your dataset and façade is pretty simple and there is not that much logic here.

The next step is to have the façade load the desired rows from the database into the data set.  The Commands variable tells it what table and stored procedures to use.  I don’t yet know a good way to look these up, so be prepared to get REALLY good at using SQL Server Management Studio (SSMS).  Once you have the stored procedure, you can add the required params.  Again, use SSMS to look these up.

Finally, we call LoadDataSet to populate the database and view the result.  Simple.

0 Comments

So, you enjoy the MVVM pattern for your Silverlight or Windows Phone 7 application, but you can't figure out how to perform your navigation from your ViewModel?  Here is a guide that allows you to do this from your ViewModel:

  1. // Option 1
  2. GotoProductCatalogCommand = new RelayCommand(
  3.     () => Navigate("/Views/ProductCatalogPage.xaml"));
  4. // Option 2, now without strings!
  5. GotoProductCatalogCommand = new RelayCommand(
  6.     () => Navigate<ProductCatalogPageViewModel>());

The first option allows you to give a URI to navigate to, just like you would expect, but option two allows your application to navigate based on convention.  Never miss-type a URI again!

All you have to do is add the following to your ViewModel base class or MVVM Light’s ViewModelBase:

  1. public void Navigate<T>()
  2. {
  3.     var UriFragment = String.Format(@"/Views/{0}.xaml"
  4.         , typeof(T).Name.Replace("ViewModel", ""));
  5.     Navigate(UriFragment);
  6. }
  7. public void Navigate(String uriFragment)
  8. {
  9.     var MyFrame = Application.Current.RootVisual as Frame;
  10.     MyFrame.Navigate(new Uri(uriFragment, UriKind.Relative));
  11. }
  12. public void GoBack()
  13. {
  14.     (Application.Current.RootVisual as Frame).GoBack();
  15. }

Notice that my ‘convention’ for Views is to basically take the type name of your ViewModel, remove the string “ViewModel” and look up the file in the “/Views” directory.  Obviously you can move to a more comprehensive convention as your needs require.

0 Comments

I am a fan of keeping strings out of my .NET Applications.  In the past I used CSLA and enjoyed the way it loaded properties and change notification without using strings.  Because why work now-a-days is all about creating samples, I use MVVM Light instead. 

For those who don’t understand the what I am talking about, take a look at this example:

// Normal RaiseProperyChanged
RaisePropertyChanged("Products");

// Statically-Typed RaisePropertyChanged
RaisePropertyChanged(() => Products);

To get the same functionality, add the following method to your class (or ViewModel base class):

public void RaisePropertyChanged<T>(Expression<Func<T>> property)
{
    RaisePropertyChanged(property.GetMemberInfo().Name);
}

And if you don’t already have the GetMemberInfo() extension method, Add the following class to your application:

using System.Linq.Expressions;
using System.Reflection;

namespace System.Linq.Expressions
{
    public static class ReflectionExtensionMethods
    {
        public static MemberInfo GetMemberInfo(this Expression expression)
        {
            MemberExpression operand;
            LambdaExpression lambdaExpression = (LambdaExpression)expression;
            if (lambdaExpression.Body as UnaryExpression != null)
            {
                UnaryExpression body = (UnaryExpression)lambdaExpression.Body;
                operand = (MemberExpression)body.Operand;
            }
            else
            {
                operand = (MemberExpression)lambdaExpression.Body;
            }
            return operand.Member;
        }
    }
}

0 Comments

Let’s just say you want to make a PivotViewer for the Periodic Table of Elements.  And lets just say you want it to look something like you remember it in your middle school science book.  You get the data, add a ‘Group’ value to control the columns, but the vertical order is all wrong. 

Here is a quick way to fix this.  I don’t think anyone documented the method for doing this before, so if you have any questions, let me know!

And add the following to your PivotViewer XAML

<pv:PivotViewer x:Name="myPivotViewer" ItemsSource="{Binding}" BorderThickness="0" ViewChanged="myPivotViewer_ViewChanged">

And in code behind, add:

  1. private System.Windows.Controls.Pivot.PivotViewerView _OldView = null;
  2.  
  3. private void myPivotViewer_ViewChanged(object sender, EventArgs e)
  4. {
  5.     if (_OldView != null)
  6.     {
  7.         _OldView.PivotViewerViewUpdating -=
  8.             new EventHandler<PivotViewerViewUpdatingEventArgs>
  9.                 (View_PivotViewerViewUpdating);
  10.     }
  11.     _OldView = myPivotViewer.View;
  12.     _OldView.PivotViewerViewUpdating +=
  13.         new EventHandler<PivotViewerViewUpdatingEventArgs>
  14.             (View_PivotViewerViewUpdating);
  15. }
  16.  
  17. private void View_PivotViewerViewUpdating(object sender
  18.     , PivotViewerViewUpdatingEventArgs e)
  19. {
  20.     e.CollectionView.SortDescriptions.Add(
  21.         new SortDescription("AtomicNumber"
  22.             , ListSortDirection.Ascending));
  23. }

It is very important to make sure you are cleaning up your PivotViewerViewUpdating event reference as shown!

And Ta-Da, you have the following work of art:

clip_image002

Sorry for making such a quick example without any downloadable source, but I figured it was good to get this information out there!