in

ASP.NET Weblogs

Natty Gur

.Net from enterprise architect point of view.

December 2003 - Posts

  • What goes in ViewState when page EnableViewState property is set to false?

    I bet that many of you sow that the __viewstate filed still holding data even if all page controls and the page itself EnableViewState property set to false. Well, what’s going on, what is saved by the page in the ViewState although we turn ViewSate off?

    To answer this question lets check what value is being saved in ViewState and what he stands for. We will start by overriding SavePageStateToPersistenceMedium method that responsible for saving the ViewState data to persist media (hidden field as default). This method gets an object parameter that is actually Triplet object. Triplet class holds three objects that can be added together to an ASP.NET server control's view state in hierarchical order. For the simplicity of that demonstration let’s talk about a page without any controls that we set it EnableViewState property to false. In this case the triplet object will hold value just in the First member. The First member holds a number, remember that number and continue the page process.

    After getting the value preserved in the view state lets see what he means. To do so I’ll use stuffs that I described in “Behind the scenes of ASPX files”. Check the page XML file for it random key and open the RandomKey.cs file. Look for the GetTypeHashCode method in the cs file and you will find that it’s the same number that the page preserve to ViewState. To be more accurate this number is hash code that is unique to the Page object's control hierarchy.

  • X# - Interesting

    Today WEB applications business logic tier responsible to transform Structure data into hierarchical data. Business Logic deals with objects graphs, Structure data from databases and hierarchical data (XML/HTML). Those three worlds aren’t very well integrated. X# aim is to overcome this shortcoming.

    If you find X# interesting refer to the following link : http://www.research.microsoft.com/~emeijer/Papers/XS.pdf

     

    but dead ... http://weblogs.asp.net/dbrowning/archive/2003/12/16/43866.aspx

     

    Thank you guys ...

  • Getting “Could not find any resources “error while using some resource files to make the internationalization of a ASP.NET application

    If you getting this error “Could not find any resources appropriate for the specified culture (or the neutral culture) in the given assembly. Make sure …” while trying to load Resources using ResourceManager from multi language assemblies it’s usually caused by loading the Resource file with this code:

     

    <code>

    ResourceManager resources = new ResourceManager(

                    "<ResName>",

                    Assembly.GetExecutingAssembly(),

                    null );

     

    </code>

     

    While this code is suggested by MSDN : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemResourcesResourceManagerClassctorTopic4.asp, it’s missing the <WebProjectName>. So it should be like this:

     

    ResourceManager resources = new ResourceManager(

        "<WebProjectName>.<ResName>",

         Assembly.GetExecutingAssembly(),

         null );

     

    Where the resx files are named: <ResName>.<Culture>.resx

     

    It’s also recommended to create only a single instance of the ResourceManager for your web app and to keep ResourceManager in a static class member or the Application object.  This causes the resources to be loaded only once per application.

  • Products: digital camera, TabletPC, cellular modem - Sunset in Eilat (Israel)

    Yea, I'm in vacation!

  • Behind the scenes of ASPX files

    ASP.NET pages usually made up from two files the ASPX file which contain the page visualization declaration and *.cs file which contain code to handle page events (Code behind). While all the *.cs files compile into one DLL (with the application name) and the page life cycle is well documented (http://www.15seconds.com/issue/020102.htm) this is not the case of ASPX files.

     

    Well what is really happened to those ASPX files? In the end of the day ASP.NET turn each ASPX file into assembly. While page is been called for the first time ASP.NET  :

    1)      generate *.cs file holding code that match the ASPX declarations.

    2)      Using csc.exe (C# compiler) to compile *cs file into DLL (you can see csc.exe if you monitor running processes).

    3)      Running the compiled DLL

    This sequence is happened just one time resulting with DLL that will be used for other request until one of the page dependencies file will be change and this sequence will be forced again. If you ever wonder why running application for the first time take so much time you probably got good notion why.

     

    To understand better what is going on here let’s take very simple page and follow those steps. I create simple page that hold Panel, Textbox and server side script inside ASPX file. Bellow you can see the ASPX file:

     

    <%@ Import Namespace="System.Web" %>

    <%@ Page language="c#" Codebehind="WebForm13.aspx.cs" AutoEventWireup="false" Inherits="WebApplication22.WebForm13" %>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

    <HTML>

                <HEAD>

                            <title>WebForm13</title>

                            <meta content="Microsoft Visual Studio 7.0" name="GENERATOR">

                            <meta content="C#" name="CODE_LANGUAGE">

                            <meta content="JavaScript" name="vs_defaultClientScript">

                            <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">

                </HEAD>

                <body MS_POSITIONING="GridLayout">

                            <script language="C#" runat="server">

                            private void myfunc(object sender, System.EventArgs e)

                            {

                                        HttpContext.Current.Response.Write("Text Init");                                

                            }

                            </script>

                            <form id="WebForm13" method="post" runat="server">

                                        <asp:TextBox id="TextBox1" OnLoad="myfunc" style="Z-INDEX: 101; LEFT: 101px; POSITION: absolute; TOP: 114px" runat="server" Width="170px" Height="48px"></asp:TextBox>

                                        <asp:Panel id="LblNav" style="Z-INDEX: 102; LEFT: 22px; POSITION: absolute; TOP: 63px" runat="server" Width="269px">Panel</asp:Panel>

                            </form>

                </body>

    </HTML>

     

    All the files that ASP.NET generated will be placed in this folder: C:\$WINDOWSDir$\Microsoft.NET\Framework\v1.0.3705\Temporary ASP.NET Files\$YourWebAppName$\42343\654564. Where the last two folders are randomly numbers generated by ASP.NET. The fun begins from the last directory. That folder holds all the files generated for ASPX files, ASCX files (user control) and ASAX file. The last folder also contain folder called Assembly that holds another directory: dl2. The “dl2” folder contains sub folders with randomly number names each for every referenced assembly from the web project, including the application DLL. We will be focused in the folder that contains all the files generated for ASPX, ASCX and ASAX files.

     

    The first file that we interest in is XML file holding the page name (WebForm13.aspx.4689d8a0.xml) . This file contains information that map between the web page name and randomly number that will be used by ASP.NET to generate that page files. Beside the mapping information this file contains data on the decency files of that page (change in that files will cause recreation of ASPX files and recompilation). :

     

    <preserve assem="jibrfh34" type="ASP.WebForm13_aspx" hash="49b238a170c332">

        <filedep name="c:\inetpub\wwwroot\WebApplication22\bin\WebApplication22.DLL" />

        <filedep name="c:\inetpub\wwwroot\WebApplication22\WebForm13.aspx" />

    </preserve>

     

    After grasping that every file that starting with “jibrfh34“ are files that generated for certain page lets see what every file used to. The most important file is *.cs. this file holds the generated C# lines correspond to ASPX Tags and code, we will discuss it later.  The *res file holds resources that the compiler will use them. *cmdline holds the command line that will be use by ASP.NET to compile the *cs file. The file includes reference to other assemblies and optimization settings. *.err file contains errors (if ocured)  while compiling *.cs file. *out file contain outputs from the compilation process. *.dll and *pdb are naturally the compilation output.

     

    Out next step is deep diving into *.cs file:

    namespace ASP {

        using System;

        using System.Collections;

        using System.Collections.Specialized;

        using System.Configuration;

        using System.Text;

        using System.Text.RegularExpressions;

        using System.Web;

        using System.Web.Caching;

        using System.Web.SessionState;

        using System.Web.Security;

        using System.Web.UI;

        using System.Web.UI.WebControls;

        using System.Web.UI.HtmlControls;

        using ASP;

       

       

        [System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]

        public class WebForm13_aspx : WebApplication22.WebForm13, System.Web.SessionState.IRequiresSessionState {

           

           

            #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

            protected System.Web.UI.HtmlControls.HtmlForm WebForm13;

           

            #line default

           

            private static bool __intialized = false;

           

            private static object __stringResource;

           

            private static System.Collections.ArrayList __fileDependencies;

           

           

            #line 13 "http://localhost/WebApplication22/WebForm13.aspx"

           

                            private void myfunc(object sender, System.EventArgs e)

                            {

                                        HttpContext.Current.Response.Write("Text Init");                                

                            }

                           

            #line default

           

            public WebForm13_aspx() {

                System.Collections.ArrayList dependencies;

                if ((ASP.WebForm13_aspx.__intialized == false)) {

                    ASP.WebForm13_aspx.__stringResource = System.Web.UI.TemplateControl.ReadStringResource(typeof(ASP.WebForm13_aspx));

                    dependencies = new System.Collections.ArrayList();

                    dependencies.Add("c:\\inetpub\\wwwroot\\WebApplication22\\WebForm13.aspx");

                    ASP.WebForm13_aspx.__fileDependencies = dependencies;

                    ASP.WebForm13_aspx.__intialized = true;

                }

                this.Server.ScriptTimeout = 30000000;

            }

           

            protected override bool SupportAutoEvents {

                get {

                    return false;

                }

            }

           

            protected ASP.Global_asax ApplicationInstance {

                get {

                    return ((ASP.Global_asax)(this.Context.ApplicationInstance));

                }

            }

           

            public override string TemplateSourceDirectory {

                get {

                    return "/WebApplication22";

                }

            }

           

            private System.Web.UI.Control __BuildControlTextBox1() {

                System.Web.UI.WebControls.TextBox __ctrl;

               

                #line 20 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl = new System.Web.UI.WebControls.TextBox();

               

                #line default

                this.TextBox1 = __ctrl;

               

                #line 20 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.ID = "TextBox1";

               

                #line default

               

                #line 20 "http://localhost/WebApplication22/WebForm13.aspx"

                ((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style", "Z-INDEX: 101; LEFT: 101px; POSITION: absolute; TOP: 114px");

               

                #line default

               

                #line 20 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.Width = System.Web.UI.WebControls.Unit.Parse("170px", System.Globalization.CultureInfo.InvariantCulture);

               

                #line default

               

                #line 20 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.Height = System.Web.UI.WebControls.Unit.Parse("48px", System.Globalization.CultureInfo.InvariantCulture);

                

                #line default

               

                #line 20 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.Load -= new System.EventHandler(this.myfunc);

               

                #line default

               

                #line 20 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.Load += new System.EventHandler(this.myfunc);

               

                #line default

                return __ctrl;

            }

           

            private System.Web.UI.Control __BuildControlLblNav() {

                System.Web.UI.WebControls.Panel __ctrl;

               

                #line 21 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl = new System.Web.UI.WebControls.Panel();

               

                #line default

                this.LblNav = __ctrl;

               

                #line 21 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.ID = "LblNav";

               

                #line default

               

                #line 21 "http://localhost/WebApplication22/WebForm13.aspx"

                ((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style", "Z-INDEX: 102; LEFT: 22px; POSITION: absolute; TOP: 63px");

               

                #line default

               

                #line 21 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.Width = System.Web.UI.WebControls.Unit.Parse("269px", System.Globalization.CultureInfo.InvariantCulture);

               

                #line default

                System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

               

                #line 21 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(new System.Web.UI.LiteralControl("Panel"));

               

                #line default

                return __ctrl;

            }

           

            private System.Web.UI.Control __BuildControlWebForm13() {

                System.Web.UI.HtmlControls.HtmlForm __ctrl;

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl = new System.Web.UI.HtmlControls.HtmlForm();

               

                #line default

                this.WebForm13 = __ctrl;

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.ID = "WebForm13";

               

                #line default

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                __ctrl.Method = "post";

               

                #line default

                System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n\t\t\t"));

               

                #line default

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                this.__BuildControlTextBox1();

               

                #line default

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(this.TextBox1);

               

                #line default

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n\t\t\t"));

               

                #line default

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                this.__BuildControlLblNav();

               

                #line default

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(this.LblNav);

               

                #line default

               

                #line 19 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n\t\t"));

               

                #line default

                return __ctrl;

            }

           

            private void __BuildControlTree(System.Web.UI.Control __ctrl) {

                System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

               

                #line 1 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(this.CreateResourceBasedLiteralControl(0, 397, true));

               

                #line default

               

                #line 1 "http://localhost/WebApplication22/WebForm13.aspx"

                this.__BuildControlWebForm13();

               

                #line default

               

                #line 1 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(this.WebForm13);

               

                #line default

               

                #line 1 "http://localhost/WebApplication22/WebForm13.aspx"

                __parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n\r\n\t</body>\r\n</HTML>\r\n"));

               

                #line default

            }

           

            protected override void FrameworkInitialize() {

                SetStringResourcePointer(ASP.WebForm13_aspx.__stringResource, 397);

                this.__BuildControlTree(this);

                this.FileDependencies = ASP.WebForm13_aspx.__fileDependencies;

                this.EnableViewStateMac = true;

            }

           

            public override int GetTypeHashCode() {

                return 423941586;

            }

        }

    }

     

    In a fast glimpse you can notice that the file contains notes that map the code to the HTML lines in the source ASPX file. You can use those lines to see how ASP.NET converts HTML lines and learn from it a lot.

    Every file is definition of class that inherits from the code behind class and implement interface:

     

    public class WebForm13_aspx : WebApplication22.WebForm13, System.Web.SessionState.IRequiresSessionState

     

    This class (WebForm13_aspx) will be called before the code behind class. First the class constructor will be called. The constructor initialize the class dependencies files. The first function to be called is FrameworkInitialize. FrameworkInitialize called __BuildControlTree function that responsible to create all the page controls. __BuildControlTree called __ BuildControlWebForm13 that create the Form and called __BuildControlXXX for every control on the form. If control holds child’s controls a call will be made to the corresponding __BuildControlXXX of every child control. Every function create object by the ASPX declaration set its attribute and attached all events that declared on ASPX file. Every function declared in ASPX file generate as class method and connected to the correspond delegate, if needed.

     

    As I mention the *CS file is compiled into assembly just the first time ASP.NET is calling a page. More then once I saw that changes that made in the ASPX file are not reflected in the HTML send to the browser. In such scenario deleting the files under the right folder under Temporary ASP.NET will solve the problem since all the files will be recreated. Another issue that you should be aware of is that events of control initialization in c# aren’t happened in the code behind file but works perfectly in the ASPX code.

     

    After understanding what goes with ASPX files, let go back to the page life cycle and update it. There are two classes in that process:

    1)      The code behind class – WebForm1.

    2)      The generated class for ASPX file – adbdef.

     

    The calls orders are:

    1)      Constructing of adbdef.

    2)      Constructing of WebForm1.

    3)      FrameworkInitialize method of adbdef class will be called.

    4)      Calling __ BuildTree and other control build functions.

    5)      Calling the Page and controls events by their order. If event will be declared in ASPX file and code behind, the ASPX event will be called first following by the code behind event.

     

  • Display HTML controls inside MS Treeview control.

    This is the final product, looks very nice ;-).

    Well, if you will add decode HTML to a TreeView node text the browser will render that HTML into visual controls inside the tree:

    Microsoft.Web.UI.WebControls.TreeNode oNode1 = new Microsoft.Web.UI.WebControls.TreeNode();

    oNode1.Text = Server.HtmlDecode("<INPUT style=\"Z-INDEX: 104\" type=\"text\">");

    Microsoft.Web.UI.WebControls.TreeNode oNode = new Microsoft.Web.UI.WebControls.TreeNode();

    oNode.Text = Server.HtmlDecode("<INPUT style=\"Z-INDEX: 104\" type=\"text\">");

    oNode.Nodes.Add (oNode1);

    this.TreeView2.Nodes.Add(oNode); 

    As you see it’s pretty easy and might be useful. Naturally you can assign any attributes to those HTML controls, such as ID or events (including PostBacks).

  • Longhorn, Windows applications navigation abilities.

    After checking the web navigation abilities it’s the windows application turn. As part of dressing windows application as web application windows application got their own navigation abilities. Avalon enables you to create navigation applications. To create such application you can use Whidbey and open new “Longhorn navigation application” project:

       namespace NavigationApplication2

    {

        /// <summary>

        /// Interaction logic for Application.xaml

        /// </summary>

        public partial class MyApp : NavigationApplication

        {

        }

    } 

    Working with the navigation system is strait forward. You need to declare a base window which serve as a container to Panels (usually FlowPanel) that holds the display data. The main page contains the navigation buttons and the code to operate them. Each navigation between FlowPanel save the page in dedicate object called Journal. This object holds the page history and optionally state for every one of them. The main page derived from NavigationWindow and defines the first panel to load by using the WindowNavigationContainer tag:

    <NavigationWindow 

        xmlns="http://schemas.microsoft.com/2003/xaml"

        xmlns:def="Definition"

        def:Class="NavigationApplication2.Window1"

        def:CodeBehind="Window1.xaml.cs"

        Text="NavigationApplication2" Visible="True"

        Activated="OnActivated" Deactivated="OnDeactivated"

        Loaded="OnWindowLoaded"

        >

        <!--  The namespace + class name in the codebehind file and the def:Class attribute in the root of this document, must stay identical.  You can change them, but you must keep them in sync. -->

       

        <NavigationWindow.Resources>

            <Style def:Name="BackButton">

                <Button/>

                <Style.VisualTree>

                    <Image def:StyleID="img" />

                </Style.VisualTree>

    <!-- Note: this is currently using Images, in the future it should be done using vector shapes, not images -->

                <Style.VisualTriggers>

                    <PropertyTrigger Property="IsEnabled" Value="false">

                        <Set PropertyPath="Image.Source" Value="Images/travelbackdisabled.png" Target="img" />

                    </PropertyTrigger>

                   

                    <PropertyTrigger Property="IsEnabled" Value="true">

                        <Set PropertyPath="Image.Source" Value="Images/travelbacknormal.png" Target="img" />

                    </PropertyTrigger>

                    <PropertyTrigger Property="IsMouseOver" Value="true">

                        <Set PropertyPath="Image.Source" Value="Images/travelbackhot.png" Target="img" />

                    </PropertyTrigger>

                   

                    <PropertyTrigger Property="Pressed" Value="true">

                        <Set PropertyPath="Image.Source" Value="Images/travelbackpressed.png" Target="img" />

                    </PropertyTrigger>

                </Style.VisualTriggers>

            </Style>

           

            <Style def:Name="ForwardButton">

                <Button/>

                <Style.VisualTree>

                    <Image def:StyleID="img" />

                </Style.VisualTree>

                <Style.VisualTriggers>

                    <PropertyTrigger Property="IsEnabled" Value="false">

                        <Set PropertyPath="Image.Source" Value="Images/travelfwddisabled.png" Target="img" />

                    </PropertyTrigger>

                   

                    <PropertyTrigger Property="IsEnabled" Value="true">

                        <Set PropertyPath="Image.Source" Value="Images/travelfwdnormal.png" Target="img" />

                    </PropertyTrigger>

                    <PropertyTrigger Property="IsMouseOver" Value="true">

                        <Set PropertyPath="Image.Source" Value="Images/travelfwdhot.png" Target="img" />

                    </PropertyTrigger>

                   

                    <PropertyTrigger Property="Pressed" Value="true">

                        <Set PropertyPath="Image.Source" Value="Images/travelfwdpressed.png" Target="img" />

                    </PropertyTrigger>

                </Style.VisualTriggers>

            </Style>

            <!-- Gradient used in NavBar Background when window is active -->

            <LinearGradientBrush def:Name="ActiveGradient">

                <LinearGradientBrush.GradientStops>

                    <GradientStop Offset="0.0" Color="#FF4E4E4E"/>

                    <GradientStop Offset="0.1" Color="#FF646464"/>

                    <GradientStop Offset="0.2" Color="#FF767676"/>

                    <GradientStop Offset="0.3" Color="#FF8E8E8E"/>

                    <GradientStop Offset="0.4" Color="#FF9E9E9E"/>

                    <GradientStop Offset="0.5" Color="#FFA5A5A5"/>

                    <GradientStop Offset="0.6" Color="#FF9E9E9E"/>

                    <GradientStop Offset="0.7" Color="#FF8E8E8E"/>

                    <GradientStop Offset="0.8" Color="#FF767676"/>

                    <GradientStop Offset="0.9" Color="#FF646464"/>

                    <GradientStop Offset="1.0" Color="#FF4E4E4E"/>

                </LinearGradientBrush.GradientStops>

            </LinearGradientBrush>

           

            <!-- Gradient used in NavBar Background when window is inactive -->

            <LinearGradientBrush def:Name="InactiveGradient">

                <LinearGradientBrush.GradientStops>

                    <GradientStop Offset="0.0" Color="#FF9CA1A2"/>

                    <GradientStop Offset="0.1" Color="#FFA9ADAE"/>

                    <GradientStop Offset="0.2" Color="#FFB3B8B9"/>

                    <GradientStop Offset="0.3" Color="#FFBFC2C3"/>

                    <GradientStop Offset="0.4" Color="#FFC7CACB"/>

                    <GradientStop Offset="0.5" Color="#FFCBCECF"/>

                    <GradientStop Offset="0.6" Color="#FFC7CACB"/>

                    <GradientStop Offset="0.7" Color="#FFBFC2C3"/>

                    <GradientStop Offset="0.8" Color="#FFB3B8B9"/>

                    <GradientStop Offset="0.9" Color="#FFA9ADAE"/>

                    <GradientStop Offset="1.0" Color="#FF9CA1A2"/>

                </LinearGradientBrush.GradientStops>

            </LinearGradientBrush>

        </NavigationWindow.Resources>

        <!-- Workaround - shouldn't need hardcoded height. -->

        <FlowPanel ID="navBar" DockPanel.Dock="Top" Width="100%" Height="54px" >

            <Button ID="backButton" Visibility ="Visible"  IsEnabled="True" Click="OnBackClicked" Style="{BackButton}"></Button>

            <Button ID="forwardButton" Visibility ="Visible" IsEnabled="True" Click="OnForwardClicked" Style="{ForwardButton}"></Button>

        </FlowPanel>

        <WindowNavigationContainer ID="wNavContainer" SourceUri="Pane1.xaml" Navigated="OnNavigated" >

       

        </WindowNavigationContainer>

    </NavigationWindow>

    The page content should be inside panel so you need to create panel for every “Page” that you want to display. For demonstration purpose I’m going to use FlowPanel. The Panel XAML holds the visualization declaration, I use button to navigate to other “windows” but there are dedicate hyperlink control for navigation purpose. The XAML code behind holds the code to navigate to another Panel. To cause navigation you should use Navigate method of WindowNavigation type. To use WindowNavigation I use Application.MainWindow to get a reference to the container window and to navigate to other panel :

    XAML :

    <FlowPanel 

        xmlns="http://schemas.microsoft.com/2003/xaml"

        xmlns:def="Definition"

        def:Class="NavigationApplication2.Pane1"

        def:CodeBehind="Pane1.xaml.cs"

        >

        <!--  The namespace + class name in the code behind file and the def:Class attribute in the root of this document, must stay identical.  You can change them, but you must keep them in sync. -->

       

        <!--

        <SimpleText>Hello World</SimpleText>

        -->

        <Text > Wellcome </Text>

        <Button ID="a" Click="OnClick" ToolTip ="Press me, please!!!!">Go to 1</Button>

    </FlowPanel>

    Code behind:

    namespace NavigationApplication2

    {

        /// <summary>

        /// Interaction logic for Pane1.xaml

        /// </summary>

        public partial class Pane1 : FlowPanel

        {

            // To use PaneLoaded put Loaded="PaneLoaded" in root element of .xaml file.

            // private void PaneLoaded(object sender, EventArgs e) {}

            // Sample event handler: 

            // private void ButtonClick(object sender, ClickEventArgs e) {}

                            private void OnClick(object sender, ClickEventArgs e)

                            {

                                        ((NavigationWindow)Application.MainWindow).Navigate(new Uri("PaneNavigationWindow1.xaml", false, true));

                            }

        }

    }

    Longhorn navigation application enables the end user to navigate easily between windows of your application (similar to web navigation). Navigation enhanced the user experience and its relatively easy to implement.

     

  • Starting ASP.NET state service result in error message.

    One of my customers didn’t succeed to start the ASP.NET state service. Every time he tries to start the service an error message pops up. Well that service occupied a port to supply it services and the problem was that other process on the computer already uses that port. You can check the current port number and change it in the following registry entry:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\Port

  • Do you know LosFormatter ?

    Stoneware in the obscurity of System.WEB.UI the class LosFormatter is hiding. ASP.NET uses this class to serialize web controls state into string presentation inside hidden field inside the page Form. ASP.NET also uses LosFormatter on post back to de-serialize the hidden field back into controls. The class advantage is that it optimized for highly compact ASCII format serialization.  This class supports serializing any object graph, but is optimized for those containing strings, arrays, and hashtables.

    If you have any need to serialize object into text (to transfer the object between pages, for example) you can use that class:

     

    //Send Page

    System.Collections.ArrayList oArr = new System.Collections.ArrayList();

    oArr.Add("a");

    oArr.Add("b");

    oArr.Add("c");

    System.Web.UI.LosFormatter oLF = new System.Web.UI.LosFormatter ();    

    System.IO.StringWriter oms = new System.IO.StringWriter();

    oLF.Serialize(oms,oArr);

    Response.Redirect(“page1.aspx?val=” & oms.ToString());                 

    //called Page

    System.Collections.ArrayList oArr = new System.Collections.ArrayList();

    System.Web.UI.LosFormatter oLF = new System.Web.UI.LosFormatter ();

    oArr = oLF.Deserialize(Request.QueryString[“val”]) as System.Collections.ArrayList;

     

  • ToString() is it really cause boxing ?

    More and more times I found myself arguing about ToString() as boxing. As you all know Tostring() is one of the object methods. Well, many programmers tend to believe that when they use ToSting() on value types (int, long, etc’) the CLR should box the value type into object to use the objects ToString(). That’s true if the value type uses the objects method. But, if value type override ToString() (and that’s what really happened) than boxing isn’t necessary since ToString() is part of the value type class.

     

    The best way to demonstrate this behavior is by examines IL code. If boxing and unboxing is necessary we will find the box / unbox IL instructions. Take a look at this code which uses assignment of value type to object and backward, there for cause boxing/unboxing and using of Tostring() on value type.

     

    int i = 9;

    System.Collections.ArrayList oArr = new System.Collections.ArrayList();

    //boxing

    oArr.Add (i);

    //unboxing

    int iRet = (int)oArr[0];

     

    //no boxing at all

    string str = i.ToString();

     

    The generated IL code that uses boxing/unboxing for using ArrayList with value types, as accepted. For using ToString() with value type you can see that IL uses int32 ToString() thus not using boxing.

     

    .locals init ([0] int32 i,

               [1] class [mscorlib]System.Collections.ArrayList oArr,

               [2] int32 iRet,

               [3] string str)

    . . .

    //000015:                                 int i = 9;

      IL_0006:  ldc.i4.s   9

      IL_0008:  stloc.0

    //000016:                                 System.Collections.ArrayList oArr = new System.Collections.ArrayList();

      IL_0009:  newobj     instance void [mscorlib]System.Collections.ArrayList::.ctor()

      IL_000e:  stloc.1

    //000017: