Git: Rollback (or Undo) a Pull from an External Repository To Return To A Previous Stable Commit State

iStock_000017591577XSmallZen is not possible and we need to return to a state of peace within Git!

In the case where one pulls from a repository such as GitHub and something breaks, one may want to undo that pull. Here are the steps to rollback to a previous version using Git.

Note if you have any work in the local working directory done after the pull, it will be lost using this method.

Our goal is to move to the Head to the last snapshot before the pull and return the Zen to us.

Steps

  1. Find the SHA-1 version using reflog. The reflog is interactive and one uses a q to exit out.

    git reflog

    That will bring up a list such as this:

    da88c95 HEAD@{0}: pull origin br_1.0.0: Merge made by recursive.
    26a96f1 HEAD@{1}: commit: Non movable end block not being placed at end time fix.
    abc8366 HEAD@{2}: commit: Created durationd dependancy to adjust the timeline correctly to the actual time.
    1b3ca89 HEAD@{3}: commit: _ReSharper directory ignored
    5d579ba HEAD@{4}: pull origin br_1.0.0: Fast-forward
    68fbb98 HEAD@{5}: commit: Ignore tests which are creating timelines and provisioned timelines

     

    We are interested in the second line as highlighted above which is before the pull.

  2. Then we want to move the head to  either the hash or the symbolic name before the pull so we do a reset command which targets the local working directory and moves it to the target commit.
    git reset --hard 26a96f1

    or (in this case yours may be different)

     

    git reset --hard HEAD@{1}:

The — hard options  brings about changes to the working copy and sets us to the state before the pull. Now interestingly enough if we look at the log it shows our reset operation as the top level log item which has the same hash as where we wanted to go:

26a96f1 HEAD@{0}: 26a96f1: updating HEAD
da88c95 HEAD@{1}: pull origin br_1.0.0: Merge made by recursive.
26a96f1 HEAD@{2}: commit: Non movable end block not being placed at end time fix.
abc8366 HEAD@{3}: commit: Created durationd dependancy to adjust the timeline correctly to the actual time.
1b3ca89 HEAD@{4}: commit: _ReSharper directory ignored
5d579ba HEAD@{5}: pull origin br_1.0.0: Fast-forward

Final Thoughts

Of course you have only delayed the inevitable. One usually does this because something about the current state of changes in the remote is just not palatable and someone else is working on it. When ready do a normal pull to pull down those new changes and merge.

Share

Tags:

Xaml: Adding Visibility Behaviors Using Blend to A DataGrid for WPF or Silverlight

iStock_000015143879XSmallIn Xaml the determining when to trigger the visibility, or the hiding of  controls or their functionality is a key concept of doing either WPF or Silverlight programming. This article builds upon my article C#: WPF and Silverlight DataGrid Linq Binding Example Using Predefined Column Header Names in Xaml where we are going to add behaviors to the datagrid shown.  (Don’t worry about reading the article, for I will get you up to speed with the code snippets in this article.) We will use Microsoft’s Expression Blend product to do the dirty work of xaml modification to our DataGrid and it will be shown in a step by step process.

Concept

In the previous article the idea was to load our datagrid with two columns of data. The first column showed us a filename and the second column displayed a modified filename with a count in it. We will take that one step further and have a description show up with the file size. Here is the resulting look:

Inital with Description

The user gets the description when the row is clicked.

But what if we wanted to disable that functionality and automatically show the user all the items when the mouse hovers over the datagrid such as

Result

Setup

First thing we need to do is setup our datagrid. Below is the xaml and the code behind to load our datagrid. Note the datagrid has the RowDetailsVisibiltyMode set to collapsed. That means that when a user clicks on the row, it will only select it and not open up our description. The loading of the ItemsSource happens during the construction and after the initial initialization and is shown in C# in the second pane.

<DataGrid x:Name="dgPrimary"
            RowDetailsVisibilityMode="Collapsed">
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>

            <TextBlock FontWeight="Bold"
                        Text="{Binding Size, StringFormat=Size \{0\} (bytes)}" />

        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Original}"
                            Header="File Name Before"
                            IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding New}"
                            Header="File Name After"
                            IsReadOnly="True" />
    </DataGrid.Columns>
</DataGrid>
dgPrimary.ItemsSource =
    new DirectoryInfo( "c:\\" ).GetFiles()
                               .Select( ( fInfo, index ) => new
                    {
                        Original = fInfo.Name,
                        New = string.Format( "{0}_{1}{2}",
                                    System.IO.Path.GetFileNameWithoutExtension( fInfo.Name ),
                                    index,
                                    System.IO.Path.GetExtension( fInfo.Name ) ),
                        Size = fInfo.Length
                    } );

Behaviors and Blend

One of the easiest ways to add a behavior [of the action] to a control is to use Blend to add an interaction behavior.  In our case we want a mouse over action to open up all of the Row Details and a secondary action to close them when the mouse leaves. The behavior we need to search for in blend is the ChangePropertyAction. Below we drag (or add) two behaviors to the datagrid and change the RowDetailsVisibilityMode to visible on mouse enter and to collapsed on mouse leave.

cpaEnter cpaLeave

Then when we build and run the app, the mouse hover over makes the descriptions visible and collapsed depending on the mouse. Here is the final xaml:

<DataGrid x:Name="dgPrimary"
            RowDetailsVisibilityMode="Collapsed">
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>

            <TextBlock FontWeight="Bold"
                        Text="{Binding Size, StringFormat=Size \{0\} (bytes)}" />

        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Original}"
                            Header="File Name Before"
                            IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding New}"
                            Header="File Name After"
                            IsReadOnly="True" />
    </DataGrid.Columns>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseEnter" SourceObject="{Binding ElementName=dgPrimary}">
            <ei:ChangePropertyAction x:Name="cpaEnter" PropertyName="RowDetailsVisibilityMode">
                <ei:ChangePropertyAction.Value>
                    <DataGridRowDetailsVisibilityMode>Visible</DataGridRowDetailsVisibilityMode>
                </ei:ChangePropertyAction.Value>
            </ei:ChangePropertyAction>
        </i:EventTrigger>
        <i:EventTrigger EventName="MouseLeave">
            <ei:ChangePropertyAction x:Name="cpaLeave"
                PropertyName="RowDetailsVisibilityMode" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
Share

Tags: , , , ,

Xaml Mammal Presentation Notes

Initial Meeting Notes and code:

Xs.Code for WPF

<Button Click="HandleClick"
        Name="TestButton"
        Width="50"
        Height="30"
        Content="Click Me!" />

<x:Code>

void HandleClick(object sender, RoutedEventArgs eventArgs)
{
    TestButton.Width = 100;
    TestButton.Content = "Thank you!";
    MessageBox.Show("Hello from Xaml");
}

</x:Code>

Links

Xaml Intellisense Presenter

Xaml Styler

buildwindowscontest.com

Silveright Lifespan

Share

.Net Regex: Can Regular Expression Parsing be Faster than XmlDocument or Linq to Xml?

iStock_000017256683XSmallMost of the time one needs the power of the xml parser whether it is the XmlDocument or Linq to Xml to manipulate and extract data. But what if I told you that in some circumstances regular expressions might be faster?

Most conventional development thinking has branded regex processing as slow and the thought of using regex on xml might seem counter intuitive. In a continuation of articles I again want to dispel those thoughts and provide a real world example where Regular Expression parsing is not only on par with other tools in the .Net world but sometimes faster. The results of my speed test may surprise you;  and hopefully show that regular expressions are not as slow as believed, if not faster!

See: Are C# .Net Regular Expressions Fast Enough for You?

Real World Scenario

There was a developer on the MSDN forums who needed the ability to count URLs in multiple xml files. (See the actual post count the urls in xml file on Msdn) The poster received three distinct replies, one to use XMLDocument, another provided a Linq to XML solution and I chimed in with the regular expression method. The poster took the XMLDocument method and marked as the answer, but could he have done better?

I thought so…

So I took the three replies and distilled them down into their core processing and wrapped them in a similar IO extraction layer and proceeded to time them. I created 48 xml files with over one hundred thousand urls to find for a total of 13 meg on disk. I then proceeded to run the test all in release mode to get the results.  (See below section Setup to get a gist repository of the code).

Real World Result

Five tests, each test name is the technology and the user as found on the original msdn post. In red is the slowest and fastest time. Remember XmlDoc is the one the user choose as the answer.

Test 1
Regex           found 116736 urls in 00:00:00.1843576
XmlLinq_Link_FR found 116736 urls in 00:00:00.2662190
XmlDoc_Hasim()  found 116736 urls in 00:00:00.3534628

Test 2
Regex           found 116736 urls in 00:00:00.2317883
XmlLinq_Link_FR found 116736 urls in 00:00:00.2792730
XmlDoc_Hasim()  found 116736 urls in 00:00:00.2694969

Test 3
Regex           found 116736 urls in 00:00:00.1646719
XmlLinq_Link_FR found 116736 urls in 00:00:00.2333891
XmlDoc_Hasim()  found 116736 urls in 00:00:00.2625176

Test 4
Regex           found 116736 urls in 00:00:00.1677931
XmlLinq_Link_FR found 116736 urls in 00:00:00.2258825
XmlDoc_Hasim()  found 116736 urls in 00:00:00.2590841

Test 5
Regex           found 116736 urls in 00:00:00.1668231
XmlLinq_Link_FR found 116736 urls in 00:00:00.2278445
XmlDoc_Hasim()  found 116736 urls in 00:00:00.2649262

 

Wow! Regex consistently performed better, even when there was no caching of the files as found for the first run! Note that the time is Hours : Minutes : Seconds and regex’s is the fastest at 164 millseconds to parse 48 files! Regex worst time of 184 milleseconds is still better than the other two’s best times.

How was this all done? Let me show you.

Setup

Ok what magic or trickery have I played? All tests are run in a C# .Net 4 Console application in release mode. I have created a public Gist (Regex vs Xml) repository of the code and data which is actually valid Git repository for anyone how may want to add their tests, but let me detail what I did here on the blog as well.

The top level operation found in the Main looks like this where I run the tests 5 times

Enumerable.Range( 1, 5 )
            .ToList()
            .ForEach( tstNumber =>
            {
                Console.WriteLine( "Test " + tstNumber );
                Time( "Regex", RegexFindXml );
                Time( "XmlLinq_Link_FR", XmlLinq_Link_FR );
                Time( "XmlDoc_Hasim()", XmlDoc_Hasim );
                Console.WriteLine( Environment.NewLine );
            }

while the Time generic method looks like this and dutifully runs the target work and reports the results in “Test X found Y Urls in X [time]”:

public static void Time<T>( string what, Func<T> work )
{
    var sw = Stopwatch.StartNew();
    var result = work();
    sw.Stop();
    Console.WriteLine( "\t{0,-15} found {1} urls in {2}", what, result, sw.Elapsed );
}

Now in the msdn post the different methods had differing ways of finding each xml file and opening it, I made them all adhere to the way I open and sum the ULR counts. Here is its snippet:

return Directory.EnumerateFiles( @"D:\temp", "*.xml" )
            .ToList()
            .Sum( fl =>
            {

            } );

Contender  –  XML Document

This is one which the poster marked as the chosen one he used and I dutifully copied it to the best of my ability.

public static int XmlDoc_Hasim()
{
    return Directory.EnumerateFiles( @"D:\temp", "*.xml" )
                .ToList()
                .Sum( fl =>
                {
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml( System.IO.File.ReadAllText( fl ) );

                    if (doc.ChildNodes.Count > 0)
                        if (doc.ChildNodes[1].HasChildNodes)
                            return doc.ChildNodes[1].ChildNodes.Count;

                    return 0;

                } );

}

I used the sum extension method which is a little different from the original sum operation used, but it brings the tests closer in line by using the Extension.

Contender – Linq to Xml

Of the other two attempts, this one I felt was the more robust of the two, because it actually handled the xml namespace. Sadly it appeared to be ignored by the original poster. Here is his code

public static int XmlLinq_Link_FR()
{
    XNamespace xn = "http://www.sitemaps.org/schemas/sitemap/0.9";

    return Directory.EnumerateFiles( @"D:\temp", "*.xml" )
                    .Sum( fl => XElement.Load( fl ).Descendants( xn + "loc" ).Count() );

}

Contender – Regular Expression

Finally here is the speed test winner. I came up with the pattern design Upon by looking at the xml and it appeared one didn’t need to match the actual url, but just the two preceding  tags and any possible space between. That is the key to regex, using good patterns can achieve fast results.

public static int RegexFindXml()
{
    string pattern = @"(<url>\s*<loc>)";

    return Directory.EnumerateFiles( @"D:\temp", "*.xml" )
                    .Sum( fl => Regex.Matches( File.ReadAllText( fl ), pattern ).OfType<Match>().Count() );

}

XML1 (Shortened)

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>http://www.linkedin.com/directory/companies/internet-web2.0-startups-social-networking/barcelona.html</loc><changefreq>weekly</changefreq></url>
<url><loc>http://www.linkedin.com/directory/companies/internet-web2.0-startups-social-networking/basel.html</loc><changefreq>weekly</changefreq></url>
<url><loc>http://www.linkedin.com/directory/companies/internet-web2.0-startups-social-networking/bath.html</loc><changefreq>weekly</changefreq></url>
<url><loc>http://www.linkedin.com/directory/companies/computer-networking/sheffield.html</loc><changefreq>weekly</changefreq></url>
<url><loc>http://www.linkedin.com/directory/companies/computer-networking/singapore.html</loc><changefreq>weekly</changefreq></url>
<url><loc>http://www.linkedin.com/directory/companies/computer-networking/slough.html</loc><changefreq>weekly</changefreq></url>
<url><loc>http://www.linkedin.com/directory/companies/computer-networking/slovak-republic.html</loc><changefreq>weekly</changefreq></url>
</urlset>

Xml2 Shortened

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>http://www.linkedin.com/groups/gid-2431604</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2430868</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/Wireless-Carrier-Reps-Past-Present-2430807</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2430694</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2430575</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2431452</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2432377</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2428508</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2432379</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2432380</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2432381</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2432383</loc><changefreq>monthly</changefreq></url>
<url><loc>http://www.linkedin.com/groups/gid-2432384</loc><changefreq>monthly</changefreq></url>
</urlset>

Summary

It really comes down to the right tool for the right situation and this one regex really did well. But Regex is not good at most xml parsing needs, but for certain scenarios it really shines. If the xml has malformed or the namespace was wrong, then the parser has its own unique problems which would lead to a bad count. All the technologies had to do some upfront loading and that is key to how they performed. Regex is optimized to handle large data efficiently and as long as the pattern is spot on, it can really be quick.

My thought is don’t dismiss regular expression parsing out of hand, while the learning of it can pay off in some unique text parsing situations.

Share

Tags: , ,

C# Silverlight: Codebehind Binding Between Two Controls Example

Here is a quick example of binding between two controls on the same xaml page. I have provided both ways of doing the binding the first in xaml and the second in the code behind. The first example is the most common method of binding in xaml while the other is the code behind, a more dynamic binding situation. 

Sometimes it helps to see a contrast if one is used to one or the other, a translation of sorts; so here it is:

Xaml Binding

The goal is to have the custom Slidebox control’s Spacing property to be bound to the TickTrack Control’s SpacingMargin property since these two controls have to work together (think of a slider control on a timeline).

If one were to do this in xaml it would look like this

<my:TickTrack
    x:Name="tkTrack"
    SecondsEnd="{Binding SecondsEnd, ElementName=userControl}"
    SecondsStart="{Binding SecondsStart, ElementName=userControl}"
    TickFrequency="{Binding TickFrequency, ElementName=userControl}"
    HorizontalAlignment="Left" Width="{Binding Width, ElementName=userControl}" Height="59" Canvas.Top="70" />

<my:SlideBox Spacing="{Binding SpacingMargin, ElementName=tkTrack}"  />

The slidebox spacing is now uses the named tkTrack control’s dependent property  (not shown but publicly available property on TickTrack).

Code Behind Binding

If one were to do the same in code behind, say for a dynamically created custom slidebox control:

var bndSpacing = new Binding()
                    {
                        Source = tkTrack, // Not the name but actual instance object
                        Path = new PropertyPath( "SpacingMargin" )
                    };

var sb = new SlideBox();

// "{Binding SpacingMargin, ElementName=tkTrack}"
sb.SetBinding( SlideBox.SpacingProperty,
               bndSpacing );

We create a binding instance with  the actual source and the path setup similar to xaml but different. The Source is not a named source but the actual object for the source to be bound to. Once we have the object, we then specify that the new slide box instance is to set the binding to the SpacingProperty (of the class description) dependency property of the slidebox instance.

Hope This Helps

Share

Tags: , ,

Fear and Loathing in Windows 8 with the Acer ICONIA 6120 Dual-Screen Touchbook

Windows 8 experience on top panel with Windows 7 visual experience on the lower touch panel.

I recently began my Windows 8 journey by installing the developer preview on an Acer Iconia 6120 or more commonly know as the dual touch screen laptop or touchbook as they have named it. My goal is to learn the metro style programming and experience the wave of the future in application development on tablet and smaller items. I am primarily a C# Silverlight developer so it is fundamental that I understand exactly what the pro’s and con’s of creating applications to the next version of windows will entail. The following are some of my initial thoughts on what I have run into as I have begun this journey which can be read by developers and non developers alike.

Souping up the TouchBook

I had purchased the Acer off of Ebay from a company which claimed they used differing laptops for demos for roughly a week, no more than ten hours of usage promised, and would sell them in a non new condition.. Long story short is that I didn’t have to pay MSRP on this gem so technically its used, but that is fine for my purposes.

There are many reasons purchasing this Touchbook which I will speak to, but the primary was for its cool factor of dual touch screens.  But I must admit that while waiting for shipment (which was delayed for a week unbeknownst to me from the seller (grrr)) my loathing began to take hold. I wondered if the dual screens would be functional within Windows 8 and thus would end up being a nice door stop for a future unknown open door draft choice in my house?Rating 4.2, Intel Core I5 M480 @2.67ghz, 4 GB of ram on 64bit OS with 10 touch points.

I also knew that Acer ships it with a Windows 7, so the possibility of bricking both screens felt remote and that the tablet is up to Microsoft’s specs for the minimum for Windows 8 screen resolution wise was 1024×768 and the screens on the Iconia are both 1366×768. 

On the downside one of coolest features found on the Iconia would probably not be there on Windows 8. That feature is where a user places his or her palms (see virtual keyboard) on the lower screen, hence bringing up Acer’s full sized virtual keyboard and yes it did not come over for Windows 8. As of this writing I am still unaware of how to get the target software to bring up Acer’s virtual keyboard which does come up in the bios actually. THe windows virtual keyboard does make its appearance as designed for Windows 8 albeit smaller form factor than the Inconia’s. Sad smile

The machine I choose had to be one where I could actively develop upon it and had to have more horse power than most of the tablets out there and the Acer fit that bill for dual usage. The fact that it came with an Intel Core I5 chip with four gig of ram meant that I could develop metro apps on Visual Studio 2011 preview, which requires 64bit at this time, and have a peppy machine to boot.

Alright you ask, what did you do to soup it up?

Once I got the laptop, I took off the backing panel of the Acer and removed it’s 640 gig Western Digital (5400 rpm) hard drive and gave it some real power with a Kingston SSDNow V+100 solid state drive. Its capacity is only 96 gig which is fine for a development machine to hold the OS and tools. I actually have one it in my primary work machine, a Dell XPS 17 Core I7 laptop, which I use on a daily basis, so it was a no brainer to use the Kingston again for the Acer. The above windows experience of 4.2 with the SSD is no barn burner it really does the job.

 

My Touching Windows 8 Experience

Now it is obvious that Microsoft has an Alpha version on their hands here but frankly the experience has been anything as such. I have yet to blue screen or have any major problems. It is apparent that Windows 8 builds off of Windows 7 for all drivers I have installed have installed without problems. The following are the problems or situations I have encountered using the Dual screen

Extended Windows Not Behaving as Expected
  1. Since the Acer is a Frankenstein dual screen tablet and a single screen the OS wants to treat the lower screen as just an extension of the top screen and it just doesn’t flow right.
    1. Only one screen is the full Windows 8 experience while the other screen is always the Windows 7 experience. When both screens are the seven experience, when dragging a window by touch to the lower window, the non touch area stops the window and the menu bar (the part which needs to be touched to have it moved) is stuck in the upper window and there is no way to flick it down to the lower window and a mouse must be used instead.
    2. Touching the lower screen also sends touch notifications to the upper screen. I believe this is a bug and hopefully will be fixed in upcoming versions.
  2. When working with a third screen attached from the HDMI port there is no way to have all three screens active in any configuration. So I have had to leave off the bottom screen when I work with an external monitor. The situation is shown below in the screen shots when trying to get all of them to work. The left picture shows the Iconia running with both screens while the right screen show s the monitor configuration I have to deal with while having the lower Iconia screen inactive. (Note even though the lower screen is inactive when using the other monitor the touch is still active on the screen and its actions are sent to the upper screen. Big bug.)
    Top and bottom of the laptop are enabled while the external monitor is disabled. The lower touch screen is disabled for the windows to work.
General Observations
  1. Most of the default Metro apps do not work on either of the Iconia’s screens! One touches them, the title splash screen comes up and eventually a blank screen of the default background color of the apps tile is shown. This situation, not related to the Iconia, has been reported to Microsoft (see When I click on an application tile, nothing happens. How can I launch the Metro applications?) and the answer was that the apps were running in less than 1024×768 resolution. For the Iconia this is not the case and should exceed that threshold by being 1366×768. In summary:
    1. Most apps fail on the Iconia’s screens and do not properly load.
    2. Most apps run on the third connected screen when the Windows 8 experience is brought to It.
    3. No error message is shown to the user.
    4. Developed apps (at least the few I have done), using the developer preview of Visual Studio 2011 work on the touch experience.
  2. Windows 8 doesn’t play well with non touch monitors. Sometimes the Windows 8 experience jumps on to the monitor and the program is expecting touch (?) actions and one has to force the windows 7 experience back to the monitor.
  3. IE 10 sometimes incorrectly reports a URL of another tab than the page being viewed when multiple tabs are being used.
  4. No Aero experience with Windows Key-Tab under W7 experience and if done under the W8 experience it is a single view change.
  5. Microsoft Virtual Keyboard needs to adapt to larger screens to give the full keyboard effect. The slimmed keyboard is frustrating to use when typing in passwords with numbers or symbols and one has to click over to show a different layout. If the screen real estate is available why not use it, or at least allow the user to configure it.

Summary

The touch experience of Windows Eight is still a long way off from being a reality. Frankly there needs to be a way to lock the experience of Windows 8 or Windows 7 to certain screens depending on the screens needs. It is a nice to have in certain situations say a true tablet experience, but the laptop or touch screens will want the older Windows 7 experience for the most part. I suspect that need to be accommodated by Microsoft as the versions evolve over time. So far I can use the Acer Iconia 6120 for my development purposes, but a true stand alone Windows 8 platform it is a long way off from being a useful stand alone experience.

Share

Tags: ,

Effective Silverlight 5

This is related to my presentation tonight (July 25, 2011) at the Denver Visual Studio User’s Group on Effective Silverlight 5 Development.

Links

 

RitchTextBox OverflowContentTarget Example

<StackPanel Width="400"
            VerticalAlignment="Top"
            Orientation="Horizontal">

    <RichTextBox x:Name="rtbPrimary"
                 Width="80"
                 Height="100"
                 Margin="5,10,0,0"
                 HorizontalScrollBarVisibility="Disabled"
                 VerticalScrollBarVisibility="Disabled"
                 OverflowContentTarget="{Binding ElementName=rtbOverflow}">
        <Paragraph>
            The Denver Visual Studio User's group is overflowing at 100 people! Come early to get a seat.
        </Paragraph>
    </RichTextBox>

    <RichTextBoxOverflow Width="200"
                         Height="100"
                         Margin="5,10,0,0"
                         HorizontalScrollBarVisibility="Disabled"
                         VerticalScrollBarVisibility="Disabled"
                         x:Name="rtbOverflow" />

</StackPanel>

HTML 5 Canvas

<!DOCTYPE html>
<title>Canvas Shapes and Sizes</title>
    <script type="text/javascript">
        window.onload = function () {
            var canvas = document.getElementById('cvPrimary');
            var ctx = canvas.getContext("2d");

            //Draw a rectangle
            ctx.fillStyle = 'Red';
            ctx.fillRect(10, 20, 50, 50);

            //Draw a circle
            ctx.arc(50, 150, 50, 0, 2 * Math.PI, false);
            ctx.fillStyle = 'Green';
            ctx.fill();

            //Draw an arc
            ctx.beginPath();
            ctx.arc(80, 280, 50, 0, Math.PI, false);
            ctx.fillStyle = 'Navy';
            ctx.fill();

            //Draw lines
            ctx.beginPath();
            ctx.moveTo(50, 350);
            ctx.lineTo(0, 450);
            ctx.lineTo(100, 450);
            ctx.lineTo(50, 350);
            ctx.strokeStyle = 'Orange';
            ctx.lineWidth = 4;
            ctx.stroke();
            ctx.fillStyle = 'Yellow';
            ctx.fill();
        };
</script>

<canvas id="cvPrimary" width="800" height="600"/>

Siverlight Extension

<navigation:Page xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
           x:Class="EffectiveSilverlight.Views.ExtensionOverview"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           xmlns:dvsug="clr-namespace:EffectiveSilverlight.Views"
           mc:Ignorable="d"
           xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           d:DesignWidth="640" d:DesignHeight="480"
           Title="ExtensionOverview Page">
    <StackPanel>
        <sdk:Label Margin="10,10,0,0"
                   FontSize="14"
                   FontFamily="Georgia"
                   FontWeight="Bold"
                   Content="{dvsug:DenverVSUG}"
                    />
    </StackPanel>
</navigation:Page>

 

using System.Xaml;

namespace EffectiveSilverlight.Views
{
    public class DenverVSUGExtension : IMarkupExtension<string>
    {

        public string ProvideValue(IServiceProvider serviceProvider)
        {

            return "88 people saw William Wegerson discuss Effective Silverlight";

        }

    }
}
Share

C# Silverlight WCF: Thread Safe Multiple Async Call Strategy With Final Operation To Join Data.

Seven Pointing Arrows ending at different points except one arror leaping of the page to show the final Async call.This article describes one way to handle asynchronous or async calls in .Net 3.5 or .Net 4.0 when using WCF in Silverlight in C#. The goal is to have a final operation wait for all the calls to finish so to combine all the data gathered, all in a thread safe way. A secondary goal is to minimize the consumer code required to perform this operation from what is currently available in straight WCF async calls.

This article has a short shelf life because after .Net 4 (see What’s Next in C#? Get Ready for Async!) one will use the built in Asynchrony methodology developed. Until that time if one is using any version of Silverlight and WCF then this article describes how to handle those multiple async calls and join the data in a final method call.

Final Result Example

Before delving into the solution, here is how the consumer will use the methodology. Below a user is getting account information of user requests, departments and accounts to join all the data on the view model in the final method for display on a Silverlight page. Thesee operations as shown are setup when the view model class (MyViewModel) is created and no blocking occurs keeping UI thread clear.

public MyViewModel()
{
    DataContext = new MyServiceClient();

    FinalAsync(CombineDataAndDisplay); // When all the data is retrieved, do this method to combine the data From the 3 async callls below

    // Provide the operation as a lambda (could be a method call) to assign data to our target backing store property
    // and if all has gone well (no errors in other async calls) and it is the final completing operation. Do the final
    // Processing call automatically.
    DataContext.GetUserRequestsCompleted   += (s, e) => { AssignResultCheckforAllAsyncsDone(e, e.Result, ref _UserRequests, "Acquisition failure for User Requests");};
    DataContext.GetAccountsCompleted       += (s, e) => { AssignResultCheckforAllAsyncsDone(e, e.Result, ref _Accounts, "Acquisition Failure for Accounts"); };
    DataContext.GetDepartments             += (s, e) => { AssignResultCheckforAllAsyncsDone(e, e.Result, ref _Departments, "Failed to get Department Info."); };   

    // Start the Async processes
    MultipleAsyncRun(DataContext.GetUserRequestsAsync);
    MultipleAsyncRun(DataContext.GetAccountsAsync);
    MultipleAsyncRun(DataContext.GetDepartmentsAsync);

    // Exit out and return the UI thread to the user operations.
}

// Once all the data is done, combine and assign into our
// PagedCollectionView property for display on the screen.
public void CombineDataAndDisplay()
{
    // Combine missing data on the calls
   _UserRequests.ToList()
                .ForEach(ur =>
                {
                ur.BillingName     = _Accounts.First(ac => ur.AccountID == ac.AccountID).Name;
                ur.DepartmentName  = _Departments.First(dp => dp.DepartmentID == ur.DepartmentID).Name;
                });

    UserRequests = new PagedCollectionView( _UserRequests);
    UserRequests.GroupDescriptions.Add(new PropertyGroupDescription("DepartmentName"));

}
Explanation
Line  5: The final async call is where this process specifies a method to use after all async calls are completed. On line 24 of the example is our final operation method to do that which is reported to FinalAsync.
Line 11-13: Just like the normal async process we subscribe to the anync handler but we handle it in a anonymous lambda.
Line 11-13: AssignResultCheckForAllAsyncsDone method will check the result returned, code show later in the article. All one needs to know now is that the respective _UserRequests, _Accounts and _Departments, all backing store variables (not properties) will be loaded with the data if the result information ( e ) operation contains no errors. This method does all the heavy lifiting by checking error state, loading the data variable, decrementing the async count and firing off the final method if all asynchronous operations are completed.
Line 16-18: Just like the normal WCF async process we must launch the asnc calls and these statements do just that. We supply the method to be launched inside the MulipleAsync method.
Line 24: Here is our final method to be executed once the asynchrony process is complete. This method combines all the async data internally into the _UserRequest object at which it becomes complete and can be used.
Line 34: Finally a paged collection view is created from our data to be bound to Silverlight Xaml items which is our end result.
24-37: Note: The section below has a variable entitled AsyncErrors. The above example did not check that for null or an error situation. I have left out the check of AsyncErrors for brevity of the example. See the last section for an example of proper error handling.

Multiple Async Methodology Plumbing

Below is what will needed to be brought into your View Model, or placed on your page if not using MVVM. This is where the .Net thread safe Silverlight asynchronous operations will occur.

// Lock Objects 0 for false, 1 for true.
private int AsyncErrorResource = 0;
private int AsyncFinal = 0;

private List<Exception> AsyncErrors;  // If not null errors have been encountered.

private int PendingAsyncOperations; // Holds the counted total of ongoing async operations. Zero means do users final operation.

private Action FinalOperation;      // The user's final operation.

public void MultipleAsyncRun(Action Operation)
{
    Interlocked.Increment(ref PendingAsyncOperations);
    Operation();
}

public void FinalAsync(Action method)
{
    FinalOperation = method;
}

public void AssignResultCheckforAllAsyncsDone<T>(AsyncCompletedEventArgs ea, T receivedData, ref T assignTo, string ErrorMessage)
   where T : class
{
    bool valid = !((ea.Error != null) || (receivedData == null));

    if (valid == false)
    {
        if (0 == Interlocked.Exchange(ref AsyncErrorResource, 1))
        {
            if (AsyncErrors == null)
                AsyncErrors = new List<Exception>();

            AsyncErrors.Add(ea.Error);

            //Release the lock
            Interlocked.Exchange(ref AsyncErrorResource, 0);
        }
    }
    else
    {
        assignTo = receivedData;
    }

    Interlocked.Decrement(ref PendingAsyncOperations);
    if (PendingAsyncOperations == 0)
    {
        if (0 == Interlocked.Exchange(ref AsyncFinal, 1))
        {
            FinalOperation();
        }

        Interlocked.Exchange(ref AsyncFinal, 0);
        Interlocked.Decrement(ref PendingAsyncOperations); // Move to -1
    }
}
Explanation
Line  2/3: These variables are used as a lock targets for thread safety. Value zero means its open and a value of 1 means a lock is in place.
Line  5: Any errors encountered are placed into AsyncErrors. The final operation must check this variable. If it is not null errors have occurred and data is incomplete see the final section of this article on how to handle errors.
Line 7: This variable will hold the running total async operations. Once it gets to zero the final operation will be executed.
Line 11: This method counts and stores our async operations as they come in and launches the async method as well.
Line 13: This process uses the Interlocked class found in the System.Threading namespace. To quote Microsoft, “Provides atomic operations for variables that are shared by multiple threads. “. We simply count up the PendingAsyncOperations variable. Later when the operations complete this will be decremented.
Line 18: This method is called by the consumer so we know what method to launch when all async operations have completed. We assign the method to a holder variable as found on line 9.
Line 22: This method will take in the event arguments and check if there is a problem. It will store the error if there is one and also decrement our count. If our count hits zero it will launch the users final operation.
25-39: Checking errors reported by the async call. If there are any we log them and do not assign the variable. Note whether an error exists or not the operation continues below where the final operation is checked for and executed. Its up to the final operation to check if errors exists and handle them appropriately.
Line 42: If the event reports a success this is where we assign the value to the passed in reference to the template T assignTo. If one doesn’t use a variable for assignTo reference an exception will be generated on this line. See the following section as to why. 
Line 46: We safely decrement our operations count variable. Zero means we are done!
Line 47-57: Here is where we execute the final operation when the count is zero. Note there is an extra lock if operations unlikely hit a zero at the same time. The extra lock ensures only one will execute the final method.

That is it, simply use the above code and you can have all your operations work done asynchronously. Smile Now for the disclaimers…

Why Can’t Properties be Used by AssignResultCheckforAllAsyncsDone?

We must use direct variables like in our example

private ObservableCollection<UserRequestDTO> _UserRequests;
private ObservableCollection<Account> _Accounts;
private ObservableCollection<Department> _Deparments;

// Not Private ObservableCollection<Department> _Departments { get; set; }

If one used a property this exception is thrown.

A property, indexer or dynamic member access may not be passed as an out or ref parameter

That is because we are using the generic method AssignResultCheckforAllAsyncsDone to assign a value, and that assignment has to have an exact object instance for the template (T) object and not a Property to assign the value. If your end result is in a property, simply assign it from the variable to the property in the final async call.

Handling Errors

Simply check the error variable if it is not null it has encountered errors.

if (AsyncErrors != null)
{
    MessageBox.Show("Errors: " + string.Join(string.Format("{0}{0}", Environment.NewLine), AsyncErrors.Select(ex => ex.Message)));
}
else
{
    // Success Handle accordingly.
}
Share

Tags: , , , ,