April 2009 - Posts

To setup an example, suppose this was an accordion being bound data to:

<mcl:Accordion x:Name="BoundAccordion">
    <mcl:Accordion.HeaderTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Title}" />   
        </DataTemplate>
    </mcl:Accordion.HeaderTemplate>
    <mcl:Accordion.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}" />                   
        </DataTemplate>
    </mcl:Accordion.ContentTemplate>
</mcl:Accordion>

Not the most practical example, but simple for this demonstration purposes.  I was trying to bind data to it in this format:

var list = new[]
{
   new { Title = "Title", Text = "Text" },
   .
   .
};

So the anonymous collection contained anonymous classes with Title and Text properties.  Binding this to the accordion through:

BoundAccordion.ItemsSource = list;

Raised an exception.  This is the proper way to bind the accordion because ItemsSource is inherited from the ItemsControl line of base classes.  And so ItemsSource tries to use our anonymous list, and an exception is thrown:

Sys.InvalidOperationException: Managed Runtime Error #4004
System.MethodAccessException: AnonymousType.get_Title() at MethodBase.PerformSecurityCheck

The reason, that I found out from another source, is described later...  An exception is thrown when trying to bind against the anonymous type; switching it up to bind against this works instead:

var list = new HeaderedInformationCollection
{
    new HeaderedInformation { Title = "First Bound Header", Text = "First Bound Content" },
    new HeaderedInformation { Title = "Second Bound Header", Text = "Second Bound Content" },
    new HeaderedInformation { Title = "Third Bound Header", Text = "Third Bound Content" },
    new HeaderedInformation { Title = "Fourth Bound Header", Text = "Fourth Bound Content" }
};

this.BoundAccordion.ItemsSource = list;

This result binds correctly, because the HeaderedInformation is a structured class, and not one developed on the fly.  The exception comes from the internal plumbing of the Silverlight framework, not from the Accordion control directly.  Anonymous types are internal, and Silverlight doesn't support reflecting against internal types.  While that binding setup would work in ASP.NET, it does not in Silverlight.  Bummer.

Posted by bmains | with no comments
Filed under:

I was using TypeMock to mock some test code, and I was contemplating the setup.  I have a method, which is going to instantiate an object.  This static object calls some configuration code to setup itself with data, which I could mock to return a specific subset of data.  This was going to be a lot of code, because I could mock the configuration code, which pre-defines the content that's available within this instantiated object, which my component that I originally was testing was going to call.  So it would be something like this:

public void MyMethod()
{
     var obj = ConfigObject.GetInstance();
}

and GetInstance looks like:

public static ConfigObject GetInstance()
{
    ConfigSection section = (ConfigSection)ConfigurationManager.GetSection("..");
    //pass information to object
}

Now, ConfigObject has a lot of information, so it's not like I'd be only working with a few props, but many collections and configuration is a pain.  I circumvented all of this with a private method that does:

private object GetConfigValue(..)
{
   //Instantiates ConfigSection, gets the value desired, and returns it
}

This way, GetConfigValue() does the actual work, and I can change my code to simply mock thsi one method.  I can do this by:

Mock mock = MockManager.Mock<ConsumingObject>();
mock.ExpectAndReturn("GetConfigValue", 123);

And thus, my TypeMock mock now is reduced to one line of code.  TypeMock mocks GetConfigValue, which means this method isn't called, but the value 123 is returned in its stead.  Pretty cool.

Posted by bmains | with no comments
Filed under:

VS provides a debugging challenge when it comes to inline property declarations as such as this:

DataRow row = table.Rows[0];

var obj = new SomeClass
{
    ID = GetValue<int>(row, "ID"),
    Name = GetValue<string>(row, "Name"),
    Address = GetValue<string>(row, "Address"),
    IsActive = GetValue<bool>(row, "IsActive"),
    LastUpdated = GetValue<DateTime?>(row, "LastUpdated")
};

Imagine this scenario: the data row values get passed from the table's row to a class.  The GetValue generic method is a helper method that examines the row's value, check for null, and converts any actual values to the correct type.  Let's assume that an exception gets thrown when accessing the LastUpdated value from the DataRow.  When VS debugs this, the cursor points to the entire definition, and an exception gets thrown without identifying the actual value in error.  So when debugging this, it's harder to figure out the erroring field (though not impossible) in this setup.

It's much easier to debug in this setup:

var obj = new SomeClass();
obj.ID = GetValue<int>(row, "ID");
obj.Name = GetValue<string>(row, "Name");
obj.Address = GetValue<string>(row, "Address");
obj.IsActive = GetValue<bool>(row, "IsActive");
obj.LastUpdated = GetValue<DateTime?>(row, "LastUpdated");

The debugger clearly identifies that the LastUpdated assignment is in error.  So debugging using this approach in VS is easier, but the two differences aren't as impossible.

When you deploy, it's going to be harder to figure out the erroring field, unless GetValue catches the casting error and passes the name of the field to the exception message.  Deploying to production would make it much harder too.  Also, if GetValue is a method outside your current assembly (third party or other), you may not be able to debug into it.  If the error message is as vague as some of the messages in the .NET framework, then it's going to be more difficult to figure out.

Posted by bmains | with no comments
Filed under: ,

 I'd recommend reading the other posts in the series first to see how the process built-up to this point.  At this point, we have a working solution, but it's not the prettiest.  So the focus is on using a table to display a better format.  The core structure definition is the table in the following form.  The table is hard-coded like the following.

<table cellspacing="0" border="0" class="DataTable">
 <thead>
  <tr class="DataTableHeaderItem">
   <th>Name</th>
   <th>Address</th>
   <th>Phone</th>
   <th>Map</th>
  </tr>
 </thead>
 <tbody id="searchresults"></tbody>
</table>

The results are essentially rendered in the body of the table; this body is cleared/re-created with every new resultset.  The core function to display the results in the table, displayResults, has been updated to look like the following:

function displayResults(yahooResults, parent) {
 while (parent.hasChildNodes())
  parent.removeChild(parent.firstChild);

 var resultSet = yahooResults.ResultSet;

 for (var resultIndex in resultSet.Result) {
  var result = resultSet.Result[resultIndex];

  var row = parent.insertRow();
  row.insertCell().innerHTML = result.Title;
  row.insertCell().innerHTML = result.Address + "<br/>" +
   result.City + "<br/>" + result.State;
  row.insertCell().innerHTML = result.Phone;

  row.insertCell().innerHTML = "<a href='" + result.MapUrl + "' target='_blank'>View Map</a>";
 }

 $("#searchresults > tr:even").addClass("DataTableItem");
 $("#searchresults > tr:odd").addClass("DataTableAlternateItem");
}

This method simply clears all of the row results, inserts the new content, and styles it appropriately.  Let's look at it in chunks.

 while (parent.hasChildNodes())
  parent.removeChild(parent.firstChild);

This code removes all of the TR tags within the body, using the hasChildNodes method to check for children, and firstChild to get the first child.

 var resultSet = yahooResults.ResultSet;

 for (var resultIndex in resultSet.Result) {
  var result = resultSet.Result[resultIndex];
  .
  .
}

Yahoo uses the ResultSet object to represent the search results, and each record in the array is found in the Result property.  When looping using the for (var) notation, each row loops through and the variable represents the index, not the actual object.  This is a variation from .NET and other structured languages.

  var row = parent.insertRow();
  row.insertCell().innerHTML = result.Title;
  row.insertCell().innerHTML = result.Address + "<br/>" +
   result.City + "<br/>" + result.State;
  row.insertCell().innerHTML = result.Phone;

  row.insertCell().innerHTML = "<a href='" + result.MapUrl + "' target='_blank'>View Map</a>";

The actual rows/cells is generated via the insertRow and insertCell methods.  These methods actually return an instance of the row/cell (in older browsers, this may not be the case) for which the content is added to.  The Yahoo client-side API has a Title, Address, City, State, and Phone properties, amongst many others.

Lastly, to make it more useful, a URL reference to the map is generated through a hyperlink, using the string-based approach (assigning a string to the innerHTML property, instead of using the DOM to generate an anchor element).  Both options are available to you to use in your code.

Lastly, I used JQuery to style the table, which makes it super easy using the following code:

 $("#searchresults > tr:even").addClass("DataTableItem");
 $("#searchresults > tr:odd").addClass("DataTableAlternateItem");

The :even and :odd designations make it easy to create the item/alt. item setup.  The #searchresults statement references the TBODY tag, for which a class is applied to its rows (hierarchy specified using the > character).

For styling, the table contains the DataTable style, the header row has the DataTableHeaderItem style, and the rows have DataTableItem/DataTableAlternateItem.  My styles were kind of weak, simply used for demo purposes.  If someone would like to suggest an alternative styles that would look much better, please go ahead and comment.

 .DataTable
{
 
}

.DataTable td
{
 vertical-align:top;
 padding-left:10px;
 padding-right:10px;
}

.DataTable th
{
 vertical-align:top;
 padding-left:10px;
 padding-right:10px;
}

.DataTableHeaderItem
{
 background-color:Navy;
 color:White;
 font-weight:bold;
}

.DataTableItem
{
 background-color:LightYellow;
 color:Navy;
}

.DataTableItem a
{
 color:Navy;
 text-decoration:underline;
}

.DataTableAlternateItem
{
 background-color:CornflowerBlue;
 color:SmokeWhite;
}

.DataTableAlternateItem a
{
 color:White;
 text-decoration:underline;
}

Posted by bmains | with no comments
Filed under: ,

I was trying to tap into Telerik Markup using JQuery, and I had an epiphany why what I was trying to do wasn't working.  What I was trying to do was target a DIV element, and I did this:

$(control.get_element()).children("DIV > DIV.message").html("New update");

What I was expecting was to update the DIV with the message.  However, the children method returns the reference to the parent DIV, which happens to have a child with a class name of message.  Switching this to:

$(control.get_element()).children("DIV").children("DIV.message").html("New Update");

Fixed the issue.  In actuality, what I did was because there was only one message, by supplying a unique ID, I could do:

$("#myuniqueid").html("New Update");

And circumvented this whole mess!

Posted by bmains | with no comments
Filed under: ,

 For some reason, when I tried to do:

Page.ResolveClientUrl("~/errorpage.aspx?Page=" + url);

I got the error that this was an invalid virtual path, even though it wasn't.  It seemed like the error was with the url because it may have been formatted like "httP://localhost/default.aspx" and that could have caused the error.  So the test was to pull the url outside the method like:

Page.ResolveClientUrl("~/errorpage.aspx") + "?Page=" + url;

And this solved the problem greatly.

Posted by bmains | with no comments
Filed under: