While designing a new WPF application I noticed exceptions not being thrown during data binding for controls with DataTemplates. To test I wrote the following simple user control with as little logic as possible. I’m using .NET 3.5 SP1, VS2008 SP1 running on WIN7.
When the DataContext is set, TestMethod is called and an exception is thrown in the codebehind but the application doesn’t break.
Would someone mind explaining what is happening when the DataTemplate is being created? Specifically I’m interested in where the exception goes.
Below is the XAML code:
<UserControl x:Class="WPF2008.DataTemplateQuestion"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
<DataTemplate x:Key="TESTKey">
<Border BorderBrush="Black" BorderThickness="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding Path=Txt}" />
<TextBox Grid.Row="1" Text="{Binding Path=Lbl}" />
<TextBox Grid.Row="2" Text="Am I disabled?" />
<TextBox Grid.Row="3" Text="I am disabled." IsEnabled="False" />
</Grid>
</Border>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Label x:Name="lblTest" Content="{Binding Path=TestMethod}" ContentTemplate="{StaticResource TESTKey}" />
</Grid>
</UserControl>
Below is the codebehind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPF2008
{
public partial class DataTemplateQuestion : UserControl
{
public DataTemplateQuestion()
{
try
{
InitializeComponent();
lblTest.DataContext = new TestClass();
}
catch (Exception e)
{
// ADDING A BREAKPOINT HERE DOESN'T CATCH THE EXCEPTION
throw e;
}
}
}
public class TestClass
{
public TestValue TestMethod
{
get
{
// BREAKPOINT WILL BE HIT WHEN DEBUGGING BUT THE EXCEPTION DISAPPEARS
throw new Exception("WATCH ME DISAPPEAR");
return new TestValue { Lbl = "Label", Txt = "Text" };
}
}
public class TestValue
{
public string Lbl { get; set; }
public string Txt { get; set; }
}
}
}
Exceptions thrown by data bindings get translated into trace, which are delivered to the
DataBindingSourceTraceSource, which has a source name of “System.Windows.Data”.You can convert these into exceptions by creating a subclass of
TraceListnerthat throws an exception on a trace, and add it to theListenerscollection of theTraceSourceSource. This can be done either in code or in yourApp.configfile.Here is how you would do it in code:
See TraceSource and TraceListener documentation and samples for more details.