Asp.Net C#: Upgrading Website to Latest Version Gotchas and How to Resolve

iStock_000015438998XSmallOne can get lost in the weeds when upgrading an asp.net .Net 1 website to anything from .Net 2 through .Net 4.  One of the biggest problems after the initial conversion is that when built each page or control throws a build error:

Could not load type ‘MyNamespace.myWebPage’.

The issue stems from the fact that things changed, made life easier for new projects, and namespaces which were required were removed and certain attributes changed. To resolve the above issue follow these steps presented in this article.

In the code behind file

  1. Remove the namespace scope. In the example below remove the highlighted lines:
    namespace MyNamespace
    {
        public class myWebPage : System.Web.UI.Page {}
    }
  2. Add the modifier partial to the class definition to make it look like this
    public partial class myWebPage : System.Web.UI.Page { ... }

In the aspx File

Which initially looks like this:

<%@ Page language="c#" AutoEventWireup="false"
                       Codebehind="myWebPage.aspx.cs"
                       Inherits="MyNamespace.myWebPage" %>
  1. Change the attribute Codebehind to CodeFile.
  2. Remove the namespace from the value found in the attribute Inherits.

The result should look like this:

<%@ Page language="c#" AutoEventWireup="false"
                       Codefile="myWebPage.aspx.cs"
                       Inherits="myWebPage" %>
Share

Tags: , ,

Silverlight (How To): Manipulation of Dynamic Selection Rubber Band in C#

Large group of women exercising in the parkOne of the basic tenets of WYSIWYG is to be able to create a rubber band region using the mouse to give the user the ability to create a selectable region. This article demonstrates how to do that in any version of Silverlight and the user is given the tools to create such a bounding rectangle in any circumstances via the usage of some basic building blocks in Silverlight.

The below picture (not the one on the left) shows our goal, the dynamic creation of a bounding rubber band (a rectangle control for this demonstration) in a canvas. The below canvas is drawn in black (visually grey due to the opacity set) while the bounding rectangle shows itself in red.

RubberBanding

The user starts the process with an initial click which designates a start location of an upper left point for our bounding box with a mouse click.  Once the click happens the mouse cursor changes to a hand (if moving to the lower right) as a visible indicator that the process has started. While user continues to move to the lower right the band grows and while the mouse button has yet to be let go or released. For the demo a bounded number is shown is which relates the actual dynamic change in the X (horizontal) position. That is done for this article only and the above picture shows the rectangle with an X size of 123 pixels and can still be grown as shown by the hand icon.

Initial Xaml

In the page’s xaml we add a grid and a canvas as such this:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="33*" />
        <RowDefinition Height="267*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="32*" />
        <ColumnDefinition Width="568*" />
    </Grid.ColumnDefinitions>
    <Canvas x:Name="cMain"
            MouseLeftButtonDown="cMain_MouseLeftButtonDown"
            MouseLeftButtonUp="cMain_MouseLeftButtonUp"
            MouseMove="cMain_MouseMove"
            Grid.Row="1"
            Grid.Column="1">
        <TextBlock Width="100"
                    Height="30"
                    Text="{Binding XValue, ElementName=userControl}"
                    />
        <Rectangle Fill="Black"
                    Width="550"
                    Height="200"
                    Opacity=".25"/>
    </Canvas>
</Grid>

The things to note are that the canvas is in a grid which is offset from the initial by 30 pixels in both axis. We then place a rectangle on the canvas which is our area which will be our strike zone where we will intercept the messages mouse events. We have a strike zone because individual controls in a canvas, such as texblocks have whitespace between them and the canvas will not get the mouse clicks and we want to be able to capture the process at all locations on the canvas; hence we fill up the canvas with our strike zone as to be ensured that the events are consumed properly by the code. 

When the user clicks within the strike zone the process starts as signified by a cursor change to the hand, as the user moves within the zone the rubber banding increases and when the mouse button is let up the process ends and the cursor is returned to its previous state.

Initial Properties

Here are the three variables we will use during this process:

private int _xValue;

public int XValue
{
    get { return _xValue; }
    set
    {
        _xValue = value;
        OnPropertyChanged( "XValue" );
    }
}

private Point OriginatingPostionOnCanvas { get; set; }

private Rectangle RubberBandBox { get; set; }

Since the XValue property is reflected on the screen in a text box it reports all changes by using  INotifyPropertyChanged which our class handles in a standard way for notify property (not shown). Followed by that is our initial click location named OriginatingPostionOnCanvas which will dictate the upper left (or lower right) location of the rubber band rectangle which we will dynamically create. The last variable is the actual dynamic rectangle control named RubberBandBox which will be created and modified during the process.

Event Mouse Left Button Down

We will handle three events during this process. The first is the when the user clicks and begins to hold down the mouse button:

private void cMain_MouseLeftButtonDown( object sender, MouseButtonEventArgs e )
{
    OriginatingPostionOnCanvas = e.GetPosition( cMain );

    RubberBandBox = new Rectangle() { Width = 1,
                                      Height = 1,
                                      Fill = new SolidColorBrush( Colors.Red ),
                                      Opacity = .1
                                    };

    RubberBandBox.SetValue( Canvas.LeftProperty, OriginatingPostionOnCanvas.X);
    RubberBandBox.SetValue( Canvas.TopProperty,  OriginatingPostionOnCanvas.Y );

    cMain.Children.Add( RubberBandBox );
}

Our goals here are simple:

  1. Get and store the location where the user clicked in relation to the canvas.
  2. Create  and store the rectangle in red and with an opacity which does allows the user to see what is being selected.
  3. Setting the initial location of the rectangle and adding it to the children of the canvas.

Event Mouse Move

The user is moving and we must adjust the rectangle as appropriate for the target direction. Note we also have to handle when the user moves to the upper left instead of the lower right…. So when that happens we will change the cursor to a Stylus (the dot) for visual indication that we are getting a reverse band situation.

private void cMain_MouseMove(object sender, MouseEventArgs e)
{
    if (RubberBandBox == null)
        return;

    Point pointMovedTo = e.GetPosition( cMain );

    double xDelta = pointMovedTo.X - OriginatingPostionOnCanvas.X;
    double yDelta = pointMovedTo.Y - OriginatingPostionOnCanvas.Y;

    LayoutRoot.Cursor = ((xDelta > 0) && (yDelta > 0)) ? Cursors.Hand : Cursors.Stylus;

    if (LayoutRoot.Cursor == Cursors.Hand)
    {
        RubberBandBox.Height = yDelta;
        RubberBandBox.Width  = xDelta;
    }
    else if (LayoutRoot.Cursor == Cursors.Stylus)
    {
        RubberBandBox.Height = Math.Abs( yDelta );
        RubberBandBox.Width = Math.Abs( xDelta );

        if (xDelta < 0)
            RubberBandBox.SetValue( Canvas.LeftProperty, pointMovedTo.X );

        if (yDelta < 0)
            RubberBandBox.SetValue( Canvas.TopProperty, pointMovedTo.Y );
    }

    XValue = (int) (e.GetPosition( cMain ).X - OriginatingPostionOnCanvas.X);
}
Explanation
Line 3 The mouse can move through the canvas during times we are not processing. We need to check that and only process when we have an actual rectangle on the canvas.
Line 6 Extract the current location in relation to the canvas.
Line 8-9 Get the change differences for x and y as named deltas.
Line 11 If the deltas retrieved are in the positive we have a drag to the lower right and that is designated by or specifying the cursor to a hand. If not, the deltas indicate that movement is upwards and to the left; regardless change the  cursor to the stylus.
Line 13 If we are in the hand state, we want to grow (or decrease) the rectangle in that direction towards the lower right.
Line 18 If we are in the stylus state, there is a negative growth either in the x or y axis. Handle the negatives while changing the height and width. Depending on which delta is negative, handle the new location position of the upper left hand position of our bounding rectangle which will follow the mouse.
Line 30 Inform the user of the current X axis location of the mouse whether positive or negative.

Event Mouse Left Button Up

This is our final event we have to handle. We do a safety check on whether we are actually in operations, and if we are then we simply return the cursor to its original state and remove the rectangle from the canvas’ children.

private void cMain_MouseLeftButtonUp( object sender, MouseButtonEventArgs e )
{
    if (RubberBandBox == null)
        return;

    // Return to the previous state; whatever it is, the OS handles it.
    LayoutRoot.Cursor = null; 

    cMain.Children.Remove( RubberBandBox );

    // Show that we are not processing by making this null.
    RubberBandBox = null;
}
Share

Tags: , , ,

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: ,