Sandrino Di Mattia

Content-type: Microsoft

Social

Follow me on Twitter! LinkedIn! RSS! SilverlightShow Contributor

Recent posts

Tags

Categories

Archive

Blogroll

Windows Phone 7 article in MSDN Magazine

A few months ago I had the opportunity to work together with our Enterprise Solutions division on a small CRM project. Part of this assignment was to work on a session for the Belgian Dynamics Community day. Besides that I had to create a Windows Phone 7 application that would connect to Dynamics CRM online and Windows Azure AppFabric to do all kinds of things.

One of those things was to get all contacts in CRM and see which of those were close to me. Based on this nice concept I wrote an article in Microsoft's MSDN Magazine:

Location-Aware Programming: Visualizing Bing Routes on Windows Phone 7 

 

 

And I'm currently working with a customer to implement this on a commercial multi-platform mobile application.

Enjoy...

TechDays Belgium 2011: Follow the speakers!

This year's TechDays is filled with big names and great sessions. When you're preparing for the event (choosing which session to go to etc...) you might want to discover some of the speakers. And during the event those speakers will probably be active on twitter. That's why I created a list of all speakers with their blogs, rss feeds and twitter accounts:

  • Adam Gilmore (Solutions Architect / Microsoft Consulting Services UK): Blog RSS Twitter
  • Bart De Smet (Software Development Engineer / Microsoft): Blog RSS
  • Boris Jabes (Senior Program Manager, Visual C++ team / Microsoft Corp): Blog RSS Twitter
  • Brian Keller (Sr. Technical Evangelist / Microsoft): Blog RSS
  • Chris Eargle (Telerik Developer Evangelist, MVP / Telerik): Blog RSS Twitter
  • Christian Weyer (Co-founder / Thinktecture): Blog RSS Twitter
  • Clemens Vasters (Principal Technical Lead AppFabric / Microsoft Corporation): Blog RSS Twitter
  • Corey Hynes (Technical Lead / Hynesite)
  • Dan Holme (Intelliem): Blog RSS Twitter
  • Dandy Weyn (Sr. Technical Product Manager - Core Database Product Management / Microsoft Corp): Twitter
  • David Allen (Principal Consultant - OpsMgr MVP / Infront Consulting Group - Europe): Twitter
  • Don Jones (Editor-in-Chief / Realtime Publishers): Twitter
  • Gill Cleeren (.NET Architect / Ordina): Blog RSS Twitter
  • Glenn Block (Senior Program Manager WCF / Microsoft Corp): Blog RSS Twitter
  • Hadi Hariri (Technical Evangelist / JetBrains): Blog RSS Twitter
  • Ilse Van Criekinge (Technology Advisor / Microsoft): Blog RSS Twitter
  • Ingo Rammer (Co-founder / Thinktecture): Blog RSS Twitter
  • Isabel Gomez Miragaya (ISV Developer Evangelist / Microsoft Spain)
  • Jeff Prosise (Instructor, Consultant and Co-Founder / Wintellect): Blog RSS Twitter
  • Jens K. Suessmeyer (Database Consultant / Microsoft Consulting Services, Germany): Blog RSS
  • Jeremy Moskowitz (Chief Propeller-Head for Moskowitz, inc. and GPanswers.com / Moskowitz inc): Blog Twitter
  • John Craddock (Principal Systems Consultant): Twitter
  • Kevin Dockx (Technical Consultant / RealDolmen): Blog RSS Twitter
  • Kim Oppalfens (Managing Consultant / OSCC): Blog RSS Twitter
  • Kurt Claeys (Technology Solution Professional on Windows Azure / Microsoft EMEA)
  • Kurt Roggen (Practice Leader / DevoTeam Belgium): Blog RSS Twitter
  • Luc Van De Velde (Director Developer & Platform group / Microsoft): Blog RSS Twitter
  • Maarten Balliauw (.NET Developer / RealDolmen): Blog RSS Twitter
  • Marcus Murray (Security Team Manager at Truesec / Truesec): Blog RSS
  • Mark Scurrell (Senior Program Management Lead / Microsoft Corp): Blog
  • Mike Resseler (Senior Technical Consultant, SCDPM MVP / Infront Consulting Group – Europe): Blog RSS Twitter
  • Phil Japikse (Patterns and Practices Evangelist / Telerik): Blog RSS Twitter
  • Pieter Gheysens (Sparkles): Blog RSS Twitter
  • Rob Miles (Lecturer / University of Hull): Site Twitter
  • Ruben Spruijt (Technology Officer at PQR / PQR): Blog RSS Twitter
  • Scott Hanselman (Principal Program Manager Lead / Microsoft Corporation): Blog RSS Twitter
  • Scott Schnoll (Principal Technical Writer / Microsoft): Blog RSS Twitter
  • Serge Luca (Sharepoint MVP consultant and trainer): Blog RSS
  • Steffen Krause (Technology Advisor / Microsoft Germany): Blog RSS Twitter
  • Symon Perriman (Program Manager - Clustering / Microsoft Corp): Blog Twitter
  • Vittorio Bertocci (Senior Architect Evangelist / Microsoft): Blog RSS
  • Wade Wegner (Sr Technical Evangelist / Microsoft Corporation): Blog RSS Twitter

Take your time to choose because you can't follow all sessions!

Enjoy...

Early binding tips and tricks for Dynamics CRM 2011

When you're working with Dynamics CRM 2011 and you need to write plugins or other kinds of integration with .NET code you should make use of early binding. This gives you a context that contains a typed .NET representation of all your entities, relations, ...

    var contacts = from c in context.ContactSet
                    where c.FirstName == "Sandrino"
                    select c;

    foreach (var contact in contacts)
    {
        Console.WriteLine(contact.FullName);
    }

The fact that you have a 1 on 1 representation of all your entities and relations has a lot of advantages:

  • You no longer have to work with magic strings when accessing attributes
  • Every property is typed the correct way. No need to cast attribute values anymore.
  • When entities or attributes are removed, renamed, ... and you update your context your code won't build and you can fix each problem immediately. No more runtime errors.
  • Less bugs
  • Less manual work
  • ...

This context is created based on the metadata of your organization. To view the metadata of your organization you just need to navigate to the following URL: http://server/organization/XRMServices/2011/OrganizationData.svc/$metadata

In Visual Studio you can use this URL to add a Service Reference and have some code generated but I wouldn't advise this. Instead you should use a tool that comes with the CRM SDK named CrmSvcUtil.exe When you start using this tool you'll quickly bump into the same error over and over again:

Exiting program with exception: The caller was not authenticated by the service.
Enable tracing and view the trace files for more information.

Let's run over a few tips on how you could solve this issue:

Proxy Settings

When you're working inside a corporate network that only allows network access via a proxy server you'll need to create a new file in the same directory as CrmSvcUtil.exe and name it crmsvcutil.exe.config Now this file should contain the proxy settings for the application, and it most cases it should look like this:

<?xml version="1.0"?>
<configuration>
  <system.net>
    <defaultProxy enabled="true" useDefaultCredentials="true"/>
  </system.net>
</configuration>

This forces the application to use the proxy and to use the default credentials. If you are still having problems and you're working behind an ISA Proxy you might want to install the Microsoft Firewall Client Management tool from Microsoft. This will help you with most other authentication problems.

Finding the actual error

The error message specifies that you should take a look at the trace files to find the actual error. This trace file is located in the C:\Program Files\Microsoft Dynamics CRM\Trace directory.

Look for the file with the most recent date modified that looks like the file on the screenshot. This will contain the trace message with a detailed exception:

<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
  <TraceIdentifier>http://msdn.microsoft.com/nl-BE/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
  <Description>Throwing an exception.</Description>
  <AppDomain>/LM/W3SVC/2/ROOT-1-129423140458251760</AppDomain>
  <Exception>
    <ExceptionType>System.ComponentModel.Win32Exception, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
    <Message>The Security Support Provider Interface (SSPI) negotiation failed.</Message>
    <StackTrace>
      at System.ServiceModel.Security.WindowsSspiNegotiation.GetOutgoingBlob(Byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
      >   at System.ServiceModel.Security.SspiNegotiationTokenAuthenticator.ProcessNegotiation(SspiNegotiationTokenAuthenticatorState negotiationState, Message incomingMessage, BinaryNegotiation incomingNego)>
    </StackTrace>
    <ExceptionString>System.ComponentModel.Win32Exception (0x80004005): The Security Support Provider Interface (SSPI) negotiation failed.</ExceptionString>
    <NativeErrorCode>8009030C</NativeErrorCode>
  </Exception>
</TraceRecord>

In this case the exception string will help me to find the solution.

The Security Support Provider Interface (SSPI) negotiation failed.

If you're working with a virtual machine that is part of an other domain you might get this error (cross domain call). To solve this you'll need to change the way you pass the authentication arguments to CrmSvcUtil.exe Instead of calling CrmSvcUtil.exe using the following line:

CrmSvcUtil.exe /url:"http:/srv/org/XRMServices/2011/Organization.svc" /out:Context.cs
     /username:"sandrino" /password:"pass" /domain:"somedomain" /serviceContextName:Context

Change it to the following:

CrmSvcUtil.exe /url:"http:/srv/org/XRMServices/2011/Organization.svc" /out:Context.cs
     /username:"sandrino@somedomain" /password:"pass" /serviceContextName:Context

By removing the domain argument and appending the domain to the username (separated with the @ sign) you'll solve the cross domain problem.

Other authentication problems

This might be a no-brainer but it will help. If for some reason you find yourself with authentication problems it might have to do with one of the arguments you are passing to CrmSvcUtil.exe That's why it's best to wrap all argument values with double quotes.

CrmSvcUtil.exe /url:"http:/srv/org/XRMServices/2011/Organization.svc" /out:"Context.cs"
     /username:"sandrino@somedomain" /password:"pass" /serviceContextName:"Context"

Creating a useful batch file

To make sure you can easily update your context class you should automate this process. In my case I created a batch file with only 1 command:

CrmSvcUtil\CrmSvcUtil.exe /url:http://server/Contoso/XRMServices/2011/Organization.svc
     /out:"..\Sandrino.CRM.Contoso.Common\ContosoContext.cs" /username:sandrino@CONTOSO
     /password:"mypwd" /serviceContextName:ContosoContext

Now each time I execute the batch file it will call CrmSvcUtil with the correct arguments and overwrite the existing ContosoContext.cs file in my Sandrino.CRM.Contoso.Common project. I don't need to memorize the arguments and I don't need to copy paste the file around. Remember if you are working with TFS you need to check out the file first!

This is how my solution looks like:

Download the sample project: Sandrino.CRM.Contoso.zip (423.70 kb)

My article in MSDN Magazine: Using MEF to Expose Interfaces in Your Silverlight MVVM Apps

After patiently waiting through the editing process my article finally got published in MSDN Magazine and Visual Studio Magazine. I had the chance to write a long article on integrating MVVM with Silverlight Navigation (Frames) using MEF.

 

Go see for yourself and let me know what you think!

Enjoy!

Posted: Jan 05 2011, 09:08 by Sandrino | Comments (0) RSS comment feed |
Filed under: .NET | Development

Controlling and viewing the ScrollBar positions of your Silverlight DataGrid

Introduction

If you take a look at the Silverlight DataGrid you'll see that you can't control scrolling by default. This could be a hurdle if you're working with data driven applications. What if you want to preserve the scroll position after you reload the DataGrid?

In this article we're going to do 2 things in regard to scrolling:

  1. Create extension methods to control the DataGrid scrolling.
  2. Create a custom DataGrid for advanced scenarios.

Scrollbars on the DataGrid

Before we get started here is a quick overview of the DataGrid with scrollbars. Each DataGrid could have up to 2 scrollbars (1 horizontal and 1 vertical). And the button you can drag around is called a thumb (from System.Windows.Controls.Primitives.Thumb).

 

Creating the DataGridScrollExtensions class

The class we'll create should provide the following functionalities:

  • Give us access to both the horizontal and vertical scrollbars
  • Inform us about the position (and changes) of the scrollbar thumbs
  • Move the scrollbar thumbs

This is how the class looks like:

 

Finding the Scrollbars

The first thing to do is make sure we can access the scrollbars. This is where we'll use the recursive method GetScrollbars. Using the VisualTreeHelper we can drill down through a DependencyObject (in our case the DataGrid) until we find the Scrollbar. The names you can use to find the right scrollbars are VerticalScrollbar and HorizontalScrollbar (case sensitive!).

        private static ScrollBar GetScrollbar(this DependencyObject dep, string name)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dep); i++)
            {
                var child = VisualTreeHelper.GetChild(dep, i);
                if (child != null && child is ScrollBar && ((ScrollBar)child).Name == name)
                    return child as ScrollBar;
                else
                {
                    ScrollBar sub = GetScrollbar(child, name);
                    if (sub != null)
                        return sub;
                }
            }
            return null;
        }  

Now that we have access to the scrollbars we can get to all the information we need. You'll probably want to look at the Maximum and Value properties and also the Scroll event.

Moving the Scrollbars

Moving the scrollbars around is a little trickier. I bet you're thinking the same as I was thinking. Just change the Value property of a scrollbar. Well, I suggest you try that. You'll see that the Thumb will move to the new value of the scrollbar, but the data won't follow. Let's take a look at the DataGrid using Reflector:


        public override void OnApplyTemplate()
        {
            ...
            this._hScrollBar = base.GetTemplateChild("HorizontalScrollbar"as ScrollBar;
            if (this._hScrollBar != null)
            {
                this._hScrollBar.IsTabStop = false;
                this._hScrollBar.Maximum = 0.0;
                this._hScrollBar.Orientation = Orientation.Horizontal;
                this._hScrollBar.Visibility = Visibility.Collapsed;
                this._hScrollBar.Scroll += new ScrollEventHandler(this.HorizontalScrollBar_Scroll);
            }
            ...
            this._vScrollBar = base.GetTemplateChild("VerticalScrollbar"as ScrollBar;
            if (this._vScrollBar != null)
            {
                this._vScrollBar.IsTabStop = false;
                this._vScrollBar.Maximum = 0.0;
                this._vScrollBar.Orientation = Orientation.Vertical;
                this._vScrollBar.Visibility = Visibility.Collapsed;
                this._vScrollBar.Scroll += new ScrollEventHandler(this.VerticalScrollBar_Scroll);
            }
            ...
        }

As you can see the DataGrid subscribes to each ScrollBar's Scroll event. When this event is raised the DataGrid will move the data around. But if you just change the Value of a ScrollBar, the Scroll event won't be triggered.

We'll need to simulate a user moving the ScrollBar around. And maybe you know this, but Silverlight (and .NET) provide a concept that was made for what we're trying to achieve, Microsoft UI Automation. One of its features is simulating user interaction. You can read more about it here and here. The following code gets the AutomationPeer for the DataGrid and this object can provide us with the IScrollProvider.

        private static IScrollProvider GetScrollProvider(DataGrid grid)
        {
            var p = FrameworkElementAutomationPeer.FromElement(grid) 
?? FrameworkElementAutomationPeer.CreatePeerForElement(grid);
            return p.GetPattern(PatternInterface.Scroll) as IScrollProvider;
        }

Finally, using this IScrollProvider you can simulate a scroll interaction:

            switch (mode)
            {
                case ScrollMode.Vertical:
                    scrollProvider.SetScrollPercent(
System.Windows.Automation.ScrollPatternIdentifiers.NoScroll, percent);
                    break;
                case ScrollMode.Horizontal:
                    scrollProvider.SetScrollPercent(percent, 
System.Windows.Automation.ScrollPatternIdentifiers.NoScroll);
                    break;
            }

The Code 

Here is the code with all the necessary extension methods:

    public static class DataGridScrollExtensions
    {
        /// <summary>
        /// Scroll to the start of the ScrollBar.
        /// <param name="mode"></param>
        public static void ScrollToStart(this DataGrid grid, ScrollMode mode)
        {
            switch (mode)
            {
                case ScrollMode.Vertical:
                    grid.ScrollToPercent(ScrollMode.Vertical, 0);
                    break;
                case ScrollMode.Horizontal:
                    grid.ScrollToPercent(ScrollMode.Horizontal, 0);
                    break;
            }
        }

        /// <summary>
        /// Scroll to the end of the ScrollBar.
        /// </summary>
        /// <param name="mode"></param>
        public static void ScrollToEnd(this DataGrid grid, ScrollMode mode)
        {
            switch (mode)
            {
                case ScrollMode.Vertical:
                    grid.ScrollToPercent(ScrollMode.Vertical, 100);
                    break;
                case ScrollMode.Horizontal:
                    grid.ScrollToPercent(ScrollMode.Horizontal, 100);
                    break;
            }
        }

        /// <summary>
        /// Scroll to a percentage of the scrollbar (50% = half).
        /// </summary>
        /// <param name="mode"></param>
        /// <param name="percent"></param>
        public static void ScrollToPercent(this DataGrid grid, ScrollMode mode, double percent)
        {
            // Fix the percentage.
            if (percent < 0)
                percent = 0;
            else if (percent > 100)
                percent = 100;

            // Get the scroll provider.
            var scrollProvider = GetScrollProvider(grid);

            // Scroll.
            switch (mode)
            {
                case ScrollMode.Vertical:
                    scrollProvider.SetScrollPercent(System.Windows.Automation.ScrollPatternIdentifiers.NoScroll, percent);
                    break;
                case ScrollMode.Horizontal:
                    scrollProvider.SetScrollPercent(percent, System.Windows.Automation.ScrollPatternIdentifiers.NoScroll);
                    break;
            }
        }

        /// <summary>
        /// Get the current position of the scrollbar.
        /// </summary>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static double GetScrollPosition(this DataGrid grid, ScrollMode mode)
        {
            var scrollBar = grid.GetScrollbar(mode);
            return scrollBar.Value;
        }

        /// <summary>
        /// Get the maximum position of a scrollbar.
        /// </summary>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static double GetScrollMaximum(this DataGrid grid, ScrollMode mode)
        {
            var scrollBar = grid.GetScrollbar(mode);
            return scrollBar.Maximum;
        }

        /// <summary>
        /// Scroll to a position of the scrollbar.
        /// </summary>
        /// <param name="mode"></param>
        /// <param name="position"></param>
        public static void Scroll(this DataGrid grid, ScrollMode mode, double position)
        {
            // Get the scrollbar and convert the position to percent.
            var scrollBar = grid.GetScrollbar(mode);
            double positionPct = ((position / scrollBar.Maximum) * 100);

            // Scroll to a specfic percentage of the scrollbar.
            grid.ScrollToPercent(mode, positionPct);
        }

        /// <summary>
        /// Get a scroll provider for the grid.
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        private static IScrollProvider GetScrollProvider(DataGrid grid)
        {
            var p = FrameworkElementAutomationPeer.FromElement(grid) ?? FrameworkElementAutomationPeer.CreatePeerForElement(grid);
            return p.GetPattern(PatternInterface.Scroll) as IScrollProvider;
        }

        /// <summary>
        /// Get one of the grid's scrollbars.
        /// </summary>
        /// <param name="grid"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static ScrollBar GetScrollbar(this DataGrid grid, ScrollMode mode)
        {
            if (mode == ScrollMode.Vertical)
                return grid.GetScrollbar("VerticalScrollbar");
            else
                return grid.GetScrollbar("HorizontalScrollbar");
        }
        
        /// <summary>
        /// Find the scrollbar for our datagrid.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dep"></param>
        /// <returns></returns>
        private static ScrollBar GetScrollbar(this DependencyObject dep, string name)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dep); i++)
            {
                var child = VisualTreeHelper.GetChild(dep, i);
                if (child != null && child is ScrollBar && ((ScrollBar)child).Name == name)
                    return child as ScrollBar;
                else
                {
                    ScrollBar sub = GetScrollbar(child, name);
                    if (sub != null)
                        return sub;
                }
            }
            return null;
        } 
    }

Creating the ScrollDataGrid control

Now that we can control the scrolling we could go even further. What about creating a DataGrid where you can subscribe to both Scroll events or even store the current scroll position? This could be useful for when we're reloading the items and we want to preserve the scroll position.

The most important things to note are the SaveScrollPosition ReloadScrollPosition methods and the HorizontalScroll VerticallScroll events. Here is a small demo of the ScrollDataGrid:


 

The method SaveScrollPosition saves the current position in an internal field and the ReloadScrollPosition applies the value of that field back to the ScrollBar. To find the ScrollBars we're applying an other technique, using GetTemplateChild. The rest of the code calls our extension methods:

    public class ScrollDataGrid : DataGrid
    {
        /// <summary>
        /// The vertical scrollbar.
        /// </summary>
        private ScrollBar verticalScrollBar;

        /// <summary>
        /// The horizontal scrollbar.
        /// </summary>
        private ScrollBar horizontalScrollBar;

        /// <summary>
        /// Position of the vertical scrollbar we saved.
        /// </summary>
        private double savedVerticalScrollPosition;

        /// <summary>
        /// Position of the horizontal scrollbar we saved.
        /// </summary>
        private double savedHorizontalScrollPosition;
        
        /// <summary>
        /// Event for each vertical scroll.
        /// </summary>
        public event EventHandler<ScrollEventArgs> VerticalScroll;

        /// <summary>
        /// Event for each horizontal scroll.
        /// </summary>
        public event EventHandler<ScrollEventArgs> HorizontalScroll;

        /// <summary>
        /// Load the scrollbars after the template gets loaded.
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.LoadScrollBars();
        }

        /// <summary>
        /// Get both scrollbars.
        /// </summary>
        private void LoadScrollBars()
        {
            verticalScrollBar = this.GetTemplateChild("VerticalScrollbar"as ScrollBar;
            if (verticalScrollBar != null)
                verticalScrollBar.Scroll += new ScrollEventHandler(OnVerticalScroll);
            horizontalScrollBar = this.GetTemplateChild("HorizontalScrollbar"as ScrollBar;
            if (horizontalScrollBar != null)
                horizontalScrollBar.Scroll += new ScrollEventHandler(OnHorizontalScroll);
        }
        
        /// <summary>
        /// Notify that we are scrolling vertically.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnVerticalScroll(object sender, ScrollEventArgs e)
        {
            if (VerticalScroll != null)
                VerticalScroll(sender, e);
        }

        /// <summary>
        /// Notify that we are scrolling horizontally.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnHorizontalScroll(object sender, ScrollEventArgs e)
        {
            if (HorizontalScroll != null)
                HorizontalScroll(sender, e);
        }
        
        /// <summary>
        /// Save the current scroll position.
        /// </summary>
        /// <param name="mode"></param>
        public void SaveScrollPosition(ScrollMode mode)
        {
            switch (mode)
            {
                case ScrollMode.Vertical:
                    this.savedVerticalScrollPosition = verticalScrollBar.Value;
                    break;
                case ScrollMode.Horizontal:
                    this.savedHorizontalScrollPosition = horizontalScrollBar.Value;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// Reload the scroll position that was saved before.
        /// </summary>
        /// <param name="mode"></param>
        public void ReloadScrollPosition(ScrollMode mode)
        {
            switch (mode)
            {
                case ScrollMode.Vertical:
                    this.Scroll(ScrollMode.Vertical, savedVerticalScrollPosition);
                    break;
                case ScrollMode.Horizontal:
                    this.Scroll(ScrollMode.Horizontal, savedHorizontalScrollPosition);
                    break;
            }
        }
    }

Downloads

 

Happy scrolling..