Monday, February 27, 2012

What happened to my SharePoint calendar color-coding?

I'm not going to talk about how to color code a SharePoint calendar here as you will find numerous examples searching for it.  Most of these examples will have you hook into a JS function SP.UI.ApplicationPages.CalendarNotify.$4a to execute your HTML rewriting code.  On SharePoint 2010, this all worked fine and well up until late 2011.  I have no idea if a hotfix changed this or what happened exactly, but the color coding examples just stopped working.  Now all you see when your calendar loads is the HTML strings literally on your calendar appointments. 

After digging through sp.ui.applicationpages.calendar.js, the JS file loaded by SharePoint to handle most of the calendar's client-side functionality, it would seem that $4a doesn't exist on the CalendarNotify object anymore. There is a $4b that seems to work just as well though.  

Cut to the chase:  All you need to do is change your references from CalendarNotify.$4a to CalendarNotify.$4b in your JS code and you should be back in business for calendar color coding.

Tuesday, August 24, 2010

DataField Quirks

While working on a detail screen in Silverlight today down at the fireworks factory, I ran into some interesting quirks with the DataField control that comes with the Silverlight Toolkit. I have a dual listbox custom control that defines an "IsReadOnly" property. Since setting IsEnabled to false will disable a control and all of it's descendants, the IsReadOnly property is designed to disable the four buttons between the two listboxes while leaving the listboxes enabled such that the scrollbars remain active. The dual listbox worked fine outside of a DataField. Once wrapped in a DataField, the label became the name of the property that the IsReadOnly property was bound to and the IsReadOnly property on the dual listbox ceased to operate.

Why did IsReadOnly stop working?
There are a very small handful of controls in Silverlight (SDK & Toolkit included) that provide an IsReadOnly property. Ideally, Control would provide an IsReadOnly property and sutypes could implement a "readonly" state in the ControlTemplate that would automatically be animated to by the VisualStateManager to handle readonly scenarios, but that is another blog post. After some digging with Reflector, I noticed behavior in the DataField.SetContentReadOnlyState method that was causing IsReadOnly on the dual listbox to fail. Below is the code of the method with comments I added to explain what is going on:

private void SetContentReadOnlyState(bool isReadOnly)
/* The Content property of the DataField is the control that is wrapped in the <DataField> tags. If there is nothing set, which would be of little value in practical applications, then we're out of here. */
if (this.Content == null)

/* Let's create a stack to store the control contained in the DataField and potentially descendants of said control. */
Stack<DependencyObject> dependencyObjectStack =
new Stack<DependencyObject>();

while (dependencyObjectStack.get_Count() > 0)
/* Get the next control off the stack. In the first pass through the loop, this will be the control contained in the DataField, after that, it will be one of the descendants of the contained control. */
DependencyObject curObject = dependencyObjectStack.Pop();

/* Let's look for a property named IsReadOnly on the control we just popped off the stack. If we find one, regardless of it's type or if it's indexed, we're going to set it to the value of DataField.IsReadOnly and move to the next control on the stack, if any. Chances are the only control we're going to find with an IsReadOnly property (other than custom controls) is TextBox. DataGrid and DataForm have IsReadOnly properties as well, but it's not likely you would use them as the contents of a DataField. */
PropertyInfo propertyInfo =
if (propertyInfo != null)
propertyInfo.SetValue(curObject, isReadOnly, null);
/* So we didn't find IsReadOnly, let's look for IsEnabled next. Since IsEnabled is defined on Control, there is a pretty good chance we're going to find it. If we do, set it to the negation of the DataField.IsReadOnly (since logically we're looking for it to be readonly, i.e. not enabled). Like IsReadOnly before it, if we found out, we're going to move on to the next control in the stack. */
propertyInfo =
if (propertyInfo != null)
propertyInfo.SetValue(curObject, !isReadOnly, null);

/* We made it here because we didn't find an IsReadOnly or an IsEnabled property. Looks like we've gotten ahold of some sort of DependencyObject (that isn't a Control). Using the current control that we popped off the stack at the start of the loop, let's add all of it's visual children to the stack. An example might be if the DataField contained a StackPanel with Buttons. A StackPanel is a Panel which is a FrameworkElement, but it's not a Control, which is how we got this far. Since we're using a stack, the buttons are going to get popped off in reverse order, but that doesn't matter since the loop will go through all buttons before exiting. That means they'll all be in a consistent state. Since this loop is behaving recursively, it will traverse each path in the object tree until it hits a type with an IsReadOnly on IsEnabled property. */
int numChildren =
for (int i = 0; i < numChildren; i++)
.Push(VisualTreeHelper.GetChild(curObject, i));

The solution is pretty simple, instead of setting (or Binding) the IsReadOnly property in the dual listbox, do it on the DataField.IsReadOnly property itself. Oddly enough, it didn't seem to affect the results of TextBox with it's IsReadOnly property, but as a general rule, I'll start using IsReadOnly on the DataField only.

Getting late, I'll post on the invalid label name in a future post.

Thursday, May 20, 2010

NullReferenceException from a view-based entity in EF and WCF RIA Services

It's late and I'm lazy so this will be short, but this was a royal pain and the only online solutions I found were based on removing the OData endpoint or changing the cross-domain policy file, neither of which applied in my case. Below is the email I sent that sums up the issue and a solution.

"I don’t know if you guys have loaded the (table name removed to protect the innocent) yet, but I got a NullReferenceException from EF when trying to load it. A few fists full of hair later and I figured out the issue. EF has an odd way of determining EntityKeys for entities based on database views. It appears that it attempts to determine if the underlying table column is nullable or not. If it’s not nullable, it makes it part of the key. That breaks down very quickly when the view uses an outer join as nulls may be introduced on non-nullable columns. The view works fine in T-SQL, but when EF tries to load it, it performs a check to determine if the key is valid, at which point a NullReferenceException is thrown. As a stop gap measure, I put a coalesce on the columns returning null to return an empty string instead, but we need to determine the best solution in the morning."

Monday, February 22, 2010

Upgrading BIOS on ASUS M2N-SLI Deluxe makes Windows 7 unbootable

Not the standard post today, but since I've wasted the better part of the evening and saw that other people have as well, thought I should mention this somewhere so maybe it'll Google up next time someone does this. Not sure if this is common with any other motherboards, but this applies to the ASUS M2N-SLI Deluxe mobo. After applying a BIOS update, Windows 7 either doesn't make it all the way through boot up, or goes to a Blue Screen of Death very quickly after getting to the desktop. The only real giveaway of what is going on is that there is a message on the blue screen that says "BUGCODE_USB". Basically, if you disable the USB controller in BIOS the problem goes away, but not having USB support isn't really an option. I've upgraded the BIOS on this board twice now and in both cases the solution has been to reset the CMOS. The manual describes how to do this in section 2.6 on page 2-20. Before doing this procedure, I would highly recommend writing down or taking pictures of the settings in your BIOS setup first as you will have to go back in after completing this procedure and setup your BIOS correctly.

A last ditch effort would be to try to get Windows to reinstall drivers. In Device Manager, you can uninstall a device under System Devices named Microsoft ACPI-Compliant System. This will cause most other drivers to uninstall as well. Don't be a hero, as soon as it asks you, reboot the system right away. It make take several boots and freezing (do a hard reboot) to get back to the desktop and get all the drivers reinstalled.

Friday, February 12, 2010

Customize resources in Silverlight with Themes and ImplicitStyleManager

Oh the joys of themes/styles and Silverlight 3. While I'm waiting for the patches of hair to grow back, let me show you how I solved the problem of having standard styles for themes that can be overridden. Basically, I have a situation where I have 14 different color schemes for the same layouts and styles. The copy and paste solution just isn't going to work. Unfortunatley Silverlight out of the box doesn't have a good solution for managing this. I need to make a note to come back and update this post at a more reasonable hour, but for now download the sample project (plenty of comments for your viewing pleasure) for a demonstration. Essentially the MyTheme.user.xaml file in SilverlightApplication1 allows you to override the values defined in MyTheme.

Wednesday, January 27, 2010

TargetType in Silverlight using custom types in the current assembly

This is going to be quick, but hopefully it'll save you some time and Excedrin. While attempting create a Style in XAML today, I received a XamlParseException that the TargetType could not be found. The TargetType happened to be a type in the current assembly, but different CLR namespace, so I defined my xmlns like this:


I defined the TargetType property like this:


Remember I said that all of this (i.e. the type for which the xmlns is defined in the XAML, the XAML itself, and the SackONuts type) is in the same assembly, so there should be no need to define the assembly in the xmlns declaration. However, XamlParseExceptions abound if you try this. There is a blurb in the Sliverlight SDK documentation for the Style.TargetType property Remarks section that suggests the XAML processor handles setting properties of Type in a special way.

To make a long story short, I went ahead and defined the assembly portion of the xmlns declaration even though it's in the current assembly and viola! It works. I guess the XAML parser uses the assembly portion of the xmlns processor a bit differently when handling Type resolution versus the rest of the processing.


Wednesday, January 28, 2009

QuickStart: ADO.NET Data Services Configuration

Want to learn how to use ADO.NET Data Services Configuration and only have 5 minutes (I hope you're not sitting on your toilet with a laptop)? This QuickStart will have you configuring your Data Services quicker than Al Bundy. What this QuickStart will not do is teach you how to use ADO.NET Data Services. To do that, I would recommend reading the following articles:

ADO.NET Data Services Overview
Using Microsoft ADO.NET Data Services

First download the current release (application or source then compile it yourself) of ADO.NET Data Services Configuration from CodePlex. The examples provided in this post are also available in the source download. Copy the CodePlex.Data.Services.Configuration.dll (and .pdb for debugging) to your ADO.NET Data Services project. Add a reference in your project to the assembly. Now you're ready to write some code.

Update your web.config file to create the configuration you want to apply to your service. The following example shows how you would create a configuration.

<?xml version="1.0"?>
<!-- IMPORTANT: Must register the section to use it in config file -->
<section name="" type="CodePlex.Data.Services.Configuration.CodePlexDataServicesSection, CodePlex.Data.Services.Configuration"/>
<!-- IMPORTANT: Configuration for ADO.NET Data Services
The IDataServiceConfiguration interface defines the configurable
options for ADO.NET Data Services. Notice below that all of the
properties defined on the IDataServiceConfiguration interface
can be applied to the <dataServiceConfiguration> element in
camel-case. The interface also defines three methods for registering
known types and setting access rules. These methods are called by
supplying the elements <knownTypes>, <entitySetAccessRules>, and
<serviceOperationAccessRules>. See below for more details.
<!-- Add 1 to many <register> elements to make calls to the RegisterKnownTypes method -->
<register type="System.String" />
<!-- Add 1 to many <set> elements to make calls to the SetEntitySetAccessRules method -->
<set name="*" rights="All" />
<!-- Add 1 to many <set> elements to make calls to the SetServiceOperationAccessRules method -->
<set name="*" rights="All" />
This example shows a single <dataServiceConfiguration>. Since it does not have a "name" attribute, it is considered the default configuration. While this example does not show it, you can have multiple <dataServiceConfiguration> defined as long as each has a unique name (a single default configuration without a name attribute is allowed as well). This example shows usage of every possible configuration element and attribute (with the exception of the name attribute). All of the elements and attributes under the <dataServiceConfiguration> element are optional. If an attribute is not supplied, that associated property on the IDataServiceConfiguration is left to it's default value.

Using the configuration in code is very simple. The following example shows applying the default configuration from the web.config file.

using System.Data.Services;
using System.ServiceModel;

using CodePlex.Data.Services.Configuration;

namespace TestService
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class AdventureWorksDataService : DataService<AdventureWorksEntities>
// This method is called only once to initialize service-wide policies.
public static void InitializeService(IDataServiceConfiguration config)

The using CodePlex.Data.Services.Configuration; statement allows the usage of IDataServiceConfiguration extension methods for applying configuration. The IDataServiceConfiguration.Configure method applies the default configuration from the web.config file. While this example does not show it, if you created named <dataServiceConfiguration> elements in your web.config file, you could call an overload of the Configure method that accepts the name of the configuration to use.

...and time! Hopefully that wasn't even 5 minutes. I encourage you to provide feedback on the CodePlex discussion board.

Tuesday, January 27, 2009

ADO.NET Data Services Configuration

Looking for a better way to configure your ADO.NET Data Services than hard-coding the configuration in the DataService-derived type? Check out my new project on CodePlex. While it's a complete and functioning solution now, I plan on cleaning up with a help file, examples, and provide an installer in the near future.

P.S. I will be getting back to working on Condiguration soon...

Tuesday, July 22, 2008

Condiguration: FAQ

Q: The resulting file is unchanged, how can I see error messages?
A: The MSBuild integration outputs error messages just like any other task. However, the build output can be quite a bit to sift through. Process the file using the command-line utility so that the error messages are immediately available.

Wednesday, July 16, 2008

Condiguration: Configuration Options

Condiguration is a template processor that transforms configuration files with conditional commands and produces pure configuration files, much like ASP.NET creates HTML from a .aspx files. A major design philosphy behind Condiguration is to allow the developer to use as little or as much as the functionality that is needed. In fact, the only requirement of a configuration file template is that the Condiguration namespace be declared. All other conditional configuration options described in this post may be used a la carte.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:condig="">
Note: The namespace will change to a URL in the next release.

Prefixes and Comments
The processor only processes XML components that are prefixed with the namespace prefix. "condig:" is the prefix used in the examples, but the prefix can be whatever you prefer. To produce a pure configuration file, Condiguration removes all traces of itself from the resulting configuration file. You can even prefix XML comments so that they will be removed from the resulting configuration file. This is useful if the comment applies to the Condiguration conditional but has no meaning in the configuration file itself.

<!-- condig: So long suckers, I won't be here on the other side! -->
<!-- I'll stick around because I'm not prefixed :p -->

Currently two methods of conditional configuration are provided. First, conditions can be supplied with <choose>/<when>/<otherwise> elements. This syntax behaves like a T-SQL CASE statement with conditional statements applied to each <when> element. The first <when> condition that evaluates to "true" will have it's contents injected into the resulting configuration file.

<condig:when condition="condig:equals('$(Configuration)', 'Debug')">
<add name="database" value="Driver=SQL Native Client;Server=sql2k5-dev;Database=myDataBase;Trusted_Connection=yes;" />
<condig:when condition="condig:equals('$(Configuration)', 'QA')">
<add name="database" value="Driver=SQL Native Client;Server=sql2k5-qa;Database=myDataBase;Trusted_Connection=yes;" />
<condig:when condition="condig:equals('$(Configuration)', 'Release')">
<add name="database" value="Driver=SQL Native Client;Server=sql2k5-pro;Database=myDataBase;Trusted_Connection=yes;" />

The <when> element has a single attribute, "condition" (<choose> and <otherwise> have no attributes at all). The condition must be a value that can be coerced to a boolean true or false. You could hard-code the word "true" or "false" in the condition, though this wouldn't be very conditional. You can evaluate a property (Configuration and Platform are provided by default with MSBuild integration, though any MSBuild properties may be provided, but that is another post) if the property's value is "true" or "false". Property evaluation will be explained later in this post with the Inline Syntax. You could use the inline syntax to return a value (a function that returns a boolean or a string "true" or "false") to be evaluated as a boolean.

<condig:when condition="false">
<!-- Hard-coded and false, so this will never happen -->
<condig:when condition="condig:overwrite('$(MeIsBool)')">
<!-- Poor grammar, but apparently this property contains a "true" or "false" -->
<condig:when condition="condig:overwrite('true')">
<!-- An example of a function that returns a string that can be coerced to a bool -->
<condig:when condition="condig:not(equals('$(Configuration)', 'Release'))">
<!-- The "not" function returns a bool -->
<!-- No dice, we end up here -->

While not necessary, this syntax allows for each <when> or <otherwise> to have different groupings of child elements to be returned in the configuration file. Another feature of this syntax is that it can be emdedded within itself multiple times.

<condig:when condition="condig:equals('$(Configuration)', 'Debug')">
<child2>Some data</child2>
<child2 important="whatever"></child2>
<condig:when condition="condig:equals('$(Configuration)', 'QA')">
<nino1>Notice the different elements</nino1>
<condig:when condition="condig:equals('$(Configuration)', 'Release')">
<condig:when condition="true">
<what now="?" />
<condig:when condition="condig:equals(1, 2)">
This is deep!
Where am I?
Enough already!

You might be asking why some of the "condition" attributes have the condig: prefix and some do not. If you want the processor to evaluate the expression, prefix it with condig. If you're just hard-coding a value then it isn't necessary.

Inline Syntax
The inline syntax provides a concise method of generating conditional content. It is limited to attribute values, but in many cases, that is what needs to be set conditionally. If you're a C# developer, the syntax may appear somewhat familiar.

<add key="Environment" value="condig:overwrite(concat(@('$(Configuration)', ' and stuff'))" />

Note the only "condig:" prefix necessary is on the outermost function. Functions may be embedded so that the return values are used as parameters. The processor will attempt to coerce the parameter values (and function return values) to the appropriate data type. Also notice that strings are qualified with single quotes rather than double qoutes.

Property Evaluation
You may have noticed some non-C# style syntax as well. In fact, if you're familiar with MSBuild it looks like something straight out of a project file. The $(...) syntax tells the processor to evaluate the value of the property at the time the function group is executed. All properties are evaluated prior to parsing, so that is why string values are qualified with single qoutes. To the parser it is just another string literal. If you just want to return the value of a property, you should use the "overwrite" BuiltIn function.

<add key="Environment" value="condig:overwrite('$(Configuration)')" />

Array Syntax
The second odd bit of syntax you might've noticed is the @(...) syntax. While property evaluation behaves exactly as it does in MSBuild, this syntax isn't exactly like item evaluation in MSBuild. This syntax actually designates it's contents as members of an array. This is due to many functions requiring a variable number of parameters to be supplied. The following example shows a "format" (think the String.Format method) that takes a variable number of parameters depending upon the string to be formatted.

<add key="Environment" value="condig:format('This configuration is {0} and it is {1} or {2}', @('$(Configuration)', 'great', 'not'))" />

The inline syntax allows for all BuiltIn functions and any registered Custom Functions to be used. The registration process and it's associated XML elements are described in the Custom Functions post.