Wednesday, January 28, 2009

Patterns & Practices

Eric Nelson (@ericnel) tweeted this morning about the patterns & practices Guidance Explorer tool.

Now I’d seen this before, but had missed the Visual Studio 2008 Guidance Explorer Add-In that brings guidance directly into VS.

I’d also missed that there’s a way to get the guidance in “bite-sized” chunks via an RSS feed for Outlook1.

Why is this relevant? Well, the p&p team’s guidance is a baseline for .net development – being at least aware of the best practice is certain to improve your own development. Time to do some configuration…

p&p Guidance Explorer: http://www.codeplex.com/guidanceExplorer

VS2008 Add-In: http://www.codeplex.com/GEVSAddIn

p&p Guidance RSS: http://blogs.msdn.com/alikl/archive/2008/01/03/consume-patterns-practices-guidance-explorer-via-rss-using-outlook-2007.aspx

 

1Disclaimer: Other RSS readers are available.

Friday, January 23, 2009

Quickie: Simulating DataContextChanged in Silverlight

One of the key line-of-business-app features of Silverlight is the ability to databind – and we use it everywhere.

So it’s slightly odd that the DataContextChanged event is internal in Silverlight (it’s public in WPF). How on earth can we then know if our data context has been changed?

The answer’s pretty simple, and is properly documented on The Problem Solver blog.

The solution is to create a custom DependencyProperty and explicitly bind it, thus:


public
partial class PersonHeader : UserControl
    {
        public PersonHeader()
        {
            // Required to initialize variables
            InitializeComponent();
            SetBinding(DataContextWatcherProperty, new Binding());
        }

        public static readonly DependencyProperty DataContextWatcherProperty =
            DependencyProperty.Register("DataContextWatcher",
                                        typeof (Object), typeof (PersonHeader),
                                        new PropertyMetadata(DataContextChanged));

        private static void DataContextChanged(object sender,
                                               DependencyPropertyChangedEventArgs e)
        {
            var personHeader = (PersonHeader) sender;
            // Update the control as needed
        }
        …
}

DataContextChanged Solution: http://msmvps.com/blogs/theproblemsolver/archive/2008/12/29/how-to-know-when-the-datacontext-changed-in-your-control.aspx  

Thursday, January 22, 2009

Simulating internal links in a Silverlight ScrollViewer

One of the unsung heroes of HTML is the ability to use internal links within a document for navigation within a page.

In HTML, this is achieved by placing name tags (e.g. <A Name=”top>…</A>) as invisible placeholders throughout the document, and then referencing them from internal hyperlinks (e.g. <A HREF=”#target”>Back to top</a>) wherever you want the navigation to appear.

In Silverlight, it’s common to use a ScrollViewer control to provide a scrolling viewport over some other set of controls, but there’s no analogue to the internal hyperlink to allow us to easily scroll that viewport. It’s easy enough to use HyperlinkButton controls to provide the navigation, but how to scroll the ScrollViewer?

My solution is a simple one – provide an extension method that commands a ScrollViewer to position itself so that a specific control is visible. The click event handler for the HyperlinkButton can then easily simulate internal links and position the ScrollViewer.

 

In the following Xaml source snippet I’ve used HeaderedItemsControls to contain my sections:

 

<!-- Navigation -->

<StackPanel Orientation="Horizontal" >

<TextBlock Text="Jump to" />

<HyperlinkButton x:Name="Section1Link" Content="First Section" Click=" Section1Link _Click" />

<HyperlinkButton x:Name="Section2Link" Content="Second Section" Click="Section2Link_Click" />

      …

</StackPanel>

 

<!-- Viewport -->

<ScrollViewer x:Name="Scroller”>

<StackPanel>

<HeaderedItemsControl x:Name="Section1">

</HeaderedItemsControl>

<HeaderedItemsControl x:Name="Section2">

</HeaderedItemsControl>

            …

</StackPanel>

</ScrollViewer>

 

By making sure the “target” HeaderedItemsControls have names, the click method for the HyperlinkButton is as simple as you could wish for:

 

/// <summary>

/// Handles the Click event of the NamesSectionLink control.

/// </summary>

/// <param name="sender">The source of the event.</param>

/// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>

private void Section1Link_Click(object sender, RoutedEventArgs e)

{

DetailsScroller.PositionOnControl(Section1);

}

 

And finally, the extension method itself.

 

/// <summary>

/// Extension methods for ScrollViewer controls

/// </summary>

public static class ScrollViewerExtensions

{

/// <summary>

/// Extension method that positions the scroll viewer to show the specified control

/// </summary>

/// <param name="scrollViewer">The scroll viewer.</param>

/// <param name="targetControl">The target control.</param>

public static void PositionOnControl(this ScrollViewer scrollViewer, UIElement targetControl)

{

var transform = targetControl.TransformToVisual(scrollViewer);

            var offset = transform.Transform(new Point(0, 0));

            scrollViewer.ScrollToVerticalOffset(offset.Y);

}       
}

 

The only magic is in the transformation used to convert the origin coordinates of the target into a scroll offset for the ScrollViewer.

Enjoy!

Thursday, January 08, 2009

Mike Taulty gets to play with all the good stuff

I’ve been quietly following Mike Taulty’s posts on his experiments with the Live Framework SDK, and with creating a simplistic photo sharing application that supports online/offline working via Live Mesh.

Now he’s got to the point of starting to implement Mesh Object sharing, I’ve started to get really interested. This is the functionality that will raise an application way above its competitors.

Sure there will be plenty of issues regarding information governance (does a user have the legal right to share whatever they want), but for the kind of application I’ve got in mind those security issues can be baked into the application at the root level – for example by encrypting the data stored, by having a central mesh object that stores “access keys” to the data or some such – nothing that can’t be solved.

What this gives is a simple way for a user to work disconnected, to upload to a central store, and to share that work with their colleagues, who can also work disconnected.

This is hard to get your head around to start with but is seriously good stuff.

Part 1: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/12/18/10965.aspx

Part 2: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/12/19/live-framework-sdk-more-steps.aspx

Part 3: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/01/02/live-framework-sdk-having-a-single-meshobject.aspx

Part4: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/01/07/live-framework-sdk-adding-a-silverlight-mewa.aspx

Part 5: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/01/07/live-framework-sdk-inviting-others.aspx