Tech Blog

Jay's Technical blog

Cool Visual Studio 2005 feature that I missed....

29 June 2006
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

Yesterday I was working for my demos for CodeCamp Tampa (yep, I’m finally speaking somewher), and I was creating a new Web form so that I could then copy all the Atlas junk into the page when I saw the words “My Templates” at the bottom of the New items window… I thought wouldn’t it be cool if I could create my own Atlas templates.  Guess what? You can!  More importantly, it’s easy. 

Here’s a link on “jfo’s coding blog.”  Basically you can turn any project or an item into a reusable template (I don’t think we’ve talked nearly enough about this).

In light of this I’ll be creating a series of Atlas templates for myself.  I have decided to make these templates available here on CodeBetter. 

I’m going to try with this post to use the CS’ attachment feature I don’t think BlogJet will let me do it, so I’ll be manually adding the files to this post (after I publish).

Right out of the gate I have 4 files – Atlas-enabled WebForm (C#), Atlas-enabled WebForm(VB), Atlas UpdatePanel WebForm (C#), and Atlas UpdatePanel WebForm (VB).  All of these are zip files (and their contained in a zip attachment to this post).  You'll want to put them in My Documents\Visual Studio 2005\Templates\ItemTemplates.  Once you do that they'll be available for you in your development (or you can try to build your own using the tools in Visual Studio 2005)

[tags: Visual Studio 2005,VB.NET, C#, Atlas]


My first Atlas behavior -- the invisibleBehavior

23 June 2006
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

[out of date post... this deals with MS Atlas CTP... which has been change drastically and is now MS Ajax Extensions]

I have been playing with the Atlas client behaviors for some time.  [My fear is that when I finally publish my “big” post it will bomb (but that’s another matter)].  I found a reason to build my own behavior (although I may incorporate it into an Atlas client control as well)

Here’s what I discovered.  The Atlas client side Sys.UI.Control class supports a visibility property which shows and hides an element using the visibility style.  The problem with this is that the space of the original element is always taken up on the page.  I wanted to build a collapsible panel (one that uses the display style instead).  I decided a behavior sounded like a good approach since this was new functionality not already covered in the Atlas control library (and I wasn’t building a new control… yet).

Admittedly I started with the clickBehavior’s source code and morphed it into this:

Sys.UI.invisibleBehavior =function() {
  Sys.UI.invisibleBehavior.initializeBase(
this); // Initialize the base class

  var _reappearedHandler;
  var _disappearedHandler;

  this.reappeared = this.createEvent(); // Create the reappeared event
  this.disappeared = this.createEvent(); // Create the disappeared event

  // destroy this class
 
this
.dispose = function() {
    Sys.UI.invisibleBehavior.callBaseMethod(this, 'dispose');
  }

  // What needs to happen to start the class
 
this
.initialize = function() {
    Sys.UI.invisibleBehavior.callBaseMethod(this, 'initialize');
    _reappearedHandler = Function.createDelegate(this, reappearedHandler);
    _disappearedHandler = Function.createDelegate(this, disappearedHandler);
  }

  // Field that holds the value of the reappearDisplayMode property… I could have used an enum here
  //
(the only 2 valid values are “” and “block”… this is what is used when reappear is called to set the 
  // display style to something visible)

  this
._ReappearDisplayMode = "";

  // set reappearDisplayMode string
  this
.set_reappearDisplayMode = function(newDisplayMode)
  {
    this._ReappearDisplayMode = newDisplayMode;
  }

 // get reappearDisplayMode string
 
this
.get_reappearDisplayMode = function()
  {
    returnthis._ReappearDisplayMode;
  }

 // method for making the underlying element appear on the screen
 
this
.reappear = function() {
    this.control.element.style.display=this._ReappearDisplayMode;
    this.reappeared.invoke(this, Sys.EventArgs.Empty);
  }

 // method for making the underlying element disappear from the screen
 
this
.disappear = function() {
    this.control.element.style.display="none";
    this.disappeared.invoke(this, Sys.EventArgs.Empty);
  }

 // single property for determining whether the element is hidden or not
 
this
.get_isHidden = function() {
    return (this.control.element.style.display=="none");
  }

/*
 
// experimental set that was just added (untested at the time of this writing… uncomment to try)
  this.get_isHidden = function(HideMe) {
    if(HideMe)
      this.disappear();
    else
      this.reappear();    
  }
*/

  // Build the metadata
  this.getDescriptor = function() {
    var td = Sys.UI.invisibleBehavior.callBaseMethod(this, 'getDescriptor');
    td.addProperty('reappearDisplayMode', String, true);
    td.addProperty('isHidden', Boolean, false);
    td.addMethod('disappear');
    td.addMethod('reappear'); 
    td.addEvent('disappeared', true);
    td.addEvent('reappeared', true);
    return td;
  }

  // reappeared Event handler 
 
function
reappearedHandler() {
    this.reappeared.invoke(this, Sys.EventArgs.Empty);
  }

  // disappeared Event handler
 
function
disappearedHandler() {
    this.disappeared.invoke(this, Sys.EventArgs.Empty);
  }
}
// Set Base class
Sys.UI.invisibleBehavior.registerSealedClass('Sys.UI.invisibleBehavior', Sys.UI.Behavior);
// Set metadata
Sys.TypeDescriptor.addType('script', 'invisibleBehavior', Sys.UI.invisibleBehavior);

Now you are probably wondering how to use it.

var myPanel;
var invisible;

function pageLoad()
{
  myPanel = new Sys.UI.Control($(“SomeControl”));
  invisible = new Sys.UI.invisibleBehavior();
  myPanel.get_behaviors().add(invisible);
  invisible.initialize();
  myPanel.initialize();
}

function someEvent()
{
  if(invisible.get_isHidden())
    invisible.reappear();
  else
    invisible.disappear();
}

[NOTE: I will try the above sample code later.. it matches exactly how I have used it in my own work.. enjoy!]

[tags: Atals, Ajax, ASP.NET]


Testing Refactoring tools (again for the first time) - .Net Refactor 2005

23 June 2006
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

I’ve looked at Refactoring tools a number of times in the past (but never blogged my experiences).  For the longest time I used CodeRush/ReFactor! Pro, and lately I switched to ReSharper.  I’m starting to become dissatisfied with the speed and am starting to wonder what else is out there.  I want a tool that is fairly productive, but doesn’t get in my way by either slowing my machine down or just making suggestions that get in the way.  I still need to go re-evaluate the new CodeRush/ReFactor! Pro 2.0… but that will be saved for another post.

I do want to talk to you about one of the lesser known refactoring tools: .Net Refactor 2005 (for VS 2005… they also have .Net Refactor which is for VS 2003).  First of all, it’s way cheaper than the others coming in at $59.

No Frills
This tool is strictly a refactoring tool, and little else.  It provides the following functions/refactorings: Region Organization (Move selection to region, Create region for selection, Insert [Defined in setup] regions), Code complexity analyzer, Paste local variable, Extract method (with or without return variable), Extract super class, Extract interface, Extract assembly interface, Extract expression to function, Simplify conditional, Stub new method, Extract properties, Wrap selection, Insert snippet, Show block (of code’s analysis, Refactor strings (to variable or constant), Smart commenter, Wrap long line, Rename local variable, Reorder variables, Extract object, Rename parameters, Promote local variables, Create strongly typed collection, Replace magic number, Navigation (Move to top of current region, Move to bottom of current region), Move class to namespace, Create namespace for class, Copy class,and SQL/ADO refactorings (SQL Parameters, call stored proc, Create enum from SQL, Generate stored proc — from inline SQL). 

My count is about 23 refactorings, plus a few more useful tools.  It’s a very nice complement to the refactorings you get with Visual Studio.  The ones that are duplicates of the Visual Studio refactorings (at least the C# refactorings) are enhanced.

Speed
My experience with this tool is that it is FAST!  I tried it on a simple web project (which for me has 2 projects — the web project and a support dll), and I was never wondering what was taking it so long.  Considering the speed of some of its competitors, this is a huge win for it.  There are no slowdowns during project load either and the memory footprint seems to be acceptable (I tried it on a machine running X64 with a AMD64x2 3800+ processor with 1gb of RAM). 

The downside
I really only have a couple things I didn’t like about this tool.  The first is that while it is fast it has no context.  When I’m refactoring with ReSharper or Refactor! Pro, there is a context… these tools know what I’m doing and only offer choices that make sense for what I have highlighted or make sense for where my cursor is; .Net Refactor always gives you the complete listing of refactorings.  I realize that context comes at a price… namely speed.  Refactor! Pro (for instance) doesn’t seem to have issues with speed in terms of figuring out my context, so I think it’s probably theoretically possible to get context with a minimal speed hit. 

The only other downsides I see is that, while the tool offers a nice suite of refactorings, it offers little else.  I guess maybe I’ve gotten used to the fact that both ReSharper and Refactor! Pro (with CodeRush) offer me lot’s of extra IDE goodies that are hard to leave them behind.  Both ReSharper and Refactor! Pro offer tools for creating your own refactorings/IDE enhancements.  It does support snippets which is nice (although I didn’t really mess with them that much).  (I guess I should also note that they are the company who handles .Net Commander which is a fuller suite of IDE goodies but I don’t think it includes the refactoring enhancements; .Net Commander is the evolution of VB Commander into the VS.Net world)

Final thoughts
At this point, if all I ever wanted was extra refactoring support, I would be done… at $59 with the number of refactorings supported, it’s hard to pass up.  And, as a guy who has dealt with Les Smith (one of the developers) and his IDE enhancements (way back when I worked at ZAC Catalogs), I know that his products are stable and offer exactly what you need (and not a lot of fluff).  You see, Les is a user of his stuff and he really analyzes what the average programmer would use and what they would not.  Based on that he adds features. 

If you read that I like this tool, but aren’t going to settle on it (yet), you would be correct.  Next up… JustCode…

[tags: development tools, .NET, C#, VB.NET, refactoring tools]


An Atlas Client-Side Enhancement: Making the ASP.NET Controls easily accessible

22 June 2006
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

[out of date post... this deals with MS Atlas CTP... which has been change drastically and is now MS Ajax Extensions.. this particular post may or may not work.. your mileage will vary]

[Small update… there were a couple issues with the code.  That’s what I get for not compiling it one last time after adding a simple parameter]

Lately, I have been playing with the client-side of Atlas.  I have a big post on the Behaviors coming up.  Well it’s similar in the vein of the browsing the source code, except I have been building examples as I work (so I guess it will be the big behaviors post and then a bunch of examples to follow).

Anyway, today I faced a challenge that I bet many people have faced.  That is using the Atlas client-side with ASP.NET server controls.  In case you don’t know the ID attribute of ASP.NET server controls is usually different client side.  It’s usually a combination of the control’s server-side ID plus all of its parents’ IDs with a underscore as a delimitter between all of them (it’s done probably to make sure that the ID is unique as well as to give you an object path… at least that’s my guess). 

So the problem is that Atlas let’s you connect an Atlas class to a real HTML element if you know it’s ID.  So you don’t always know what ASP.NET will assign the client side ID to (unless either you use ClientID property from the server side or your one of the ASP.NET team).  I haven’t seen anything in the docs to suggest that the Atlas team has built anything to make it easy to get around this.  If you are building an extender or a Atlas-aware server control then you always have the ClientID field available to you, but what if you are doing something a little more basic… Atlas makes a lot of things easy, but it would be nice to be able to easily make the translation client side.

Anyway, I decided to tackle the problem.  My solution produces a Javascript object called “ASPDotNetControls.”  This object has a method for every server side control (there’s also a switch to filter out any hidden controls that won’t be on the client); each method returns a DOM reference to that element (I chose this method so that I don’t end up with an object with references to a bunch of DOM elements).  By the way, my solution scans the entire control tree, so it will pick up all controls on the page even those buried deep inside the controls hierarchy.

So enough of the talk here’s the code:

protectedvoidregisterASPDotNetControlsForAtlas(boolOnlyVisibleControls)
{
  System.Text.
StringBuildersb =newSystem.Text.StringBuilder();
 
sb.Append("function ASPDotNetControlsClass() {\n");
  sb.Append(LoopThroughControlsForAtlasRegistration(Controls, OnlyVisibleControls));
  sb.Append(
"}");
  sb.Append(
"\nvar ASPDotNetControls = new ASPDotNetControlsClass();");
 
this.ClientScript.RegisterClientScriptBlock(this.GetType(),"ASPNetControls", sb.ToString(),true);
}

protectedstringLoopThroughControlsForAtlasRegistration(ControlCollectionCtls,boolOnlyVisibleControls)
{
  System.Text.
StringBuildersb =newSystem.Text.StringBuilder();
 
foreach(ControlCtlinCtls)
  {
   
if(!OnlyVisibleControls || Ctl.Visible)
    {

     
if(Ctl.ID !=null&& Ctl.ID.Trim() !="")
        sb.Append(
" this."+ Ctl.ID +" = function() { return $(\""+ Ctl.ClientID +"\")};\n");

     
if(Ctl.Controls !=null&& Ctl.Controls.Count > 0)
        sb.Append(LoopThroughControlsForAtlasRegistration(Ctl.Controls, OnlyVisibleControls ));
    }
  }
  returnsb.ToString();
}

Now all you need to do is add a call to the first method registerASPDotNetControlsForAtlas in your codebehind (I usedthe PreRender event); if you are using the UpdatePanel you might want to set the parameter to false (but be aware that you will need to check any references that you get back from the class to see if they are null).

Here’s a quick scenario.  Let’s say I have an actual label on my form.  It might look like this:
<asp:Labelrunat="server"id="MyLabel"/>

So you could turn this label into an atlas label (in javascript) like this:
var MyAtlasLabel =newSys.UI.Control(ASPDotNetControls.MyLabel());
MyAtlasLabel.initialize();

Now from the script side I can use Atlas to its fullest… enjoy…

[A number of improvements I can think of… if I cached my script code for the complete list of controls, so that you’re not looping through the control tree on every hit… I’m too tired to come up with anymore]

[tags: Atlas, Ajax, ASP.NET]


How to attach Atlas Behaviors to elements programmatially via script

18 June 2006
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

[out of date post... this deals with MS Atlas CTP... which has been change drastically and is now MS Ajax Extensions]

I’m working on a fairly large post on Behaviors (right now I’m still working on it).  A side result of this large post is that I’ve learned to attach Atlas behaviors to elements via script (most of the examples use MS’ new declarative method which seems to be a cool method waiting for a tool to make it easier).

So, here’s the code to apply the FloatingBehavior (which makes an element draggable) to an element and the PopupBehavior (creates inline dialogs using an element).  In a nutshell we’re creating a movable popup dialog.  So here’s the complete code for those who want to jump in and tinker right away.

<%@PageLanguage="VB"AutoEventWireup="false"CodeFile="Default2.aspx.vb"Inherits="Default2"%>

<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<htmlxmlns="http://www.w3.org/1999/xhtml">

<headid="Head1"runat="server">

<title>Untitled Page</title>

</head>

<body>

<formid="form1"runat="server">

<atlas:ScriptManagerID="ScriptManager1"runat="server">
  <scripts>
   
<atlas:scriptreferencescriptname="AtlasUIDragDrop"/>
   
<atlas:scriptreferencescriptname="AtlasUIGlitz"/>
  </scripts>
</atlas:ScriptManager>

<divstyle="width:800px; height:600px; border:solid 1px black">
<spanid="MySpan">Just some text to use as a placeholder</span><br/>
<buttonid="MyButton"onclick="PopupBehavr.show();">Click Me</button>

<
divid="divPopup"style="width:100px; border: inset 1px black; background-color:White;">
 
<div id="divTitleBar" style="width:100px;background-color:Blue; color:White">My Popup</div>
     
This is a popup<br/>
     
<buttonid="BtnClose"onclick="PopupBehavr.hide();">Close</button>
 
</div>
</div>

</div>

</form>

<scripttype="text/javascript">
varPopupBehavr;
varFloatBehavr;
varMyLabel;
varMyPopup;

 

 

 

function pageLoad()
{
  MyLabel =
new Sys.UI.Label($( "MySpan" ));
  MyLabel.initialize();
  MyPopup =
new Sys.UI.Control($( "divPopup" ));
  MyPopup.initialize();
 
var b = MyPopup.get_behaviors()
  PopupBehavr =
new Sys.UI.PopupBehavior();
  FloatBehavr =
new Sys.UI.FloatingBehavior();
  FloatBehavr.set_handle($(
"divPopup" ));
  b.add(PopupBehavr);
  PopupBehavr.initialize();
  b.add(FloatBehavr);
  FloatBehavr.initialize();
}
</ script >

 

Design
Here’s the major points… We load the “AtlasUIDragDrop” and the “AtlasUIGlitz” libraries (although I’m not sure UIGlitz is needed for this example… I think it’s a code leftover) 

Believe it or not the first div (which looks like this: <divstyle="width:800px; height:600px; border:solid 1px black">) is extremely important.  It creates our surface for dragging, because you can’t drag the dialog off the page.  This was one of the first mistakes I made.  I got my element to drag, but it wouldn’t stay anywhere (basically you can move the element anywhere on the defined page.  If the element itself is the only thing on the page you’ll be able to drag the element, but it won’t stay where you drop it.

Next, we create a span (label) and a button that will be used to launch our dialog.  I use the html button tag here because I think it’s cool (you could easily swap it out with a standard input button if you like).

After this we define our divPopup which will be our popup dialog.  Notice that if we want this to look dialog like we have to create the look and feel ourselves (since I’m a bit graphically-challenged I created the minimal number of items: a title bar, a line of text within the element and a button to close).

The only other thing to note here is that the button’s click event manipulates the behavior (and not the element itself).

Script
The script is not overly complex, but here’s what it does.  It defines globally usable variables for the Popup Behavior (PopupBehavr), the Floating Behavior (FloatBehavr), A label control (MyLabel… which incidently is never really used… I used it in development for debug messages), the popup dialog (MyPopup). 

pageLoad()
All Atlas pages will automatically run this “event” and it is effectively a replacement for an onLoad event (except you don’t have to hook up the handler).  So here’s a code break down of what’s happening.

  MyLabel = new Sys.UI.Label($("MySpan"));
  MyLabel.initialize();

Our pageLoad method instantiatates the MyLabel label control with this code.  In this example this class remains unused.  When doing my research I have a standard page that I use, and this element is always there in case I want to give myself some feedback on what is happening without resorting to alert boxes everywhere.

  MyPopup = new Sys.UI.Control($("divPopup"));
  MyPopup.initialize();
 

Next, we initialize the MyPopup as a control.  In case you don’t know the $("divPopup") is an Atlas construct found in a lot of Ajax libraries.  It equates to document.getElementById(“divPopup”).

  var b = MyPopup.get_behaviors()

Set a variable for the Popup’s behaviors

  PopupBehavr = new Sys.UI.PopupBehavior();
  FloatBehavr = new Sys.UI.FloatingBehavior();
  FloatBehavr.set_handle($("divPopup"));

Create the PopupBehavior and FloatingBehavior classes.  Note that with FloatingBehavior we also set any necessary properties.  Handle is used to identify to the behavior which element it will be allowing to move.

  b.add(PopupBehavr);
  PopupBehavr.initialize();
  b.add(FloatBehavr);
  FloatBehavr.initialize();

Finally, we add the two created behaviors to the behaviors of the popup and we initialize each behavior.  That’s it.

Final notes
The final thing you should see is that we did all this without any server side code at all.  Despite what you might think; much of the server side Atlas Extenders really do is write javascript using the Atlas script framework for you (although the UpdatePanel does a lot more than simply write script).  Now if I have time I’m going to write a control to wrap what we just did for building quick and easy client-side dialogs (but someone will probably beat me to it).

[tags: Atlas, ASP.NET, Ajax]