30

Just as there is "treat warning as errors" set in our projects to catch early possible problems, I would love to have a runtime exception to catch them early.

I have recently been bit by this problem and I would have been glad to have this.

Can it be done? And if yes, how?

Andrei Rînea
  • 20,288
  • 17
  • 117
  • 166

3 Answers3

44

You could hook into the PresentationTraceSources collection with your own listener:

public class BindingErrorListener : TraceListener
{
    private Action<string> logAction;
    public static void Listen(Action<string> logAction)
    {
        PresentationTraceSources.DataBindingSource.Listeners
            .Add(new BindingErrorListener() { logAction = logAction });
    }
    public override void Write(string message) { }
    public override void WriteLine(string message)
    {
        logAction(message);
    }
}

and then hook it up in code-behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        BindingErrorListener.Listen(m => MessageBox.Show(m));
        InitializeComponent();
        DataContext = new string[] { "hello" };
    }
}

Here is the XAML with a binding error

    <Grid>
    <TextBlock Text="{Binding BadBinding}" />
</Grid>
Crono
  • 10,211
  • 6
  • 43
  • 75
Dean Chalk
  • 20,076
  • 6
  • 59
  • 90
  • 1
    Does this work only when I run my application within visual studio? How about when I publish my application to a share and run the wpf exe from there? – Jithu Oct 22 '15 at 21:29
14

I implemented a solution very similar to the one proposed by Dean Chalk:

  1. Derived a TraceListener that throws instead of logging
  2. Added that listener to PresentationTraceSources.DataBindingSource

Please see the complete solution on GitHub, it includes a demo application and a unit test project.

Exception in Visual Studio

Benoit Blanchon
  • 13,364
  • 4
  • 73
  • 81
  • 1
    Cool. You could turn it into NuGet package. – Robert Važan Jul 16 '14 at 19:43
  • Readers may find it useful to look at this additional information on an answer to a different question, where Benoit has also posted *this* answer https://stackoverflow.com/a/55641847/5198140 – Richardissimo Nov 10 '20 at 11:23
  • 1
    And I've just noticed that Benoit seems to have taken Robert's advice, and put this in a NuGet package, thanks Benoit... https://www.nuget.org/packages/WpfBindingErrors/ – Richardissimo Nov 11 '20 at 14:19
0

First add this class to your project:

using System.Diagnostics;

namespace WpfTestApp
{
    public class BindingErrorListener : TraceListener
    {
        public static void Register()
        {
            PresentationTraceSources.DataBindingSource.Listeners.Add(new BindingErrorListener());
        }

        public override void Write(string message)
        {
        }

        public override void WriteLine(string message)
        {
#if DEBUG
            throw new System.Exception(message);
#endif
        }
    }
}

Then call the Register method in your App.xaml.cs class:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        BindingErrorListener.Register();
        // ...
    }
}

This way, (by throwing an exception) if you have any binding errors then you will be aware of those errors in the first place, that is, as soon as you start (F5) your application. If you wish, you can log those by injecting your logger object in the BindingErrorListener constructor.

Mustafa Özçetin
  • 1,893
  • 1
  • 14
  • 16