Хорошо, я нашел немного «хакерского» решения, но оно работает.
Так как похоже, что XamlReader не знает о локальном пространстве имен при создании DataTemplate, я расширил StackPanel и «запекся» в событии Load. Это не совсем идеально, но работает:
this._listBox.ItemTemplate = (DataTemplate) XamlReader.Load(
@"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:foo=""clr-namespace:Foo;assembly=Foo"">
<Border>
<foo:ExtendedStackPanel>
<TextBlock Text=""{Binding " + this._displayMemberPath + @"}"" />
</foo:ExtendedStackPanel>
</Border>
</DataTemplate>"
);
И расширенный класс:
public class ExtendedStackPanel : StackPanel
{
public ExtendedStackPanel() : base()
{
this.Loaded += new RoutedEventHandler(this.ChildItem_Loaded);
}
private void ChildItem_Loaded(object sender, RoutedEventArgs e)
{
// Logic here...
}
}