开发者

How can I turn binding errors into runtime exceptions?

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?


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>


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.

How can I turn binding errors into runtime exceptions?


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜