In Part 1 of this series, I showed how delegates work in C#. We created a matrix that was populated with a delegated function call. This function was responsible for performing the display result in each cell of the matrix.
In today's post, we wish to accomplish the same results, but instead of using C#, we're going to be using JavaScript against the Microsoft ASP.NET Ajax Extensions. Currently we're building on Beta 2 of these extensions.
First, let's have a look at the code behind(side) C# file.
1: using System;
2: using System.Web.UI;
3:
4: public partial class ClientSideDelegate : Page
5: { 6: protected void Page_Load ( object sender, EventArgs e )
7: {} 8: }
Nothing. There is not an ounce of C# code running this sample, in fact, we don't even need a code behind(side) file.
Here are screen shots of the finished product running, to give you a good mental picture of what we want to accomplish.

No Math Function, Just Display X, Y

The Add Matrix

The Subtract Matrix

The Multiply Matrix
Remember our goal. Create the matrix with a single set of code, that is reused over and over again, for every math function.
One thing you'll notice is that I've changed the title of part 2, to be delegates/inheritance. This is because after looking at the JavaScript code (you'll see this in a moment) that it looks/acts more like inheritance then it does a delegate. Although it kind of looks the same, we actually pass in a class that matches our signature. You'll see as we go through the article.
OK, here is the ASP.NET code.
1: <asp:ScriptManager ID="ClientMatrixScriptManager" runat="server">
2: <Scripts>
3: <asp:ScriptReference Path="ClientSideDelegate.aspx.js" />
4: </Scripts>
5: </asp:ScriptManager>
6:
7: <asp:DropDownList ID="OperationList" runat="server" OnChange="DrawMatrix(this.value)" >
8: <asp:ListItem Selected="True" Text="Do...." Value="0" />
9: <asp:ListItem Text="No Math" Value="0" />
10: <asp:ListItem Text="Add" Value="1" />
11: <asp:ListItem Text="Subtract" Value="2" />
12: <asp:ListItem Text="Multiply" Value="3" />
13: </asp:DropDownList>
14:
15: <div id="Matrix">
16: </div>
Nothing tricky, just a drop down list with some options, and an empty div tag that we'll fill with our Client Side Matrix. Also notice that on line 3 is where we're setting up the reference to our external JavaScript file. We do this inside the script manager so the external file is sure to be loaded after all the other MS Ajax scripts have been loaded. Also notice that the OnChange client event of the DropDownList is set to call a function called "DrawMatrix()" that takes the value of the drop down list as a parameter. This will be the integer value of 0-3, and again (as you'll see) we'll create an Enumerator in JavaScript to work the same as it did in C#.
What the MS Ajax Extensions give us is pseodu .NET in JavaScript. The first thing that we need to do is create/register a namespace. This does some wiring under the hood that will later let us register classes, enums, and other stuff to that namespace.
1: //register name space
2: registerNamespace('ScottCate');You might be asking -- "What does the registerNamespace() method call into?" And that's a great question. It calls in the Core MS Ajax Extension libraries that are loaded from the script manager. For now, we'll just call it automagic.
Remember the Enumertor I was talking about using? Here it is defined in JavaScript.
1: //setup enum
2: ScottCate.MathOperator = function() { 3: }
4: ScottCate.MathOperator.prototype = { 5: None: 0,
6: Add: 1,
7: Subtract: 2,
8: Multiply: 3
9: }
10: // the second param determines if the Enum is flagged
11: ScottCate.MathOperator.registerEnum("ScottCate.MathOperator", false);Line 11 calls a registerEnum method and registers the MathOperator Enumerator. Now we have an Enum (like) class in JavaScript that is going to act just like we would expect it to, knowing everything we already know about Enums in .NET including flagging (second parameter);
Next, is the MatrixWorker JavaSript Method() inside of DelegateSample.aspx.js. This is going to be our work horse that does the actual Martix building for us.
1: function MatrixWorker(mathDelegate) { 2: var matrix = $get('Matrix'); 3: var matrixString = new Sys.StringBuilder('<table border=1>'); 4: for(x = 0; x <= 10; x++) { 5: matrixString.append('<tr>'); 6: for(y = 0; y <= 10; y++) { 7: matrixString.append('<td>'); 8: var math = new mathDelegate(x,y);
9: matrixString.append( math.toString() );
10: matrixString.append('</td>'); 11: }
12: matrixString.append('</tr>'); 13: }
14: matrixString.append('</table>'); 15: matrix.innerHTML = matrixString.toString();
16: }
Notice on line 8 where we "New" up an instance of the class that is passed in. These classes will be part of an inheritance chain that will know how to give back the appropriate string presentation for the Math function they're responsible for. We simply nest this call inside two fro loops that will create our table, rows, and cells. When it's done (on line 15) we simply stuff the contents inside the div tag.
Next we need to create our Math classes that will be used to create our cell results. We'll start just generating the classes. On lines 1-20 we create our base math class. Then on lines 21-27 we create our first child of Math called AddMath. Line 23 calls an initializeBase method, and passes off the X,Y values to it's parent. Then we repeat the options for Subtract and Multiply. See how we're creating an individual toString() method for each class?
1: //setup base method
2: ScottCate.Math = function(a,b) { 3: this._a = a; //value of a or 0
4: this._b = b; //value of b or 0
5: }
6: ScottCate.Math.prototype = { 7: get_a: function() { 8: return this._a;
9: },
10: get_b: function () { 11: return this._b;
12: },
13: toString: function() { 14: return this.get_a() + ',' + this.get_b();
15: },
16: dispose: function() { 17: //gone;
18: }
19: }
20:
21: //setup add function
22: ScottCate.AddMath = function(a,b) { 23: ScottCate.AddMath.initializeBase(this, [a,b]);
24: }
25: ScottCate.AddMath.prototype.toString = function() { 26: return this.get_a() + this.get_b();
27: }
28:
29: //setup subtract function
30: ScottCate.SubtractMath = function(a,b) { 31: ScottCate.SubtractMath.initializeBase(this, [a,b]);
32: }
33: ScottCate.SubtractMath.prototype.toString = function() { 34: return this.get_a() - this.get_b();
35: }
36:
37: //setup multiply function
38: ScottCate.MultiplyMath = function(a,b) { 39: ScottCate.MultiplyMath.initializeBase(this, [a,b]);
40: }
41: ScottCate.MultiplyMath.prototype.toString = function() { 42: return this.get_a() * this.get_b();
43: }
And then registering the classes with the MS Ajax Extensions.
1: //register classes
2: ScottCate.Math.registerClass('ScottCate.Math', null, Sys.IDisposable); 3: ScottCate.AddMath.registerClass('ScottCate.AddMath', ScottCate.Math); 4: ScottCate.SubtractMath.registerClass('ScottCate.SubtractMath', ScottCate.Math); 5: ScottCate.MultiplyMath.registerClass('ScottCate.MultiplyMath', ScottCate.Math);Notice the registration of each class is done so be defining it's parent for inheritance. the Math class doesn't have a parent, but it does implement IDisposable. Yes Interfaces are supported to :). Then AddMath, SubtractMath, and MultiplyMath all inherit from Math.
Finally, the missing piece is the DrawMatrix() method that is called from the Client Drop Down List. A nice little JavaScript switch statement using our Enumerator to decide which class to use to call into the Matrix Worker.
1: function DrawMatrix(operator) { 2: //make sure operator is a number
3: switch(parseInt(operator)) { 4: case ScottCate.MathOperator.None:
5: MatrixWorker(ScottCate.Math);
6: break;
7: case ScottCate.MathOperator.Add:
8: MatrixWorker(ScottCate.AddMath);
9: break;
10: case ScottCate.MathOperator.Subtract:
11: MatrixWorker(ScottCate.SubtractMath);
12: break;
13: case ScottCate.MathOperator.Multiply:
14: MatrixWorker(ScottCate.MultiplyMath);
15: break;
16: }
17: }
And Pooof. You have just experienced Inheritance/Delegate like behavior in JavaScript running against the Microsoft ASP.NET Ajax Extensions.
Enjoy!
In Part 1 of 2, I want to show the example that I created today for my talk at VSLive in Dallas.
First, let's explore delegates in C# on the server in .net. In part 2, we'll look at how to accomplish the same concept on the client using MS Ajax Extensions. Beta2.
We have the following ASP markup.
1: <asp:DropDownList ID="OperationList" runat="server" AutoPostBack="True" OnSelectedIndexChanged="OperationList_SelectedIndexChanged">
2: <asp:ListItem Selected="True" Text="Do...." Value="0" />
3: <asp:ListItem Text="Add" Value="1" />
4: <asp:ListItem Text="Subtract" Value="2" />
5: <asp:ListItem Text="Multiply" Value="3" />
6: </asp:DropDownList>
7: <asp:PlaceHolder ID="MatrixPlaceHolder" runat="server" />
Lines 1 through 6 contains a simple drop down list. These items are listed 0 through 3, which will become an Enum (both on the server, and in JavaScript (part2)). Line 7 is a place holder, that we're going to build a matrix of numbers. Our goal is to write code that will create a 11X11 matrix where each cell in the matrix has a function (delegate) applied to it. Following are the sample outputs.

Server Side Add Function

Server Side Just display X,Y function
Server Side Multiply function

Server Side Subtract function
So now we know the output, and our goal is to write code that will perform these outputs. Now, there is now doubt that anyone, in any language, could write two nested loops, and output the above tables. And they could just as easily perform the math. The trick here is to use a delegate in just the right place, so that we only have to write one set of nested loops. When we're creating the cells in our matrix, we will delegate the math operation, out to another function that will actually do the work for us. So when we're creating the matrix, we don't know (and don't really care) what math functions can be done with X and Y. We'll let the delegate coder worry about that.
So ... To the code.
in the C# code behind(side) file, we first want to create our delegate. This is the contract that we want to create, for others to write math methods against. The delegate is nothing more than a signature. That's it. In fact, the delegate itself is the easiest of the code that we're about the write.
1: public delegate string DoMath(int a, int b);
So we now have a DoMath delegate. It's functions are to return a string, and take to int's as parameters. That's it. No more no less. any function that returns a string, that takes two int's as parameters, now matches out delegate signature, and can be used in place of the delegate. Let's create a few delegated methods. That is.... let's create a couple of methods that returns a string from two ints.
1: private string NoMath(int a, int b)
2: { 3: return string.Format("{0},{1}", a, b); 4: }
5: private string SubtractMath(int a, int b)
6: { 7: return ( a - b ).ToString();
8: }
9: private string MultiplyMath(int a, int b)
10: { 11: return (a * b).ToString();
12: }
13: private string AddMath(int a, int b)
14: { 15: return ( a + b ).ToString();
16: }
So there we have 4 methods. NoMath, AddMath, SubtractMath, and MultiplyMath. All of these methods have the same signature. They all return a string from two ints.
Next, we create an Enumerator to handle the values of our possible options in our ASP.NET drop down list.
1: public enum MathOperation : int
2: { 3: None = 0,
4: Add = 1,
5: Subtract = 2,
6: Multiply = 3
7: }
This enum will let us mnemonically see the value. It isn't necessary, but makes for much nicer code to read.
Next we need a worker method, that will actually build the matrix for us. Notice that the method takes a delegate as it's only parameter.
1: private void BuildMatrix( DoMath operate)
2: { 3: Table table = new Table();
4:
5: for (int x = 0; x <= 10; x++)
6: { 7: TableRow row = new TableRow();
8: for (int y = 0; y <= 10; y++)
9: { 10: TableCell cell = new TableCell();
11: cell.BorderWidth = new Unit(1);
12: cell.BorderColor = Color.Black;
13: string val = operate( x, y );
14: LiteralControl lit =new LiteralControl(val);
15: cell.Controls.Add(lit);
16: row.Cells.Add( cell );
17: }
18: table.Rows.Add( row );
19: }
20: MatrixPlaceHolder.Controls.Clear();
21: MatrixPlaceHolder.Controls.Add(table);
22: }
look closely at line 13. We call operate(x,y) and set its return value to a string variable we call "val". Then this "val" is set to a literal text control, and added to the cell, which is in turn added to the row, which is in turn added to a table, which is finally added to the place holder control.
The only thing left for us to do is handle the SelectedIndexChanged event of the drop down. Here we run a switch statement on the incoming drop down list value, and call the BuildMatrix method. Notice the parameter that we pass in, is JUST THE NAME of the method that we want to call. That is the delegate. That method will be called on line 13 (above) and X and Y will be passed in as parameters. The return value (remember they all return a string?) gets set to the cell text, and the table is rendered.
1: protected void OperationList_SelectedIndexChanged(object sender, EventArgs e)
2: { 3: int val = Convert.ToInt32( ((DropDownList)sender).SelectedValue );
4: MathOperation math = (MathOperation) val;
5: switch (math)
6: { 7: case MathOperation.Add:
8: { 9: BuildMatrix( AddMath );
10: break;
11: }
12: case MathOperation.Multiply:
13: { 14: BuildMatrix( MultiplyMath );
15: break;
16: }
17: case MathOperation.Subtract:
18: { 19: BuildMatrix( SubtractMath );
20: break;
21: }
22: case MathOperation.None:
23: { 24: BuildMatrix(NoMath);
25: break;
26: }
27: }
28: }
In part two of this (to be posted as the next post) We're going to use Microsoft ASP.NET Ajax Extensions to accomplish the same goal, only we won't use **ANY** c#, it'll be 100% JavaScript. That's an exciting article.
I just got stuck on something, and it was one of those "in your face" type of solutions that my friend Jeff Julian had to help me with.
I have a file called c:\temp.xml.
In C# I was trying to load this into a XmlDocument. Easy enough.
XmlDocument xml = new XmlDocument();
xml.Load("c:\temp.xml");
Of course the values aren't hard coded, but for the point this works fine.
Here was my problem. I had the contents of c:\temp.xml already loaded in as a string called xmlContents. So I was trying to
xml.Load(xmlContents);
And I was getting an "Invalid URI" error.
The solution.
xml.LoadXml(xmlContents);
Worked perfectly. One of those little oversights that I could have spent hours on, where another set of eyes/ears helped in a few seconds.
Thanks Jeff.
Knowledge Base Server (KBS) is an add-in product for Community Server that lets you store and manage factual data. Community Server has many components; but the two that are most commonly used are blogs and forums. Blogs are the voice of a single person or a team. Forums are the conversation of the community. Knowledge Base Server brings an official company voice where questions can be answered.
Knowledge Base Server will be your factual store, a section of your website that can be the voice of the company, department, or team where consumers of your product or service will come to find answers.
With Knowledge Base Server as an effective store for factual data, what can we do to leverage all the factual data that we already have in Community Server? Knowledge Base Server includes several features that help you to populate and promote your Knowledge Base content.
The first question people usually have about Knowledge Base Server is, what's the difference between a forum and a knowledge base? Why not just setup a single forum called "Knowledge Base" and have that be used as your factual store? Well, we see that a Knowledge Base has more functionality than just housing a set of posts.
We are pleased to announce that the public beta for Knowledge Base Server is now available.
Copy Forum Post / Thread
Forums are used for conversations. Person A asks a question, person B answers, person C chimes in, and before you know it, a full conversation has begun, and hopefully the original question gets answered. This answer can come as a single person's response, but many times is answered from a combination of people. This is one of the real benefits of community. So let's imagine that Person A's question was answered, but it was answered over a series of 30 posts in a thread. This is not an uncommon scenario. After Knowledge Base Server is installed, a Knowledge Base Administrator will see a "Copy to KB" button on the toolbar. This option allows either a single post or a series of posts to be copied into a new Knowledge Base article. The content is not just copied verbatim, instead a nice dialog pops up for you to dissect all the posts, and create a concise Knowledge Base article from the contents of the selected posts. Now you have a simple knowledge base article that was created from the Forum thread. Credit is given as a "contributor" to the original forum post authors in the finished Knowledge Base article.
Knowledge Base Suggest
One of the most common complaints for a Forums Administrator is managing duplicate posts. KB Suggest intercepts new forum posts, does a quick scan for the keywords in the post, searches against Knowledge Base Server, and suggests Knowledge Base articles for the user to read. The user has the option to say "Yes, this answered my question" and if so, the post is not submitted to the Forums. If the user answers "No, these didn't help" or the user does nothing, the post is still submitted.
Knowledge Base Terms
After you have created a Knowledge Base article, it doesn't do any good unless you can drive traffic to it. For the example, let's say you have an error that you've been trying to solve for a long time. Your community users have been talking about it, and trying to figure it out. Now you have a solution and have written a Knowledge Base article. If you add a KB Term to the article, everywhere that the term is used in the forums, it will render as a link back to the Knowledge Base article. Using KB Terms is a great way to drive traffic back to the right answer in the Knowledge Base without having to manually edit all the old forum posts.
Below are links back to the website, that have video tutorials on the above features.

Installation Directions
Data Entry (Categories / Articles)
Copy Post or Thread to Knowledge Base
Knowledge Base Suggestions
Knowledge Base Terms
Well, Well, Well, it’s happened again. Every once in a while something comes along that makes your life a little easier. This little nudge then helps push you to start doing what you’ve wanted to do for a long time.
In my case it’s http://BlogMailr.com to help me start blogging more.
How lazy am I? I already have a bloging site, and all I have to do is go there, and start typing, save a post and the rest is done.
But with BlogMailr.com I can use my Email client to send blog posts. It's not so much the technology that I'm excited about, it's the fact that I live/breath in Outlook 90% of my day, so it's my home base.
I can start a blog post, save it as a draft, and get back to it later. When I'm ready I just press send, and in a few minutes, the post is made for me. How great is that? Since I've been traveling a lot lately, this will let me post a blog from the plane, or wherever I may be.
By now I'm sure most of you have heard about BlogMailr.com but I have a few subscribers that might not follow the main feed.
So if you see more posts out of my, it's because they're so easy to write/publish now J
Thanks BlogMailr.